From c04b060e8f31c91873715c55fc60444f1338942f Mon Sep 17 00:00:00 2001 From: Andrew Hsieh Date: Mon, 17 Dec 2012 16:21:49 +0800 Subject: [PATCH] Add polly r150480 & its dependency cloog Add polly svn co http://llvm.org/svn/llvm-project/polly/trunk r150480, the most recent revision works with llvm 3.1. Also run "cd utils ; ./checkout_cloog.sh cloog_src" to get the cloog it depends See http://polly.llvm.org/ Change-Id: I3e99a7d1adda7d5601278acae4748446e9881333 --- tools/polly/CMakeLists.txt | 166 + tools/polly/CREDITS.txt | 30 + tools/polly/LICENSE.txt | 61 + tools/polly/Makefile | 17 + tools/polly/Makefile.common.in | 34 + tools/polly/Makefile.config.in | 42 + tools/polly/README | 10 + tools/polly/autoconf/AutoRegen.sh | 33 + tools/polly/autoconf/LICENSE.TXT | 24 + tools/polly/autoconf/aclocal.m4 | 75 + tools/polly/autoconf/config.guess | 1388 + tools/polly/autoconf/config.sub | 1489 + tools/polly/autoconf/configure.ac | 114 + tools/polly/autoconf/configure.bak | 65 + .../polly/autoconf/m4/find_lib_and_headers.m4 | 46 + tools/polly/cmake/FindCloog.cmake | 19 + tools/polly/cmake/FindGmp.cmake | 19 + tools/polly/cmake/FindIsl.cmake | 19 + tools/polly/cmake/FindOpenScop.cmake | 19 + tools/polly/cmake/FindSCoPLib.cmake | 19 + tools/polly/configure | 4088 ++ tools/polly/docs/index.html | 6 + tools/polly/docs/polly.png | Bin 0 -> 15526 bytes tools/polly/docs/polly.svg | 149 + tools/polly/include/CMakeLists.txt | 1 + tools/polly/include/polly/CMakeLists.txt | 9 + tools/polly/include/polly/Cloog.h | 69 + tools/polly/include/polly/CodeGeneration.h | 20 + .../polly/include/polly/Config/config.h.cmake | 19 + tools/polly/include/polly/Config/config.h.in | 28 + tools/polly/include/polly/Dependences.h | 116 + tools/polly/include/polly/LinkAllPasses.h | 127 + tools/polly/include/polly/MayAliasSet.h | 157 + tools/polly/include/polly/RegisterPasses.h | 27 + tools/polly/include/polly/ScheduleOptimizer.h | 19 + tools/polly/include/polly/ScopDetection.h | 279 + tools/polly/include/polly/ScopInfo.h | 639 + tools/polly/include/polly/ScopLib.h | 72 + tools/polly/include/polly/ScopPass.h | 64 + tools/polly/include/polly/Support/GICHelper.h | 50 + .../include/polly/Support/SCEVValidator.h | 36 + .../polly/include/polly/Support/ScopHelper.h | 85 + tools/polly/include/polly/TempScopInfo.h | 298 + tools/polly/lib/Analysis/CMakeLists.txt | 8 + tools/polly/lib/Analysis/Dependences.cpp | 438 + tools/polly/lib/Analysis/Makefile | 17 + tools/polly/lib/Analysis/ScopDetection.cpp | 598 + tools/polly/lib/Analysis/ScopGraphPrinter.cpp | 216 + tools/polly/lib/Analysis/ScopInfo.cpp | 1047 + tools/polly/lib/Analysis/ScopPass.cpp | 42 + tools/polly/lib/Analysis/TempScopInfo.cpp | 319 + tools/polly/lib/CMakeLists.txt | 44 + tools/polly/lib/Cloog.cpp | 339 + tools/polly/lib/CodeGeneration.cpp | 1796 + tools/polly/lib/CodePreparation.cpp | 174 + tools/polly/lib/DeadCodeElimination.cpp | 75 + tools/polly/lib/Exchange/CMakeLists.txt | 18 + tools/polly/lib/Exchange/JSONExporter.cpp | 352 + tools/polly/lib/Exchange/Makefile | 16 + tools/polly/lib/Exchange/OpenScopExporter.cpp | 589 + tools/polly/lib/Exchange/OpenScopImporter.cpp | 256 + tools/polly/lib/Exchange/ScopLib.cpp | 764 + tools/polly/lib/Exchange/ScopLibExporter.cpp | 99 + tools/polly/lib/Exchange/ScopLibImporter.cpp | 120 + tools/polly/lib/IndependentBlocks.cpp | 556 + tools/polly/lib/JSON/CMakeLists.txt | 6 + tools/polly/lib/JSON/LICENSE.txt | 1 + tools/polly/lib/JSON/Makefile | 16 + tools/polly/lib/JSON/include/json/autolink.h | 19 + tools/polly/lib/JSON/include/json/config.h | 43 + tools/polly/lib/JSON/include/json/features.h | 42 + tools/polly/lib/JSON/include/json/forwards.h | 39 + tools/polly/lib/JSON/include/json/json.h | 10 + tools/polly/lib/JSON/include/json/reader.h | 196 + tools/polly/lib/JSON/include/json/value.h | 1069 + tools/polly/lib/JSON/include/json/writer.h | 174 + tools/polly/lib/JSON/json_batchallocator.h | 125 + tools/polly/lib/JSON/json_internalarray.inl | 448 + tools/polly/lib/JSON/json_internalmap.inl | 607 + tools/polly/lib/JSON/json_reader.cpp | 890 + tools/polly/lib/JSON/json_value.cpp | 1727 + tools/polly/lib/JSON/json_valueiterator.inl | 292 + tools/polly/lib/JSON/json_writer.cpp | 829 + tools/polly/lib/JSON/sconscript | 8 + tools/polly/lib/Makefile | 81 + tools/polly/lib/MayAliasSet.cpp | 47 + tools/polly/lib/Pocc.cpp | 287 + tools/polly/lib/RegionSimplify.cpp | 222 + tools/polly/lib/RegisterPasses.cpp | 251 + tools/polly/lib/ScheduleOptimizer.cpp | 551 + tools/polly/lib/Support/CMakeLists.txt | 5 + tools/polly/lib/Support/GICHelper.cpp | 112 + tools/polly/lib/Support/Makefile | 16 + tools/polly/lib/Support/SCEVValidator.cpp | 302 + tools/polly/lib/Support/ScopHelper.cpp | 247 + tools/polly/svn.log | 3374 ++ tools/polly/test/CMakeLists.txt | 69 + tools/polly/test/Cloog/ambigous_schedule.ll | 118 + ...us_schedule___%for.cond---%for.end30.jscop | 28 + tools/polly/test/CodeGen/20100617.ll | 20 + tools/polly/test/CodeGen/20100622.ll | 44 + tools/polly/test/CodeGen/20100707.ll | 28 + tools/polly/test/CodeGen/20100707_2.ll | 116 + tools/polly/test/CodeGen/20100708.ll | 19 + tools/polly/test/CodeGen/20100708_2.ll | 29 + tools/polly/test/CodeGen/20100713.ll | 35 + tools/polly/test/CodeGen/20100713_2.ll | 35 + tools/polly/test/CodeGen/20100717.ll | 40 + .../polly/test/CodeGen/20100718-DomInfo-2.ll | 36 + tools/polly/test/CodeGen/20100718-DomInfo.ll | 29 + .../CodeGen/20100720-MultipleConditions.c | 23 + .../CodeGen/20100720-MultipleConditions.ll | 73 + .../test/CodeGen/20100809-IndependentBlock.ll | 31 + ...0100811-ScalarDependencyBetweenBrAndCnd.ll | 30 + tools/polly/test/CodeGen/20101030-Overflow.ll | 22 + .../polly/test/CodeGen/20101103-Overflow3.ll | 24 + .../test/CodeGen/20101103-signmissmatch.ll | 38 + .../test/CodeGen/20110226-Ignore-Dead-Code.ll | 60 + .../test/CodeGen/20110226-PHI-Node-removed.ll | 30 + .../CodeGen/20110312-Fail-without-basicaa.ll | 28 + .../memaccess_codegen_constant_offset.c | 8 + .../memaccess_codegen_constant_offset.ll | 34 + ...nstant_offset___%for.cond---%for.end.jscop | 25 + ...t___%for.cond---%for.end.jscop.transformed | 25 + .../MemAccess/memaccess_codegen_simple.c | 8 + .../MemAccess/memaccess_codegen_simple.ll | 34 + ...odegen_simple___%for.cond---%for.end.jscop | 25 + ...e___%for.cond---%for.end.jscop.transformed | 25 + .../test/CodeGen/MemAccess/memaccess_simple.c | 17 + .../CodeGen/MemAccess/memaccess_simple.ll | 47 + ...access_simple___%for.cond---%for.end.jscop | 17 + ...e___%for.cond---%for.end.jscop.transformed | 17 + ...ess_simple___%for.cond4---%for.end14.jscop | 17 + ..._%for.cond4---%for.end14.jscop.transformed | 17 + .../MemAccess/memaccess_simple_analyze.ll | 48 + tools/polly/test/CodeGen/OpenMP/add_memref.c | 10 + tools/polly/test/CodeGen/OpenMP/add_memref.ll | 29 + .../test/CodeGen/OpenMP/extract_memref.c | 17 + .../test/CodeGen/OpenMP/extract_memref.ll | 39 + .../CodeGen/OpenMP/invalidate_subfn_scops.c | 11 + .../CodeGen/OpenMP/invalidate_subfn_scops.ll | 38 + .../polly/test/CodeGen/OpenMP/parallel_loop.c | 21 + .../test/CodeGen/OpenMP/parallel_loop.ll | 186 + .../parallel_loop___%bb18---%bb50.jscop | 42 + .../parallel_loop___%bb18---%bb50.jscop.tiled | 42 + .../CodeGen/OpenMP/parallel_loop_simple.c | 15 + .../CodeGen/OpenMP/parallel_loop_simple.ll | 56 + .../CodeGen/OpenMP/parallel_loop_simple2.c | 15 + .../CodeGen/OpenMP/parallel_loop_simple2.ll | 64 + .../test/CodeGen/OpenMP/simple_nested_loop.c | 22 + .../test/CodeGen/OpenMP/simple_nested_loop.ll | 67 + tools/polly/test/CodeGen/OpenMP/structnames.c | 26 + .../polly/test/CodeGen/OpenMP/structnames.ll | 77 + tools/polly/test/CodeGen/OpenMP/two_loop.c | 24 + tools/polly/test/CodeGen/OpenMP/two_loop.ll | 56 + tools/polly/test/CodeGen/PHIInExit.ll | 77 + tools/polly/test/CodeGen/constant_condition.c | 23 + .../polly/test/CodeGen/constant_condition.ll | 32 + tools/polly/test/CodeGen/do_pluto_matmult.c | 74 + tools/polly/test/CodeGen/do_pluto_matmult.ll | 229 + .../test/CodeGen/do_pluto_matmult.ll.result | 36 + ...pluto_matmult___%do.body---%do.end45.jscop | 25 + ...%do.body---%do.end45.jscop.invalid_reverse | 25 + ...__%do.body---%do.end45.jscop.valid_reverse | 25 + .../polly/test/CodeGen/loop_with_condition.c | 39 + .../polly/test/CodeGen/loop_with_condition.ll | 140 + .../test/CodeGen/loop_with_condition_2.ll | 141 + .../test/CodeGen/loop_with_condition_ineq.c | 39 + .../test/CodeGen/loop_with_condition_ineq.ll | 141 + .../test/CodeGen/loop_with_condition_nested.c | 45 + .../CodeGen/loop_with_condition_nested.ll | 172 + tools/polly/test/CodeGen/matmul_vec.c | 46 + tools/polly/test/CodeGen/matmul_vec.ll | 92 + .../test/CodeGen/matmul_vec___%1---%17.jscop | 25 + tools/polly/test/CodeGen/pluto_matmult.c | 36 + tools/polly/test/CodeGen/pluto_matmult.ll | 111 + ...uto_matmult___%for.cond---%for.end47.jscop | 25 + tools/polly/test/CodeGen/reduction.c | 27 + tools/polly/test/CodeGen/reduction.ll | 63 + tools/polly/test/CodeGen/reduction_2.c | 23 + tools/polly/test/CodeGen/reduction_2.ll | 71 + tools/polly/test/CodeGen/scev.ll | 23 + tools/polly/test/CodeGen/sequential_loops.c | 31 + tools/polly/test/CodeGen/sequential_loops.ll | 108 + .../test/CodeGen/simple_nonaffine_loop.c | 15 + .../test/CodeGen/simple_nonaffine_loop.ll | 43 + .../test/CodeGen/simple_vec_assign_scalar.c | 15 + .../test/CodeGen/simple_vec_assign_scalar.ll | 43 + .../test/CodeGen/simple_vec_assign_scalar_2.c | 15 + .../CodeGen/simple_vec_assign_scalar_2.ll | 47 + tools/polly/test/CodeGen/simple_vec_cast.ll | 33 + tools/polly/test/CodeGen/simple_vec_const.c | 15 + tools/polly/test/CodeGen/simple_vec_const.ll | 43 + .../test/CodeGen/simple_vec_large_width.ll | 41 + .../test/CodeGen/simple_vec_stride_one.c | 15 + .../test/CodeGen/simple_vec_stride_one.ll | 52 + .../simple_vec_stride_one___%1---%5.jscop | 17 + .../polly/test/CodeGen/simple_vec_stride_x.c | 15 + .../polly/test/CodeGen/simple_vec_stride_x.ll | 59 + .../test/CodeGen/simple_vec_two_stmts.ll | 52 + .../single_do_loop_int_max_iterations.c | 34 + .../single_do_loop_int_max_iterations.ll | 59 + ..._max_iterations___%do.body---%do.end.jscop | 13 + .../single_do_loop_int_param_iterations.c | 25 + .../single_do_loop_int_param_iterations.ll | 51 + .../single_do_loop_ll_max_iterations.c | 25 + .../single_do_loop_ll_max_iterations.ll | 43 + .../CodeGen/single_do_loop_one_iteration.c | 25 + .../CodeGen/single_do_loop_one_iteration.ll | 45 + .../CodeGen/single_do_loop_scev_replace.c | 32 + .../CodeGen/single_do_loop_scev_replace.ll | 64 + tools/polly/test/CodeGen/single_loop.c | 20 + tools/polly/test/CodeGen/single_loop.ll | 66 + .../CodeGen/single_loop_int_max_iterations.c | 21 + .../CodeGen/single_loop_int_max_iterations.ll | 51 + .../CodeGen/single_loop_ll_max_iterations.c | 21 + .../CodeGen/single_loop_ll_max_iterations.ll | 51 + .../test/CodeGen/single_loop_one_iteration.c | 20 + .../test/CodeGen/single_loop_one_iteration.ll | 49 + tools/polly/test/CodeGen/single_loop_param.ll | 76 + .../CodeGen/single_loop_uint_max_iterations.c | 21 + .../single_loop_uint_max_iterations.ll | 50 + .../CodeGen/single_loop_ull_max_iterations.c | 21 + .../CodeGen/single_loop_ull_max_iterations.ll | 50 + .../CodeGen/single_loop_zero_iterations.c | 20 + .../CodeGen/single_loop_zero_iterations.ll | 50 + tools/polly/test/CodeGen/split_edges.ll | 34 + tools/polly/test/CodeGen/split_edges_2.ll | 33 + tools/polly/test/CodeGen/test.c | 19 + tools/polly/test/CodeGen/test.ll | 48 + tools/polly/test/Makefile | 56 + tools/polly/test/README | 1 + .../2011-08-25-crash_in_vectorizer.ll | 44 + .../ScopDetection/single_function_only.ll | 122 + .../20111108-Parameter-not-detected.ll | 56 + tools/polly/test/ScopInfo/Alias-0.ll | 35 + tools/polly/test/ScopInfo/Alias-1.ll | 36 + tools/polly/test/ScopInfo/Alias-2.ll | 33 + tools/polly/test/ScopInfo/Alias-3.ll | 27 + tools/polly/test/ScopInfo/Alias-4.ll | 27 + tools/polly/test/ScopInfo/bad_loop_0.ll | 45 + tools/polly/test/ScopInfo/bug_2010_10_22.ll | 47 + tools/polly/test/ScopInfo/bug_2011_1_5.ll | 61 + .../test/ScopInfo/bug_scev_not_fully_eval.ll | 36 + tools/polly/test/ScopInfo/cond_in_loop.ll | 48 + .../polly/test/ScopInfo/indvar_out_of_loop.ll | 41 + .../test/ScopInfo/indvar_out_of_loop_1.ll | 47 + .../test/ScopInfo/indvar_out_of_loop_2.ll | 45 + .../test/ScopInfo/loop_affine_bound_0.ll | 56 + .../test/ScopInfo/loop_affine_bound_1.ll | 54 + .../test/ScopInfo/loop_affine_bound_2.ll | 65 + tools/polly/test/ScopInfo/loop_carry.ll | 92 + .../test/ScopInfo/loop_complex_parameter.ll | 57 + tools/polly/test/ScopInfo/loop_depth_0.ll | 56 + tools/polly/test/ScopInfo/loop_multi_exits.ll | 101 + tools/polly/test/ScopInfo/out_of_loop_0.ll | 35 + .../test/ScopInfo/phi_not_grouped_at_top.ll | 30 + .../test/ScopInfo/phi_with_invoke_edge.ll | 27 + tools/polly/test/ScopInfo/simple_loop_1.ll | 30 + .../test/ScopInfo/simple_nonaffine_loop.ll | 41 + .../ScopInfo/simple_nonaffine_loop_not.ll | 41 + tools/polly/test/ScopInfo/undef_in_cond.ll | 24 + tools/polly/test/TempScop/not-a-reduction.c | 13 + tools/polly/test/TempScop/not-a-reduction.ll | 37 + tools/polly/test/create_ll.sh | 11 + tools/polly/test/lit.cfg | 97 + tools/polly/test/lit.site.cfg.in | 26 + tools/polly/test/polly.ll | 12 + tools/polly/test/polybench/README | 87 + .../datamining/correlation/correlation.c | 165 + .../correlation/correlation_with_param.ll | 169 + .../correlation/correlation_without_param.ll | 117 + .../datamining/covariance/covariance.c | 138 + .../covariance/covariance_with_param.ll | 203 + .../covariance/covariance_without_param.ll | 135 + .../linear-algebra/kernels/2mm/2mm.c | 168 + .../kernels/2mm/2mm_with_param.ll | 164 + .../kernels/2mm/2mm_without_param.ll | 101 + .../linear-algebra/kernels/2mm/compiler.opts | 1 + .../linear-algebra/kernels/3mm/3mm.c | 217 + .../kernels/3mm/3mm_with_param.ll | 213 + .../kernels/3mm/3mm_without_param.ll | 137 + .../linear-algebra/kernels/3mm/compiler.opts | 1 + .../linear-algebra/kernels/atax/atax.c | 119 + .../kernels/atax/atax_with_param.ll | 91 + .../kernels/atax/atax_without_param.ll | 77 + .../linear-algebra/kernels/bicg/bicg.c | 126 + .../kernels/bicg/bicg_with_param.ll | 101 + .../kernels/bicg/bicg_without_param.ll | 69 + .../linear-algebra/kernels/doitgen/doitgen.c | 141 + .../kernels/doitgen/doitgen_with_param.ll | 104 + .../kernels/doitgen/doitgen_without_param.ll | 79 + .../linear-algebra/kernels/gemm/compiler.opts | 1 + .../linear-algebra/kernels/gemm/gemm.c | 139 + .../kernels/gemm/gemm_with_param.ll | 98 + .../kernels/gemm/gemm_without_param.ll | 64 + .../linear-algebra/kernels/gemver/gemver.c | 146 + .../kernels/gemver/gemver_with_param.ll | 154 + .../kernels/gemver/gemver_without_param.ll | 138 + .../linear-algebra/kernels/gesummv/gesummv.c | 127 + .../kernels/gesummv/gesummv_with_param.ll | 73 + .../kernels/gesummv/gesummv_without_param.ll | 66 + .../solvers/gramschmidt/gramschmidt.c | 133 + .../gramschmidt/gramschmidt_with_param.ll | 175 + .../gramschmidt/gramschmidt_without_param.ll | 162 + .../polybench/linear-algebra/solvers/lu/lu.c | 110 + .../solvers/lu/lu_with_param.ll | 97 + .../solvers/lu/lu_without_param.ll | 89 + .../linear-algebra/solvers/ludcmp/ludcmp.c | 145 + .../solvers/ludcmp/ludcmp_with_param.ll | 301 + .../solvers/ludcmp/ludcmp_without_param.ll | 249 + tools/polly/test/polybench/scripts/compile.sh | 14 + tools/polly/test/polybench/scripts/runall.sh | 40 + tools/polly/test/polybench/stencils/adi/adi.c | 147 + .../polybench/stencils/adi/adi_with_param.ll | 251 + .../stencils/adi/adi_without_param.ll | 200 + .../jacobi-2d-imper/jacobi-2d-imper.c | 123 + .../jacobi-2d-imper_with_param.ll | 109 + .../jacobi-2d-imper_without_param.ll | 93 + .../test/polybench/stencils/seidel/seidel.c | 112 + .../stencils/seidel/seidel_with_param.ll | 96 + .../stencils/seidel/seidel_without_param.ll | 81 + .../test/polybench/utilities/instrument.c | 87 + .../test/polybench/utilities/instrument.h | 25 + .../utilities/template-for-new-benchmark.c | 99 + tools/polly/tools/CMakeLists.txt | 1 + tools/polly/tools/Makefile | 13 + tools/polly/utils/argparse.py | 2353 ++ tools/polly/utils/checkout_cloog.sh | 92 + tools/polly/utils/cloog_src/ChangeLog | 22 + tools/polly/utils/cloog_src/LICENSE | 458 + tools/polly/utils/cloog_src/Makefile.am | 179 + tools/polly/utils/cloog_src/Makefile.in | 1375 + tools/polly/utils/cloog_src/README | 203 + tools/polly/utils/cloog_src/aclocal.m4 | 991 + .../utils/cloog_src/autoconf/Doxyfile.in | 1101 + .../polly/utils/cloog_src/autoconf/c-ced.ssh | 81 + .../utils/cloog_src/autoconf/config.guess | 1533 + .../polly/utils/cloog_src/autoconf/config.sub | 1693 + tools/polly/utils/cloog_src/autoconf/depcomp | 630 + .../polly/utils/cloog_src/autoconf/install-sh | 520 + .../polly/utils/cloog_src/autoconf/ltmain.sh | 8413 ++++ tools/polly/utils/cloog_src/autoconf/missing | 376 + tools/polly/utils/cloog_src/autogen.sh | 5 + tools/polly/utils/cloog_src/configure | 15054 +++++++ tools/polly/utils/cloog_src/configure.ac | 263 + tools/polly/utils/cloog_src/doc/Makefile.am | 7 + tools/polly/utils/cloog_src/doc/Makefile.in | 387 + tools/polly/utils/cloog_src/doc/ROADMAP | 18 + .../utils/cloog_src/doc/SubmittingPatches | 41 + tools/polly/utils/cloog_src/doc/TODO | 58 + tools/polly/utils/cloog_src/doc/cloog.texi | 2571 ++ .../utils/cloog_src/doc/images/basic.eps | 402 + .../utils/cloog_src/doc/images/basic.fig | 100 + .../utils/cloog_src/doc/images/basic.jpg | Bin 0 -> 21180 bytes .../utils/cloog_src/doc/images/basic.pdf | Bin 0 -> 40073 bytes .../utils/cloog_src/doc/images/basic.txt | 13 + .../polly/utils/cloog_src/doc/images/tree.eps | 258 + .../polly/utils/cloog_src/doc/images/tree.fig | 54 + .../polly/utils/cloog_src/doc/images/tree.jpg | Bin 0 -> 13713 bytes .../polly/utils/cloog_src/doc/images/tree.pdf | Bin 0 -> 4558 bytes .../polly/utils/cloog_src/doc/images/tree.txt | 25 + tools/polly/utils/cloog_src/examples/README | 58 + .../utils/cloog_src/examples/example/Makefile | 21 + .../cloog_src/examples/example/example.c | 29 + tools/polly/utils/cloog_src/genversion.sh.in | 15 + tools/polly/utils/cloog_src/get_submodules.sh | 3 + .../utils/cloog_src/include/cloog/block.h | 117 + .../utils/cloog_src/include/cloog/clast.h | 154 + .../utils/cloog_src/include/cloog/cloog.h | 62 + .../cloog_src/include/cloog/constraints.h | 121 + .../utils/cloog_src/include/cloog/domain.h | 177 + .../utils/cloog_src/include/cloog/input.h | 27 + .../polly/utils/cloog_src/include/cloog/int.h | 174 + .../cloog_src/include/cloog/isl/backend.h | 11 + .../utils/cloog_src/include/cloog/isl/cloog.h | 22 + .../include/cloog/isl/constraintset.h | 33 + .../cloog_src/include/cloog/isl/domain.h | 36 + .../utils/cloog_src/include/cloog/loop.h | 120 + .../utils/cloog_src/include/cloog/matrix.h | 59 + .../include/cloog/matrix/constraintset.h | 28 + .../utils/cloog_src/include/cloog/names.h | 103 + .../utils/cloog_src/include/cloog/options.h | 165 + .../utils/cloog_src/include/cloog/pprint.h | 67 + .../utils/cloog_src/include/cloog/program.h | 116 + .../utils/cloog_src/include/cloog/state.h | 46 + .../utils/cloog_src/include/cloog/statement.h | 85 + .../utils/cloog_src/include/cloog/stride.h | 33 + .../cloog_src/include/cloog/union_domain.h | 52 + .../cloog_src/include/cloog/version.h.in | 50 + tools/polly/utils/cloog_src/isl/AUTHORS | 19 + tools/polly/utils/cloog_src/isl/ChangeLog | 72 + tools/polly/utils/cloog_src/isl/LICENSE | 458 + tools/polly/utils/cloog_src/isl/Makefile.am | 274 + tools/polly/utils/cloog_src/isl/Makefile.in | 2227 ++ tools/polly/utils/cloog_src/isl/aclocal.m4 | 995 + tools/polly/utils/cloog_src/isl/autogen.sh | 2 + .../utils/cloog_src/isl/basis_reduction_tab.c | 243 + .../cloog_src/isl/basis_reduction_templ.c | 357 + tools/polly/utils/cloog_src/isl/bound.c | 278 + .../utils/cloog_src/isl/bound_test.sh.in | 35 + tools/polly/utils/cloog_src/isl/cat.c | 58 + tools/polly/utils/cloog_src/isl/closure.c | 34 + tools/polly/utils/cloog_src/isl/config.guess | 1533 + tools/polly/utils/cloog_src/isl/config.sub | 1693 + tools/polly/utils/cloog_src/isl/configure | 20389 ++++++++++ tools/polly/utils/cloog_src/isl/configure.ac | 187 + tools/polly/utils/cloog_src/isl/depcomp | 630 + .../polly/utils/cloog_src/isl/doc/Makefile.am | 17 + .../polly/utils/cloog_src/isl/doc/Makefile.in | 410 + .../utils/cloog_src/isl/doc/SubmittingPatches | 41 + .../polly/utils/cloog_src/isl/doc/chicago.bst | 1726 + .../polly/utils/cloog_src/isl/doc/chicago.sty | 320 + .../cloog_src/isl/doc/implementation.tex | 2036 + tools/polly/utils/cloog_src/isl/doc/isl.bib | 313 + .../polly/utils/cloog_src/isl/doc/manual.tex | 75 + .../polly/utils/cloog_src/isl/doc/mypod2latex | 14 + tools/polly/utils/cloog_src/isl/doc/user.pod | 4370 ++ .../utils/cloog_src/isl/include/isl/aff.h | 363 + .../cloog_src/isl/include/isl/aff_type.h | 16 + .../utils/cloog_src/isl/include/isl/arg.h | 313 + .../utils/cloog_src/isl/include/isl/band.h | 42 + .../utils/cloog_src/isl/include/isl/blk.h | 40 + .../cloog_src/isl/include/isl/config.h.in | 3 + .../cloog_src/isl/include/isl/constraint.h | 126 + .../utils/cloog_src/isl/include/isl/ctx.h | 212 + .../utils/cloog_src/isl/include/isl/dim.h | 122 + .../utils/cloog_src/isl/include/isl/flow.h | 59 + .../utils/cloog_src/isl/include/isl/hash.h | 79 + .../utils/cloog_src/isl/include/isl/id.h | 32 + .../utils/cloog_src/isl/include/isl/ilp.h | 34 + .../utils/cloog_src/isl/include/isl/int.h | 134 + .../utils/cloog_src/isl/include/isl/list.h | 57 + .../cloog_src/isl/include/isl/local_space.h | 72 + .../utils/cloog_src/isl/include/isl/lp.h | 50 + .../utils/cloog_src/isl/include/isl/map.h | 594 + .../cloog_src/isl/include/isl/map_type.h | 28 + .../utils/cloog_src/isl/include/isl/mat.h | 116 + .../utils/cloog_src/isl/include/isl/multi.h | 22 + .../utils/cloog_src/isl/include/isl/obj.h | 64 + .../utils/cloog_src/isl/include/isl/options.h | 47 + .../utils/cloog_src/isl/include/isl/point.h | 43 + .../cloog_src/isl/include/isl/polynomial.h | 593 + .../isl/include/isl/polynomial_type.h | 31 + .../utils/cloog_src/isl/include/isl/printer.h | 58 + .../cloog_src/isl/include/isl/schedule.h | 52 + .../utils/cloog_src/isl/include/isl/seq.h | 58 + .../utils/cloog_src/isl/include/isl/set.h | 477 + .../cloog_src/isl/include/isl/set_type.h | 6 + .../utils/cloog_src/isl/include/isl/space.h | 137 + .../utils/cloog_src/isl/include/isl/stream.h | 110 + .../cloog_src/isl/include/isl/union_map.h | 192 + .../cloog_src/isl/include/isl/union_set.h | 130 + .../utils/cloog_src/isl/include/isl/vec.h | 75 + .../utils/cloog_src/isl/include/isl/version.h | 14 + .../cloog_src/isl/include/isl/vertices.h | 46 + tools/polly/utils/cloog_src/isl/install-sh | 520 + .../utils/cloog_src/isl/interface/Makefile.am | 30 + .../utils/cloog_src/isl/interface/Makefile.in | 575 + .../polly/utils/cloog_src/isl/interface/all.h | 4 + .../isl/interface/extract_interface.cc | 252 + .../isl/interface/extract_interface.h | 3 + .../utils/cloog_src/isl/interface/isl.py.top | 29 + .../utils/cloog_src/isl/interface/python.cc | 515 + .../utils/cloog_src/isl/interface/python.h | 7 + tools/polly/utils/cloog_src/isl/isl.py | 100 + tools/polly/utils/cloog_src/isl/isl_aff.c | 2635 ++ .../utils/cloog_src/isl/isl_aff_private.h | 100 + .../utils/cloog_src/isl/isl_affine_hull.c | 1016 + tools/polly/utils/cloog_src/isl/isl_arg.c | 1205 + tools/polly/utils/cloog_src/isl/isl_band.c | 188 + .../utils/cloog_src/isl/isl_band_private.h | 36 + .../utils/cloog_src/isl/isl_basis_reduction.h | 27 + .../polly/utils/cloog_src/isl/isl_bernstein.c | 554 + .../polly/utils/cloog_src/isl/isl_bernstein.h | 4 + tools/polly/utils/cloog_src/isl/isl_blk.c | 134 + tools/polly/utils/cloog_src/isl/isl_bound.c | 331 + tools/polly/utils/cloog_src/isl/isl_bound.h | 20 + .../polly/utils/cloog_src/isl/isl_coalesce.c | 1294 + .../polly/utils/cloog_src/isl/isl_config.h.in | 117 + .../utils/cloog_src/isl/isl_config_post.h | 3 + .../utils/cloog_src/isl/isl_constraint.c | 1170 + .../cloog_src/isl/isl_constraint_private.h | 18 + .../utils/cloog_src/isl/isl_convex_hull.c | 2435 ++ tools/polly/utils/cloog_src/isl/isl_ctx.c | 219 + .../utils/cloog_src/isl/isl_ctx_private.h | 28 + tools/polly/utils/cloog_src/isl/isl_dim.c | 258 + tools/polly/utils/cloog_src/isl/isl_dim_map.c | 233 + tools/polly/utils/cloog_src/isl/isl_dim_map.h | 36 + .../utils/cloog_src/isl/isl_equalities.c | 697 + .../utils/cloog_src/isl/isl_equalities.h | 31 + .../utils/cloog_src/isl/isl_factorization.c | 331 + .../utils/cloog_src/isl/isl_factorization.h | 29 + tools/polly/utils/cloog_src/isl/isl_farkas.c | 385 + tools/polly/utils/cloog_src/isl/isl_flow.c | 1355 + tools/polly/utils/cloog_src/isl/isl_fold.c | 1629 + tools/polly/utils/cloog_src/isl/isl_gmp.c | 24 + tools/polly/utils/cloog_src/isl/isl_hash.c | 209 + .../cloog_src/isl/isl_hmap_map_basic_set.c | 102 + .../cloog_src/isl/isl_hmap_map_basic_set.h | 26 + tools/polly/utils/cloog_src/isl/isl_id.c | 186 + .../utils/cloog_src/isl/isl_id_private.h | 28 + tools/polly/utils/cloog_src/isl/isl_ilp.c | 485 + tools/polly/utils/cloog_src/isl/isl_input.c | 2685 ++ tools/polly/utils/cloog_src/isl/isl_list.c | 38 + .../utils/cloog_src/isl/isl_list_private.h | 31 + .../utils/cloog_src/isl/isl_list_templ.c | 216 + .../utils/cloog_src/isl/isl_list_templ.h | 24 + .../utils/cloog_src/isl/isl_local_space.c | 897 + .../cloog_src/isl/isl_local_space_private.h | 56 + tools/polly/utils/cloog_src/isl/isl_lp.c | 204 + .../utils/cloog_src/isl/isl_lp_no_piplib.c | 18 + .../polly/utils/cloog_src/isl/isl_lp_piplib.c | 106 + .../polly/utils/cloog_src/isl/isl_lp_piplib.h | 28 + tools/polly/utils/cloog_src/isl/isl_map.c | 10011 +++++ .../utils/cloog_src/isl/isl_map_no_piplib.c | 20 + .../utils/cloog_src/isl/isl_map_piplib.c | 476 + .../utils/cloog_src/isl/isl_map_piplib.h | 27 + .../utils/cloog_src/isl/isl_map_private.h | 341 + .../utils/cloog_src/isl/isl_map_simplify.c | 2569 ++ .../utils/cloog_src/isl/isl_map_subtract.c | 856 + tools/polly/utils/cloog_src/isl/isl_mat.c | 1647 + .../utils/cloog_src/isl/isl_mat_private.h | 30 + tools/polly/utils/cloog_src/isl/isl_morph.c | 824 + tools/polly/utils/cloog_src/isl/isl_morph.h | 81 + .../utils/cloog_src/isl/isl_multi_templ.c | 391 + .../utils/cloog_src/isl/isl_multi_templ.h | 22 + tools/polly/utils/cloog_src/isl/isl_obj.c | 426 + tools/polly/utils/cloog_src/isl/isl_options.c | 209 + .../utils/cloog_src/isl/isl_options_private.h | 57 + tools/polly/utils/cloog_src/isl/isl_output.c | 2388 ++ tools/polly/utils/cloog_src/isl/isl_piplib.c | 26 + tools/polly/utils/cloog_src/isl/isl_piplib.h | 28 + tools/polly/utils/cloog_src/isl/isl_point.c | 500 + .../utils/cloog_src/isl/isl_point_private.h | 12 + .../utils/cloog_src/isl/isl_polynomial.c | 4781 +++ .../cloog_src/isl/isl_polynomial_private.h | 233 + tools/polly/utils/cloog_src/isl/isl_printer.c | 367 + .../utils/cloog_src/isl/isl_printer_private.h | 17 + .../polly/utils/cloog_src/isl/isl_pw_templ.c | 1571 + tools/polly/utils/cloog_src/isl/isl_qsort.c | 249 + tools/polly/utils/cloog_src/isl/isl_qsort.h | 7 + tools/polly/utils/cloog_src/isl/isl_range.c | 491 + tools/polly/utils/cloog_src/isl/isl_range.h | 6 + .../utils/cloog_src/isl/isl_reordering.c | 199 + .../utils/cloog_src/isl/isl_reordering.h | 31 + tools/polly/utils/cloog_src/isl/isl_sample.c | 1356 + tools/polly/utils/cloog_src/isl/isl_sample.h | 35 + .../cloog_src/isl/isl_sample_no_piplib.c | 16 + .../utils/cloog_src/isl/isl_sample_piplib.c | 73 + .../utils/cloog_src/isl/isl_sample_piplib.h | 25 + tools/polly/utils/cloog_src/isl/isl_scan.c | 304 + tools/polly/utils/cloog_src/isl/isl_scan.h | 24 + .../polly/utils/cloog_src/isl/isl_schedule.c | 2951 ++ .../cloog_src/isl/isl_schedule_private.h | 44 + tools/polly/utils/cloog_src/isl/isl_seq.c | 291 + tools/polly/utils/cloog_src/isl/isl_space.c | 1700 + .../utils/cloog_src/isl/isl_space_private.h | 51 + tools/polly/utils/cloog_src/isl/isl_stream.c | 735 + .../utils/cloog_src/isl/isl_stream_private.h | 4 + tools/polly/utils/cloog_src/isl/isl_tab.c | 3362 ++ tools/polly/utils/cloog_src/isl/isl_tab.h | 298 + tools/polly/utils/cloog_src/isl/isl_tab_pip.c | 5514 +++ tools/polly/utils/cloog_src/isl/isl_test.c | 2639 ++ .../cloog_src/isl/isl_transitive_closure.c | 3104 ++ .../polly/utils/cloog_src/isl/isl_union_map.c | 2329 ++ .../cloog_src/isl/isl_union_map_private.h | 9 + .../utils/cloog_src/isl/isl_union_templ.c | 801 + tools/polly/utils/cloog_src/isl/isl_vec.c | 344 + tools/polly/utils/cloog_src/isl/isl_version.c | 6 + .../polly/utils/cloog_src/isl/isl_vertices.c | 1567 + .../cloog_src/isl/isl_vertices_private.h | 64 + tools/polly/utils/cloog_src/isl/ltmain.sh | 8413 ++++ .../cloog_src/isl/m4/ax_c___attribute__.m4 | 66 + .../utils/cloog_src/isl/m4/ax_cc_maxopt.m4 | 188 + .../cloog_src/isl/m4/ax_cflags_warn_all.m4 | 149 + .../isl/m4/ax_check_compiler_flags.m4 | 74 + .../cloog_src/isl/m4/ax_compiler_vendor.m4 | 63 + .../isl/m4/ax_create_pkgconfig_info.m4 | 349 + .../cloog_src/isl/m4/ax_create_stdint_h.m4 | 739 + .../cloog_src/isl/m4/ax_detect_git_head.m4 | 27 + .../utils/cloog_src/isl/m4/ax_gcc_archflag.m4 | 213 + .../isl/m4/ax_gcc_warn_unused_result.m4 | 56 + .../cloog_src/isl/m4/ax_gcc_x86_cpuid.m4 | 77 + .../cloog_src/isl/m4/ax_set_warning_flags.m4 | 17 + .../utils/cloog_src/isl/m4/ax_submodule.m4 | 71 + tools/polly/utils/cloog_src/isl/m4/libtool.m4 | 7377 ++++ .../polly/utils/cloog_src/isl/m4/ltoptions.m4 | 368 + tools/polly/utils/cloog_src/isl/m4/ltsugar.m4 | 123 + .../polly/utils/cloog_src/isl/m4/ltversion.m4 | 23 + .../utils/cloog_src/isl/m4/lt~obsolete.m4 | 92 + tools/polly/utils/cloog_src/isl/missing | 376 + .../cloog_src/isl/mp_get_memory_functions.c | 14 + tools/polly/utils/cloog_src/isl/pip.c | 381 + .../polly/utils/cloog_src/isl/pip_test.sh.in | 28 + .../isl/polyhedron_detect_equalities.c | 24 + .../utils/cloog_src/isl/polyhedron_minimize.c | 104 + .../utils/cloog_src/isl/polyhedron_sample.c | 36 + .../polly/utils/cloog_src/isl/polytope_scan.c | 103 + tools/polly/utils/cloog_src/isl/print.c | 77 + tools/polly/utils/cloog_src/isl/print_templ.c | 33 + .../cloog_src/isl/test_inputs/affine.polylib | 9 + .../cloog_src/isl/test_inputs/affine2.polylib | 9 + .../cloog_src/isl/test_inputs/affine3.polylib | 7 + .../isl/test_inputs/application.omega | 3 + .../isl/test_inputs/application2.omega | 3 + .../isl/test_inputs/basicLinear.pwqp | 1 + .../isl/test_inputs/basicLinear2.pwqp | 1 + .../cloog_src/isl/test_inputs/basicTest.pwqp | 1 + .../test_inputs/basicTestParameterPosNeg.pwqp | 1 + .../cloog_src/isl/test_inputs/boulet.pip | 13 + .../cloog_src/isl/test_inputs/brisebarre.pip | 34 + .../utils/cloog_src/isl/test_inputs/cg1.pip | 15 + .../cloog_src/isl/test_inputs/convex0.polylib | 11 + .../cloog_src/isl/test_inputs/convex1.polylib | 17 + .../isl/test_inputs/convex10.polylib | 17 + .../isl/test_inputs/convex11.polylib | 14 + .../isl/test_inputs/convex12.polylib | 12 + .../isl/test_inputs/convex13.polylib | 17 + .../isl/test_inputs/convex14.polylib | 14 + .../isl/test_inputs/convex15.polylib | 66 + .../cloog_src/isl/test_inputs/convex2.polylib | 24 + .../cloog_src/isl/test_inputs/convex3.polylib | 10 + .../cloog_src/isl/test_inputs/convex4.polylib | 9 + .../cloog_src/isl/test_inputs/convex5.polylib | 12 + .../cloog_src/isl/test_inputs/convex6.polylib | 17 + .../cloog_src/isl/test_inputs/convex7.polylib | 9 + .../cloog_src/isl/test_inputs/convex8.polylib | 24 + .../cloog_src/isl/test_inputs/convex9.polylib | 14 + .../cloog_src/isl/test_inputs/devos.pwqp | 1 + .../cloog_src/isl/test_inputs/equality1.pwqp | 1 + .../cloog_src/isl/test_inputs/equality2.pwqp | 1 + .../cloog_src/isl/test_inputs/equality3.pwqp | 1 + .../cloog_src/isl/test_inputs/equality4.pwqp | 1 + .../cloog_src/isl/test_inputs/equality5.pwqp | 1 + .../utils/cloog_src/isl/test_inputs/esced.pip | 27 + .../utils/cloog_src/isl/test_inputs/ex.pip | 9 + .../utils/cloog_src/isl/test_inputs/ex2.pip | 9 + .../cloog_src/isl/test_inputs/faddeev.pwqp | 1 + .../cloog_src/isl/test_inputs/fimmel.pip | 12 + .../cloog_src/isl/test_inputs/gist1.polylib | 14 + .../isl/test_inputs/linearExample.pwqp | 1 + .../utils/cloog_src/isl/test_inputs/max.pip | 9 + .../utils/cloog_src/isl/test_inputs/neg.pwqp | 1 + .../cloog_src/isl/test_inputs/negative.pip | 9 + .../cloog_src/isl/test_inputs/philippe.pwqp | 1 + .../isl/test_inputs/philippe3vars.pwqp | 1 + .../isl/test_inputs/philippe3vars3pars.pwqp | 1 + .../isl/test_inputs/philippeNeg.pwqp | 1 + .../test_inputs/philippePolynomialCoeff.pwqp | 1 + .../philippePolynomialCoeff1P.pwqp | 1 + .../cloog_src/isl/test_inputs/product.pwqp | 1 + .../cloog_src/isl/test_inputs/seghir-vd.pip | 17 + .../utils/cloog_src/isl/test_inputs/set.omega | 1 + .../utils/cloog_src/isl/test_inputs/small.pip | 9 + .../utils/cloog_src/isl/test_inputs/sor1d.pip | 28 + .../cloog_src/isl/test_inputs/split.pwqp | 1 + .../cloog_src/isl/test_inputs/square.pip | 9 + .../utils/cloog_src/isl/test_inputs/sven.pip | 7 + .../isl/test_inputs/test3Deg3Var.pwqp | 1 + .../utils/cloog_src/isl/test_inputs/tobi.pip | 15 + .../cloog_src/isl/test_inputs/toplas.pwqp | 1 + .../cloog_src/isl/test_inputs/unexpanded.pwqp | 1 + .../polly/utils/cloog_src/m4/ax_cc_maxopt.m4 | 178 + .../utils/cloog_src/m4/ax_cflags_warn_all.m4 | 149 + .../cloog_src/m4/ax_check_compiler_flags.m4 | 74 + .../utils/cloog_src/m4/ax_compiler_vendor.m4 | 61 + .../cloog_src/m4/ax_create_pkgconfig_info.m4 | 349 + .../utils/cloog_src/m4/ax_gcc_archflag.m4 | 213 + .../utils/cloog_src/m4/ax_gcc_x86_cpuid.m4 | 77 + .../polly/utils/cloog_src/m4/ax_submodule.m4 | 63 + tools/polly/utils/cloog_src/m4/libtool.m4 | 7377 ++++ tools/polly/utils/cloog_src/m4/ltoptions.m4 | 368 + tools/polly/utils/cloog_src/m4/ltsugar.m4 | 123 + tools/polly/utils/cloog_src/m4/ltversion.m4 | 23 + tools/polly/utils/cloog_src/m4/lt~obsolete.m4 | 92 + tools/polly/utils/cloog_src/source/block.c | 404 + tools/polly/utils/cloog_src/source/clast.c | 1894 + tools/polly/utils/cloog_src/source/cloog.c | 98 + tools/polly/utils/cloog_src/source/input.c | 218 + tools/polly/utils/cloog_src/source/int.c | 177 + .../utils/cloog_src/source/isl/backend.c | 37 + .../utils/cloog_src/source/isl/constraints.c | 966 + .../polly/utils/cloog_src/source/isl/domain.c | 1913 + tools/polly/utils/cloog_src/source/loop.c | 2665 ++ tools/polly/utils/cloog_src/source/matrix.c | 213 + .../cloog_src/source/matrix/constraintset.c | 1056 + .../source/mp_get_memory_functions.c | 14 + tools/polly/utils/cloog_src/source/names.c | 526 + tools/polly/utils/cloog_src/source/options.c | 521 + tools/polly/utils/cloog_src/source/pprint.c | 493 + tools/polly/utils/cloog_src/source/program.c | 1077 + tools/polly/utils/cloog_src/source/state.c | 52 + .../polly/utils/cloog_src/source/statement.c | 280 + tools/polly/utils/cloog_src/source/stride.c | 70 + .../utils/cloog_src/source/union_domain.c | 366 + .../polly/utils/cloog_src/source/version.c.in | 24 + tools/polly/utils/cloog_src/test/0D-1.c | 2 + tools/polly/utils/cloog_src/test/0D-1.cloog | 13 + tools/polly/utils/cloog_src/test/0D-1.good.c | 15 + tools/polly/utils/cloog_src/test/0D-2.c | 4 + tools/polly/utils/cloog_src/test/0D-2.cloog | 14 + tools/polly/utils/cloog_src/test/0D-2.good.c | 17 + tools/polly/utils/cloog_src/test/0D-3.c | 2 + tools/polly/utils/cloog_src/test/0D-3.cloog | 15 + tools/polly/utils/cloog_src/test/0D-3.good.c | 15 + tools/polly/utils/cloog_src/test/1point-1.c | 2 + .../polly/utils/cloog_src/test/1point-1.cloog | 23 + .../utils/cloog_src/test/1point-1.good.c | 18 + tools/polly/utils/cloog_src/test/1point-2.c | 2 + .../polly/utils/cloog_src/test/1point-2.cloog | 23 + .../utils/cloog_src/test/1point-2.good.c | 19 + tools/polly/utils/cloog_src/test/4-param.c | 17 + .../polly/utils/cloog_src/test/4-param.cloog | 33 + .../polly/utils/cloog_src/test/4-param.good.c | 33 + tools/polly/utils/cloog_src/test/Makefile.am | 345 + tools/polly/utils/cloog_src/test/Makefile.in | 945 + tools/polly/utils/cloog_src/test/ard.cloog | 28 + tools/polly/utils/cloog_src/test/ard.dat | 13 + tools/polly/utils/cloog_src/test/backtrack.c | 2 + .../utils/cloog_src/test/backtrack.cloog | 24 + .../utils/cloog_src/test/backtrack.good.c | 19 + .../utils/cloog_src/test/basic-bounds-1.c | 4 + .../utils/cloog_src/test/basic-bounds-1.cloog | 21 + .../cloog_src/test/basic-bounds-1.good.c | 19 + .../utils/cloog_src/test/basic-bounds-2.c | 2 + .../utils/cloog_src/test/basic-bounds-2.cloog | 21 + .../cloog_src/test/basic-bounds-2.good.c | 17 + .../utils/cloog_src/test/basic-bounds-3.c | 4 + .../utils/cloog_src/test/basic-bounds-3.cloog | 23 + .../cloog_src/test/basic-bounds-3.good.c | 19 + .../utils/cloog_src/test/basic-bounds-4.c | 4 + .../utils/cloog_src/test/basic-bounds-4.cloog | 23 + .../cloog_src/test/basic-bounds-4.good.c | 19 + .../utils/cloog_src/test/basic-bounds-5.c | 3 + .../utils/cloog_src/test/basic-bounds-5.cloog | 22 + .../cloog_src/test/basic-bounds-5.good.c | 18 + .../utils/cloog_src/test/basic-bounds-6.c | 2 + .../utils/cloog_src/test/basic-bounds-6.cloog | 20 + .../cloog_src/test/basic-bounds-6.good.c | 17 + .../utils/cloog_src/test/bigs/applu.N.w2p12 | 2772 ++ .../utils/cloog_src/test/bigs/applu.N.w2p21 | 2484 ++ .../utils/cloog_src/test/bigs/applu12.loopgen | 2184 + .../utils/cloog_src/test/bigs/applu21.loopgen | 1959 + .../utils/cloog_src/test/bigs/apsi.N.w2p82 | 1255 + .../utils/cloog_src/test/bigs/apsi.N.w2p89 | 1221 + .../utils/cloog_src/test/bigs/dyfesm.N.w2p20 | 292 + .../test/bigs/lucas_distrib_spec.N.w2p1 | 2106 + .../test/bigs/lucas_distrib_spec.N.w2p10 | 2509 ++ .../utils/cloog_src/test/bigs/mg3d.N.w2p26 | 2293 ++ .../utils/cloog_src/test/bigs/qcd.N.w2p47 | 1328 + .../utils/cloog_src/test/bigs/qcd.N.w2p49 | 855 + .../utils/cloog_src/test/bigs/qcd.N.w2p8 | 1963 + .../utils/cloog_src/test/bigs/quake.N.w2p26 | 124 + tools/polly/utils/cloog_src/test/block.c | 5 + tools/polly/utils/cloog_src/test/block.cloog | 42 + tools/polly/utils/cloog_src/test/block.good.c | 24 + tools/polly/utils/cloog_src/test/block2.c | 6 + tools/polly/utils/cloog_src/test/block2.cloog | 77 + .../polly/utils/cloog_src/test/block2.good.c | 25 + tools/polly/utils/cloog_src/test/block3.c | 5 + tools/polly/utils/cloog_src/test/block3.cloog | 36 + .../polly/utils/cloog_src/test/block3.good.c | 24 + .../polly/utils/cloog_src/test/byu98-1-2-3.c | 24 + .../utils/cloog_src/test/byu98-1-2-3.cloog | 65 + .../utils/cloog_src/test/byu98-1-2-3.good.c | 41 + .../utils/cloog_src/test/ceilfloor.cloog | 21 + .../cloog_src/test/challenges/apsi.N.w2p56 | 1137 + .../test/challenges/challenge1.cloog | 217 + .../cloog_src/test/challenges/lucas.N.w2p11 | 33176 ++++++++++++++++ .../test/challenges/motionek1945.cloog | 178 + .../cloog_src/test/challenges/test2.N.cloog | 280 + .../cloog_src/test/challenges/test3.N.cloog | 350 + tools/polly/utils/cloog_src/test/check_c.sh | 38 + .../utils/cloog_src/test/check_fortran.sh | 38 + .../utils/cloog_src/test/check_openscop.sh | 38 + tools/polly/utils/cloog_src/test/check_run.sh | 55 + .../utils/cloog_src/test/check_special.sh | 47 + .../utils/cloog_src/test/check_strided.sh | 38 + tools/polly/utils/cloog_src/test/checker.sh | 126 + .../cloog_src/test/cholesau_allocation.cloog | 254 + .../cloog_src/test/cholesau_original.cloog | 245 + tools/polly/utils/cloog_src/test/cholesky.c | 36 + .../polly/utils/cloog_src/test/cholesky.cloog | 129 + .../utils/cloog_src/test/cholesky.good.c | 56 + tools/polly/utils/cloog_src/test/cholesky2.c | 67 + .../utils/cloog_src/test/cholesky2.cloog | 108 + .../utils/cloog_src/test/cholesky2.good.c | 114 + tools/polly/utils/cloog_src/test/christian.c | 17 + .../utils/cloog_src/test/christian.cloog | 57 + .../utils/cloog_src/test/christian.good.c | 35 + tools/polly/utils/cloog_src/test/classen.c | 101 + .../polly/utils/cloog_src/test/classen.cloog | 233 + .../polly/utils/cloog_src/test/classen.good.c | 396 + tools/polly/utils/cloog_src/test/classen2.c | 10 + .../polly/utils/cloog_src/test/classen2.cloog | 57 + .../utils/cloog_src/test/classen2.good.c | 27 + tools/polly/utils/cloog_src/test/constant.c | 17 + .../polly/utils/cloog_src/test/constant.cloog | 128 + .../utils/cloog_src/test/constant.good.c | 39 + tools/polly/utils/cloog_src/test/constbound.c | 13 + .../utils/cloog_src/test/constbound.cloog | 53 + .../utils/cloog_src/test/constbound.good.c | 31 + .../utils/cloog_src/test/daegon_lu_osp.cloog | 80 + tools/polly/utils/cloog_src/test/darte.c | 65 + tools/polly/utils/cloog_src/test/darte.cloog | 52 + tools/polly/utils/cloog_src/test/darte.good.c | 449 + tools/polly/utils/cloog_src/test/dartef.c | 442 + tools/polly/utils/cloog_src/test/dartef.cloog | 52 + tools/polly/utils/cloog_src/test/dartef.f | 65 + tools/polly/utils/cloog_src/test/dealII.c | 14 + tools/polly/utils/cloog_src/test/dealII.cloog | 54 + .../polly/utils/cloog_src/test/dealII.good.c | 30 + .../polly/utils/cloog_src/test/diagonal.cloog | 31 + tools/polly/utils/cloog_src/test/donotsimp.c | 9 + .../utils/cloog_src/test/donotsimp.cloog | 54 + .../utils/cloog_src/test/donotsimp.good.c | 27 + tools/polly/utils/cloog_src/test/dot.c | 9 + tools/polly/utils/cloog_src/test/dot.cloog | 33 + tools/polly/utils/cloog_src/test/dot.good.c | 25 + tools/polly/utils/cloog_src/test/dot2.c | 15 + tools/polly/utils/cloog_src/test/dot2.cloog | 29 + tools/polly/utils/cloog_src/test/dot2.good.c | 31 + tools/polly/utils/cloog_src/test/double.c | 11 + tools/polly/utils/cloog_src/test/double.cloog | 69 + .../polly/utils/cloog_src/test/double.good.c | 27 + tools/polly/utils/cloog_src/test/durbin_e_s.c | 25 + .../utils/cloog_src/test/durbin_e_s.cloog | 71 + .../utils/cloog_src/test/durbin_e_s.good.c | 78 + .../utils/cloog_src/test/elimination.cloog | 51 + tools/polly/utils/cloog_src/test/emploi.c | 16 + tools/polly/utils/cloog_src/test/emploi.cloog | 49 + .../polly/utils/cloog_src/test/emploi.good.c | 35 + tools/polly/utils/cloog_src/test/equality.c | 11 + .../polly/utils/cloog_src/test/equality.cloog | 33 + .../utils/cloog_src/test/equality.good.c | 27 + tools/polly/utils/cloog_src/test/equality2.c | 15 + .../utils/cloog_src/test/equality2.cloog | 57 + .../utils/cloog_src/test/equality2.good.c | 31 + tools/polly/utils/cloog_src/test/esced.c | 16 + tools/polly/utils/cloog_src/test/esced.cloog | 30 + tools/polly/utils/cloog_src/test/esced.good.c | 30 + tools/polly/utils/cloog_src/test/ex1.c | 18 + tools/polly/utils/cloog_src/test/ex1.cloog | 34 + tools/polly/utils/cloog_src/test/ex1.good.c | 34 + tools/polly/utils/cloog_src/test/faber.c | 4690 +++ tools/polly/utils/cloog_src/test/faber.cloog | 140 + .../utils/cloog_src/test/forwardsub-1-1-2.c | 11 + .../cloog_src/test/forwardsub-1-1-2.cloog | 56 + .../cloog_src/test/forwardsub-1-1-2.good.c | 29 + .../utils/cloog_src/test/forwardsub-2-1-2-3.c | 12 + .../cloog_src/test/forwardsub-2-1-2-3.cloog | 58 + .../cloog_src/test/forwardsub-2-1-2-3.good.c | 30 + .../utils/cloog_src/test/forwardsub-3-1-2.c | 23 + .../cloog_src/test/forwardsub-3-1-2.cloog | 57 + .../cloog_src/test/forwardsub-3-1-2.good.c | 42 + tools/polly/utils/cloog_src/test/gauss.c | 18 + tools/polly/utils/cloog_src/test/gauss.cloog | 72 + tools/polly/utils/cloog_src/test/gauss.good.c | 36 + .../utils/cloog_src/test/generate_test.c | 153 + tools/polly/utils/cloog_src/test/gesced.c | 20 + tools/polly/utils/cloog_src/test/gesced.cloog | 56 + .../polly/utils/cloog_src/test/gesced.good.c | 43 + tools/polly/utils/cloog_src/test/gesced2.c | 26 + .../polly/utils/cloog_src/test/gesced2.cloog | 82 + .../polly/utils/cloog_src/test/gesced2.good.c | 69 + tools/polly/utils/cloog_src/test/gesced3.c | 11 + .../polly/utils/cloog_src/test/gesced3.cloog | 39 + .../polly/utils/cloog_src/test/gesced3.good.c | 33 + tools/polly/utils/cloog_src/test/guide.c | 9 + tools/polly/utils/cloog_src/test/guide.cloog | 35 + tools/polly/utils/cloog_src/test/guide.good.c | 28 + tools/polly/utils/cloog_src/test/iftest.c | 6 + tools/polly/utils/cloog_src/test/iftest.cloog | 28 + .../polly/utils/cloog_src/test/iftest.good.c | 24 + tools/polly/utils/cloog_src/test/iftest2.c | 8 + .../polly/utils/cloog_src/test/iftest2.cloog | 31 + .../polly/utils/cloog_src/test/iftest2.good.c | 28 + .../polly/utils/cloog_src/test/iftestf.cloog | 29 + tools/polly/utils/cloog_src/test/iftestf.f | 6 + tools/polly/utils/cloog_src/test/infinite.c | 13 + .../polly/utils/cloog_src/test/infinite.cloog | 32 + .../polly/utils/cloog_src/test/infinite.omega | 13 + tools/polly/utils/cloog_src/test/infinite2.c | 10 + .../utils/cloog_src/test/infinite2.cloog | 32 + tools/polly/utils/cloog_src/test/infinite3.c | 18 + .../utils/cloog_src/test/infinite3.cloog | 32 + tools/polly/utils/cloog_src/test/infinite4.c | 4 + .../utils/cloog_src/test/infinite4.cloog | 16 + .../utils/cloog_src/test/isl/jacobi-shared.c | 11 + .../cloog_src/test/isl/jacobi-shared.cloog | 129 + .../cloog_src/test/isl/jacobi-shared.good.c | 28 + tools/polly/utils/cloog_src/test/isl/mod.c | 6 + .../polly/utils/cloog_src/test/isl/mod.cloog | 23 + tools/polly/utils/cloog_src/test/isl/mod2.c | 6 + .../polly/utils/cloog_src/test/isl/mod2.cloog | 20 + tools/polly/utils/cloog_src/test/isl/mod3.c | 8 + .../polly/utils/cloog_src/test/isl/mod3.cloog | 34 + tools/polly/utils/cloog_src/test/isl/mod4.c | 10 + .../polly/utils/cloog_src/test/isl/mod4.cloog | 23 + .../utils/cloog_src/test/isl/mxm-shared.c | 8 + .../utils/cloog_src/test/isl/mxm-shared.cloog | 162 + tools/polly/utils/cloog_src/test/isl/unroll.c | 12 + .../utils/cloog_src/test/isl/unroll.cloog | 14 + .../utils/cloog_src/test/isl/unroll.good.c | 27 + .../polly/utils/cloog_src/test/isl/unroll2.c | 7 + .../utils/cloog_src/test/isl/unroll2.cloog | 14 + .../utils/cloog_src/test/isl/unroll2.good.c | 21 + tools/polly/utils/cloog_src/test/ispdc.cloog | 26 + tools/polly/utils/cloog_src/test/issues | 66 + tools/polly/utils/cloog_src/test/largeur.c | 8 + .../polly/utils/cloog_src/test/largeur.cloog | 26 + .../polly/utils/cloog_src/test/largeur.good.c | 23 + .../utils/cloog_src/test/levenshtein-1-2-3.c | 37 + .../cloog_src/test/levenshtein-1-2-3.cloog | 110 + .../cloog_src/test/levenshtein-1-2-3.good.c | 62 + .../utils/cloog_src/test/levenshtein-1-2-3f.c | 42 + .../cloog_src/test/levenshtein-1-2-3f.cloog | 110 + .../utils/cloog_src/test/levenshtein-1-2-3f.f | 37 + tools/polly/utils/cloog_src/test/lex.c | 5 + tools/polly/utils/cloog_src/test/lex.cloog | 35 + tools/polly/utils/cloog_src/test/lex.good.c | 23 + .../utils/cloog_src/test/lineality-1-2.c | 11 + .../utils/cloog_src/test/lineality-1-2.cloog | 36 + .../utils/cloog_src/test/lineality-1-2.good.c | 37 + .../utils/cloog_src/test/lineality-2-1-2.c | 16 + .../cloog_src/test/lineality-2-1-2.cloog | 36 + .../cloog_src/test/lineality-2-1-2.good.c | 43 + tools/polly/utils/cloog_src/test/logo.c | 21 + tools/polly/utils/cloog_src/test/logo.cloog | 30 + tools/polly/utils/cloog_src/test/logo.good.c | 43 + tools/polly/utils/cloog_src/test/logopar.c | 21 + .../polly/utils/cloog_src/test/logopar.cloog | 33 + .../polly/utils/cloog_src/test/logopar.good.c | 50 + tools/polly/utils/cloog_src/test/lu.c | 21 + tools/polly/utils/cloog_src/test/lu.cloog | 47 + tools/polly/utils/cloog_src/test/lu.good.c | 44 + tools/polly/utils/cloog_src/test/lu2.c | 21 + tools/polly/utils/cloog_src/test/lu2.cloog | 37 + tools/polly/utils/cloog_src/test/lu2.good.c | 42 + tools/polly/utils/cloog_src/test/lub.c | 13 + tools/polly/utils/cloog_src/test/lub.cloog | 58 + tools/polly/utils/cloog_src/test/lub.good.c | 29 + tools/polly/utils/cloog_src/test/lux.c | 21 + tools/polly/utils/cloog_src/test/lux.cloog | 36 + tools/polly/utils/cloog_src/test/lux.good.c | 39 + .../utils/cloog_src/test/manual_basic.cloog | 31 + .../utils/cloog_src/test/manual_gauss.cloog | 64 + .../cloog_src/test/manual_scattering.cloog | 56 + tools/polly/utils/cloog_src/test/merge.c | 8 + tools/polly/utils/cloog_src/test/merge.cloog | 42 + tools/polly/utils/cloog_src/test/merge.good.c | 29 + tools/polly/utils/cloog_src/test/min-1-1.c | 8 + .../polly/utils/cloog_src/test/min-1-1.cloog | 27 + .../polly/utils/cloog_src/test/min-1-1.good.c | 23 + tools/polly/utils/cloog_src/test/min-2-1.c | 10 + .../polly/utils/cloog_src/test/min-2-1.cloog | 31 + .../polly/utils/cloog_src/test/min-2-1.good.c | 25 + tools/polly/utils/cloog_src/test/min-3-1.c | 6 + .../polly/utils/cloog_src/test/min-3-1.cloog | 27 + .../polly/utils/cloog_src/test/min-3-1.good.c | 21 + tools/polly/utils/cloog_src/test/min-4-1.c | 6 + .../polly/utils/cloog_src/test/min-4-1.cloog | 25 + .../polly/utils/cloog_src/test/min-4-1.good.c | 19 + tools/polly/utils/cloog_src/test/mod4.c | 6 + tools/polly/utils/cloog_src/test/mod4.cloog | 72 + tools/polly/utils/cloog_src/test/mode.c | 24 + tools/polly/utils/cloog_src/test/mode.cloog | 33 + tools/polly/utils/cloog_src/test/mode.good.c | 50 + tools/polly/utils/cloog_src/test/multi-mm-1.c | 10 + .../utils/cloog_src/test/multi-mm-1.cloog | 37 + .../utils/cloog_src/test/multi-mm-1.good.c | 32 + .../polly/utils/cloog_src/test/multi-stride.c | 1 + .../utils/cloog_src/test/multi-stride.cloog | 28 + .../utils/cloog_src/test/multi-stride2.c | 4 + .../utils/cloog_src/test/multi-stride2.cloog | 28 + tools/polly/utils/cloog_src/test/no_lindep.c | 2 + .../utils/cloog_src/test/no_lindep.cloog | 34 + .../utils/cloog_src/test/no_lindep.good.c | 21 + .../cloog_src/test/non_optimal/deuxpts.cloog | 35 + .../test/non_optimal/dreamupT1.cloog | 32 + .../non_optimal/dreamupT3-delta-gamma.cloog | 58 + .../test/non_optimal/dreamupT3.cloog | 58 + .../test/non_optimal/dreamupT3.omega | 17 + .../non_optimal/interpolation-duration.cloog | 74 + .../cloog_src/test/non_optimal/nul_complex1.c | 10 + .../test/non_optimal/nul_complex1.cloog | 37 + .../test/non_optimal/nul_complex1.good.c | 27 + .../cloog_src/test/non_optimal/usvd_e_t.c | 375 + .../cloog_src/test/non_optimal/usvd_e_t.cloog | 240 + .../test/non_optimal/usvd_e_t.good.c | 429 + .../utils/cloog_src/test/non_optimal/youcef.c | 8 + .../cloog_src/test/non_optimal/youcef.cloog | 46 + .../cloog_src/test/non_optimal/youcef.good.c | 34 + tools/polly/utils/cloog_src/test/nul_basic1.c | 6 + .../utils/cloog_src/test/nul_basic1.cloog | 28 + tools/polly/utils/cloog_src/test/nul_basic2.c | 7 + .../utils/cloog_src/test/nul_basic2.cloog | 54 + .../utils/cloog_src/test/nul_girbal.cloog | 89 + .../utils/cloog_src/test/nul_ispdc.cloog | 39 + tools/polly/utils/cloog_src/test/nul_lcpc.c | 15 + .../polly/utils/cloog_src/test/nul_lcpc.cloog | 39 + tools/polly/utils/cloog_src/test/oc.out | 0 .../utils/cloog_src/test/openscop/empty.c | 1 + .../utils/cloog_src/test/openscop/empty.scop | 35 + .../utils/cloog_src/test/openscop/matmult.c | 9 + .../cloog_src/test/openscop/matmult.scop | 140 + .../utils/cloog_src/test/openscop/union.c | 11 + .../utils/cloog_src/test/openscop/union.scop | 106 + tools/polly/utils/cloog_src/test/orc.c | 68 + tools/polly/utils/cloog_src/test/orc.cloog | 133 + tools/polly/utils/cloog_src/test/orc.good.c | 110 + tools/polly/utils/cloog_src/test/otl.c | 28 + tools/polly/utils/cloog_src/test/otl.cloog | 117 + tools/polly/utils/cloog_src/test/otl.good.c | 45 + .../polly/utils/cloog_src/test/overlap.cloog | 35 + .../polly/utils/cloog_src/test/param-split.c | 10 + .../utils/cloog_src/test/param-split.cloog | 24 + .../utils/cloog_src/test/param-split.good.c | 27 + tools/polly/utils/cloog_src/test/pouchet.c | 22 + .../polly/utils/cloog_src/test/pouchet.cloog | 76 + .../polly/utils/cloog_src/test/pouchet.good.c | 40 + .../test/published/CC2003/esced.cloog | 30 + .../cloog_src/test/published/CC2006/QR.cloog | 229 + .../test/published/CC2006/classen2.cloog | 226 + .../test/published/CC2006/dreamupT3.cloog | 58 + .../CC2006/swim.B.MAIN__.scop7.cloog | 5369 +++ .../test/published/PACT2004/youcefn.cloog | 49 + .../cloog_src/test/published/Web/web1.cloog | 81 + .../cloog_src/test/published/Web/web2.cloog | 85 + .../cloog_src/test/published/Web/web3.cloog | 73 + .../cloog_src/test/published/Web/web4.cloog | 62 + .../cloog_src/test/published/Web/web5.cloog | 261 + .../cloog_src/test/published/Web/web6.cloog | 269 + .../cloog_src/test/published/Web/web7.cloog | 30 + .../polly/utils/cloog_src/test/quillere.cloog | 35 + .../polly/utils/cloog_src/test/rational.cloog | 23 + tools/polly/utils/cloog_src/test/readme.cloog | 27 + tools/polly/utils/cloog_src/test/rectangle.c | 6 + .../utils/cloog_src/test/rectangle.cloog | 29 + .../utils/cloog_src/test/rectangle.good.c | 24 + .../test/reports/fabrice_baray_29-10-2004 | 99 + .../test/reports/kim_daegon_27-04-2005.eml | 17578 ++++++++ .../test/reports/kristof_beyls_16-05-2005.txt | 933 + .../reports/michael_classen_03-05-2005.eml | 333 + .../reports/michael_classen_27-10-2004.txt | 59 + .../reports/nicolas_vasilache_03-05-2005.eml | 306 + .../reports/nicolas_vasilache_09-05-2005.txt | 44 + .../reports/sergej_schwenk_01-06-2004.txt | 39 + .../reports/sylvain_girbal_01-11-2004.txt | 11 + .../reports/sylvain_girbal_24-02-2004.txt | 135 + .../polly/utils/cloog_src/test/reservoir/QR.c | 117 + .../utils/cloog_src/test/reservoir/QR.cloog | 228 + .../utils/cloog_src/test/reservoir/QR.good.c | 208 + .../utils/cloog_src/test/reservoir/bastoul3.c | 6 + .../cloog_src/test/reservoir/bastoul3.cloog | 33 + .../cloog_src/test/reservoir/cholesky2.c | 33 + .../cloog_src/test/reservoir/cholesky2.cloog | 79 + .../cloog_src/test/reservoir/cholesky2.good.c | 72 + .../utils/cloog_src/test/reservoir/fusion1.c | 10 + .../cloog_src/test/reservoir/fusion1.cloog | 65 + .../cloog_src/test/reservoir/fusion1.good.c | 29 + .../utils/cloog_src/test/reservoir/fusion2.c | 17 + .../cloog_src/test/reservoir/fusion2.cloog | 56 + .../cloog_src/test/reservoir/fusion2.good.c | 41 + .../utils/cloog_src/test/reservoir/jacobi2.c | 6 + .../cloog_src/test/reservoir/jacobi2.cloog | 37 + .../cloog_src/test/reservoir/jacobi2.good.c | 23 + .../utils/cloog_src/test/reservoir/jacobi3.c | 29 + .../cloog_src/test/reservoir/jacobi3.cloog | 64 + .../cloog_src/test/reservoir/jacobi3.good.c | 53 + .../utils/cloog_src/test/reservoir/lim-lam1.c | 25 + .../cloog_src/test/reservoir/lim-lam1.cloog | 54 + .../cloog_src/test/reservoir/lim-lam1.good.c | 56 + .../utils/cloog_src/test/reservoir/lim-lam2.c | 18 + .../cloog_src/test/reservoir/lim-lam2.cloog | 76 + .../cloog_src/test/reservoir/lim-lam2.good.c | 37 + .../utils/cloog_src/test/reservoir/lim-lam3.c | 36 + .../cloog_src/test/reservoir/lim-lam3.cloog | 101 + .../cloog_src/test/reservoir/lim-lam3.good.c | 66 + .../utils/cloog_src/test/reservoir/lim-lam4.c | 17 + .../cloog_src/test/reservoir/lim-lam4.cloog | 62 + .../cloog_src/test/reservoir/lim-lam4.good.c | 39 + .../utils/cloog_src/test/reservoir/lim-lam5.c | 18 + .../cloog_src/test/reservoir/lim-lam5.cloog | 76 + .../cloog_src/test/reservoir/lim-lam5.good.c | 35 + .../utils/cloog_src/test/reservoir/lim-lam6.c | 13 + .../cloog_src/test/reservoir/lim-lam6.cloog | 56 + .../cloog_src/test/reservoir/lim-lam6.good.c | 33 + .../cloog_src/test/reservoir/liu-zhuge1.c | 47 + .../cloog_src/test/reservoir/liu-zhuge1.cloog | 76 + .../test/reservoir/liu-zhuge1.good.c | 168 + .../cloog_src/test/reservoir/loechner3.c | 10 + .../cloog_src/test/reservoir/loechner3.cloog | 39 + .../cloog_src/test/reservoir/loechner3.good.c | 26 + .../cloog_src/test/reservoir/loechner4.c | 12 + .../cloog_src/test/reservoir/loechner4.cloog | 44 + .../cloog_src/test/reservoir/loechner4.good.c | 28 + .../cloog_src/test/reservoir/loechner5.c | 12 + .../cloog_src/test/reservoir/loechner5.cloog | 44 + .../cloog_src/test/reservoir/loechner5.good.c | 27 + .../utils/cloog_src/test/reservoir/long.c | 20 + .../utils/cloog_src/test/reservoir/long.cloog | 127 + .../utils/cloog_src/test/reservoir/makefile | 80 + .../cloog_src/test/reservoir/mg-interp.c | 219 + .../cloog_src/test/reservoir/mg-interp.cloog | 376 + .../cloog_src/test/reservoir/mg-interp.good.c | 318 + .../cloog_src/test/reservoir/mg-interp2.c | 39 + .../cloog_src/test/reservoir/mg-interp2.cloog | 112 + .../test/reservoir/mg-interp2.good.c | 57 + .../utils/cloog_src/test/reservoir/mg-psinv.c | 39 + .../cloog_src/test/reservoir/mg-psinv.cloog | 88 + .../cloog_src/test/reservoir/mg-psinv.good.c | 71 + .../utils/cloog_src/test/reservoir/mg-resid.c | 39 + .../cloog_src/test/reservoir/mg-resid.cloog | 88 + .../cloog_src/test/reservoir/mg-resid.good.c | 71 + .../utils/cloog_src/test/reservoir/mg-rprj3.c | 47 + .../cloog_src/test/reservoir/mg-rprj3.cloog | 136 + .../cloog_src/test/reservoir/mg-rprj3.good.c | 163 + .../utils/cloog_src/test/reservoir/pingali1.c | 21 + .../cloog_src/test/reservoir/pingali1.cloog | 61 + .../cloog_src/test/reservoir/pingali1.good.c | 44 + .../utils/cloog_src/test/reservoir/pingali2.c | 13 + .../cloog_src/test/reservoir/pingali2.cloog | 56 + .../cloog_src/test/reservoir/pingali2.good.c | 29 + .../utils/cloog_src/test/reservoir/pingali3.c | 15 + .../cloog_src/test/reservoir/pingali3.cloog | 62 + .../cloog_src/test/reservoir/pingali3.good.c | 31 + .../utils/cloog_src/test/reservoir/pingali4.c | 11 + .../cloog_src/test/reservoir/pingali4.cloog | 57 + .../cloog_src/test/reservoir/pingali4.good.c | 29 + .../utils/cloog_src/test/reservoir/pingali5.c | 21 + .../cloog_src/test/reservoir/pingali5.cloog | 81 + .../cloog_src/test/reservoir/pingali5.good.c | 44 + .../utils/cloog_src/test/reservoir/pingali6.c | 29 + .../cloog_src/test/reservoir/pingali6.cloog | 66 + .../cloog_src/test/reservoir/pingali6.good.c | 53 + .../utils/cloog_src/test/reservoir/stride.c | 6 + .../cloog_src/test/reservoir/stride.cloog | 45 + .../utils/cloog_src/test/reservoir/stride2.c | 6 + .../cloog_src/test/reservoir/stride2.cloog | 45 + .../cloog_src/test/reservoir/tang-xue1.c | 14 + .../cloog_src/test/reservoir/tang-xue1.cloog | 80 + .../cloog_src/test/reservoir/tang-xue1.good.c | 34 + .../utils/cloog_src/test/reservoir/two.c | 2 + .../utils/cloog_src/test/reservoir/two.cloog | 26 + .../utils/cloog_src/test/reservoir/two.good.c | 23 + tools/polly/utils/cloog_src/test/singleton.c | 3 + .../utils/cloog_src/test/singleton.cloog | 27 + .../utils/cloog_src/test/singleton.good.c | 17 + tools/polly/utils/cloog_src/test/sor1d.c | 19 + tools/polly/utils/cloog_src/test/sor1d.cloog | 256 + tools/polly/utils/cloog_src/test/sor1d.good.c | 39 + .../cloog_src/test/square+triangle-1-1-2-3.c | 14 + .../test/square+triangle-1-1-2-3.cloog | 36 + .../test/square+triangle-1-1-2-3.good.c | 37 + tools/polly/utils/cloog_src/test/stage.cloog | 36 + tools/polly/utils/cloog_src/test/stride.c | 9 + tools/polly/utils/cloog_src/test/stride.cloog | 32 + .../polly/utils/cloog_src/test/stride.good.c | 27 + tools/polly/utils/cloog_src/test/stride2.c | 7 + .../polly/utils/cloog_src/test/stride2.cloog | 32 + .../polly/utils/cloog_src/test/stride2.good.c | 25 + tools/polly/utils/cloog_src/test/stride3.c | 6 + .../polly/utils/cloog_src/test/stride3.cloog | 41 + tools/polly/utils/cloog_src/test/stride4.c | 6 + .../polly/utils/cloog_src/test/stride4.cloog | 33 + tools/polly/utils/cloog_src/test/swim.c | 672 + tools/polly/utils/cloog_src/test/swim.cloog | 2453 ++ tools/polly/utils/cloog_src/test/swim.good.c | 819 + tools/polly/utils/cloog_src/test/test.c | 21 + tools/polly/utils/cloog_src/test/test.cloog | 33 + tools/polly/utils/cloog_src/test/test.good.c | 43 + tools/polly/utils/cloog_src/test/tete.cloog | 30 + tools/polly/utils/cloog_src/test/thomasset.c | 49 + .../utils/cloog_src/test/thomasset.cloog | 51 + .../utils/cloog_src/test/thomasset.good.c | 99 + tools/polly/utils/cloog_src/test/tiling.c | 6 + tools/polly/utils/cloog_src/test/tiling.cloog | 30 + .../polly/utils/cloog_src/test/tiling.good.c | 21 + .../polly/utils/cloog_src/test/tiling2.cloog | 32 + .../polly/utils/cloog_src/test/tiling3.cloog | 41 + .../polly/utils/cloog_src/test/uday_scalars.c | 9 + .../utils/cloog_src/test/uday_scalars.cloog | 58 + .../utils/cloog_src/test/uday_scalars.good.c | 25 + tools/polly/utils/cloog_src/test/union.c | 16 + tools/polly/utils/cloog_src/test/union.cloog | 33 + tools/polly/utils/cloog_src/test/union.good.c | 35 + .../test/urgent/matmul.B.main.scop1.cloog | 217 + .../utils/cloog_src/test/urgent/matmul.cloog | 217 + .../utils/cloog_src/test/urgent/matmul1.cloog | 246 + .../utils/cloog_src/test/urgent/scop7.cloog | 3322 ++ .../utils/cloog_src/test/urgent/swim.cloog | 2453 ++ .../utils/cloog_src/test/urgent/swim7.cloog | 5369 +++ tools/polly/utils/cloog_src/test/vasilache.c | 27 + .../utils/cloog_src/test/vasilache.cloog | 248 + .../utils/cloog_src/test/vasilache.good.c | 62 + tools/polly/utils/cloog_src/test/vivien.c | 195 + tools/polly/utils/cloog_src/test/vivien.cloog | 156 + .../polly/utils/cloog_src/test/vivien.good.c | 831 + tools/polly/utils/cloog_src/test/vivien2.c | 168 + .../polly/utils/cloog_src/test/vivien2.cloog | 156 + .../polly/utils/cloog_src/test/vivien2.good.c | 656 + tools/polly/utils/cloog_src/test/walters.c | 21 + .../polly/utils/cloog_src/test/walters.cloog | 189 + .../polly/utils/cloog_src/test/walters.good.c | 46 + tools/polly/utils/cloog_src/test/walters2.c | 14 + .../polly/utils/cloog_src/test/walters2.cloog | 90 + .../utils/cloog_src/test/walters2.good.c | 32 + tools/polly/utils/cloog_src/test/walters3.c | 8 + .../polly/utils/cloog_src/test/walters3.cloog | 49 + .../utils/cloog_src/test/walters3.good.c | 24 + tools/polly/utils/cloog_src/test/wavefront.c | 8 + .../utils/cloog_src/test/wavefront.cloog | 27 + .../utils/cloog_src/test/wavefront.good.c | 26 + tools/polly/utils/cloog_src/test/yosr.c | 21 + tools/polly/utils/cloog_src/test/yosr.cloog | 65 + tools/polly/utils/cloog_src/test/yosr.good.c | 41 + tools/polly/utils/cloog_src/test/yosr.omega | 17 + tools/polly/utils/cloog_src/test/yosr2.c | 23 + tools/polly/utils/cloog_src/test/yosr2.cloog | 71 + tools/polly/utils/cloog_src/test/yosr2.good.c | 43 + .../utils/cloog_src/test/yosr_sync.cloog | 102 + tools/polly/utils/cloog_src/test/yosrf.cloog | 65 + tools/polly/utils/cloog_src/test/yosrf.f | 21 + .../polly/utils/cloog_src/test/youcefn.cloog | 49 + tools/polly/utils/jscop2cloog.py | 68 + tools/polly/utils/pyscop/isl.py | 578 + tools/polly/utils/pyscop/jscop2iscc.py | 68 + tools/polly/utils/pyscop/pyscop.py | 68 + tools/polly/www/.htaccess | 1 + tools/polly/www/bugs.html | 38 + tools/polly/www/content.css | 39 + tools/polly/www/contributors.html | 58 + tools/polly/www/documentation.html | 26 + tools/polly/www/documentation/memaccess.html | 109 + tools/polly/www/documentation/passes.html | 68 + .../www/example_load_Polly_into_clang.html | 131 + tools/polly/www/example_manual_matmul.html | 455 + tools/polly/www/examples.html | 37 + tools/polly/www/experiments/matmul/.htaccess | 1 + .../matmul/init_array___%1---%19.jscop | 21 + .../experiments/matmul/main___%1---%17.jscop | 40 + .../matmul/main___%1---%17.jscop.interchanged | 40 + .../main___%1---%17.jscop.interchanged+tiled | 40 + ...__%1---%17.jscop.interchanged+tiled+vector | 40 + tools/polly/www/experiments/matmul/matmul.c | 52 + .../experiments/matmul/matmul.normalopt.exe | Bin 0 -> 8644 bytes .../experiments/matmul/matmul.normalopt.ll | Bin 0 -> 1744 bytes .../www/experiments/matmul/matmul.normalopt.s | 203 + ...polly.interchanged+tiled+vector+openmp.exe | Bin 0 -> 13208 bytes ....polly.interchanged+tiled+vector+openmp.ll | Bin 0 -> 4784 bytes ...l.polly.interchanged+tiled+vector+openmp.s | 628 + ...matmul.polly.interchanged+tiled+vector.exe | Bin 0 -> 8718 bytes .../matmul.polly.interchanged+tiled+vector.ll | Bin 0 -> 2820 bytes .../matmul.polly.interchanged+tiled+vector.s | 318 + .../matmul.polly.interchanged+tiled.exe | Bin 0 -> 8711 bytes .../matmul/matmul.polly.interchanged+tiled.ll | Bin 0 -> 2748 bytes .../matmul/matmul.polly.interchanged+tiled.s | 323 + .../matmul/matmul.polly.interchanged.exe | Bin 0 -> 8705 bytes .../matmul/matmul.polly.interchanged.ll | Bin 0 -> 2308 bytes .../matmul/matmul.polly.interchanged.s | 217 + .../www/experiments/matmul/matmul.preopt.ll | 180 + tools/polly/www/experiments/matmul/matmul.s | 255 + tools/polly/www/experiments/matmul/runall.sh | 94 + .../experiments/matmul/scops.init_array.dot | 47 + .../matmul/scops.init_array.dot.png | Bin 0 -> 144639 bytes .../www/experiments/matmul/scops.main.dot | 65 + .../www/experiments/matmul/scops.main.dot.png | Bin 0 -> 175453 bytes .../experiments/matmul/scops.print_array.dot | 60 + .../matmul/scops.print_array.dot.png | Bin 0 -> 181300 bytes .../matmul/scopsonly.init_array.dot | 47 + .../matmul/scopsonly.init_array.dot.png | Bin 0 -> 24332 bytes .../www/experiments/matmul/scopsonly.main.dot | 65 + .../experiments/matmul/scopsonly.main.dot.png | Bin 0 -> 35645 bytes .../matmul/scopsonly.print_array.dot | 60 + .../matmul/scopsonly.print_array.dot.png | Bin 0 -> 30645 bytes tools/polly/www/get_started.html | 180 + tools/polly/www/images/architecture.png | Bin 0 -> 30298 bytes tools/polly/www/images/iit-madras.png | Bin 0 -> 10864 bytes tools/polly/www/images/osu.png | Bin 0 -> 6673 bytes .../www/images/performance/parallel-large.png | Bin 0 -> 43113 bytes .../www/images/performance/parallel-small.png | Bin 0 -> 43404 bytes .../images/performance/sequential-large.png | Bin 0 -> 43852 bytes .../images/performance/sequential-small.png | Bin 0 -> 41102 bytes tools/polly/www/images/sys-uni.png | Bin 0 -> 7919 bytes tools/polly/www/images/uni-passau.png | Bin 0 -> 6780 bytes tools/polly/www/images/video-summit-2011.png | Bin 0 -> 46922 bytes tools/polly/www/index.html | 243 + tools/polly/www/menu.css | 40 + tools/polly/www/menu.html.incl | 31 + tools/polly/www/performance.html | 66 + tools/polly/www/phonecall.html | 46 + tools/polly/www/polly.sh | 50 + tools/polly/www/publications.html | 141 + .../publications/grosser-diploma-thesis.pdf | Bin 0 -> 886366 bytes .../grosser-impact-2011-slides.pdf | Bin 0 -> 734304 bytes .../www/publications/grosser-impact-2011.pdf | Bin 0 -> 323334 bytes .../publications/raghesh-a-masters-thesis.pdf | Bin 0 -> 509037 bytes tools/polly/www/todo.html | 383 + tools/polly/www/video-js/video-js.css | 242 + tools/polly/www/video-js/video.js | 1758 + 1302 files changed, 390248 insertions(+) create mode 100644 tools/polly/CMakeLists.txt create mode 100644 tools/polly/CREDITS.txt create mode 100644 tools/polly/LICENSE.txt create mode 100644 tools/polly/Makefile create mode 100755 tools/polly/Makefile.common.in create mode 100755 tools/polly/Makefile.config.in create mode 100644 tools/polly/README create mode 100755 tools/polly/autoconf/AutoRegen.sh create mode 100644 tools/polly/autoconf/LICENSE.TXT create mode 100644 tools/polly/autoconf/aclocal.m4 create mode 100644 tools/polly/autoconf/config.guess create mode 100644 tools/polly/autoconf/config.sub create mode 100644 tools/polly/autoconf/configure.ac create mode 100644 tools/polly/autoconf/configure.bak create mode 100755 tools/polly/autoconf/m4/find_lib_and_headers.m4 create mode 100644 tools/polly/cmake/FindCloog.cmake create mode 100644 tools/polly/cmake/FindGmp.cmake create mode 100644 tools/polly/cmake/FindIsl.cmake create mode 100644 tools/polly/cmake/FindOpenScop.cmake create mode 100644 tools/polly/cmake/FindSCoPLib.cmake create mode 100755 tools/polly/configure create mode 100644 tools/polly/docs/index.html create mode 100644 tools/polly/docs/polly.png create mode 100644 tools/polly/docs/polly.svg create mode 100644 tools/polly/include/CMakeLists.txt create mode 100644 tools/polly/include/polly/CMakeLists.txt create mode 100644 tools/polly/include/polly/Cloog.h create mode 100644 tools/polly/include/polly/CodeGeneration.h create mode 100755 tools/polly/include/polly/Config/config.h.cmake create mode 100644 tools/polly/include/polly/Config/config.h.in create mode 100755 tools/polly/include/polly/Dependences.h create mode 100644 tools/polly/include/polly/LinkAllPasses.h create mode 100755 tools/polly/include/polly/MayAliasSet.h create mode 100644 tools/polly/include/polly/RegisterPasses.h create mode 100644 tools/polly/include/polly/ScheduleOptimizer.h create mode 100755 tools/polly/include/polly/ScopDetection.h create mode 100755 tools/polly/include/polly/ScopInfo.h create mode 100644 tools/polly/include/polly/ScopLib.h create mode 100755 tools/polly/include/polly/ScopPass.h create mode 100755 tools/polly/include/polly/Support/GICHelper.h create mode 100755 tools/polly/include/polly/Support/SCEVValidator.h create mode 100755 tools/polly/include/polly/Support/ScopHelper.h create mode 100755 tools/polly/include/polly/TempScopInfo.h create mode 100644 tools/polly/lib/Analysis/CMakeLists.txt create mode 100644 tools/polly/lib/Analysis/Dependences.cpp create mode 100755 tools/polly/lib/Analysis/Makefile create mode 100644 tools/polly/lib/Analysis/ScopDetection.cpp create mode 100644 tools/polly/lib/Analysis/ScopGraphPrinter.cpp create mode 100644 tools/polly/lib/Analysis/ScopInfo.cpp create mode 100755 tools/polly/lib/Analysis/ScopPass.cpp create mode 100644 tools/polly/lib/Analysis/TempScopInfo.cpp create mode 100755 tools/polly/lib/CMakeLists.txt create mode 100644 tools/polly/lib/Cloog.cpp create mode 100644 tools/polly/lib/CodeGeneration.cpp create mode 100644 tools/polly/lib/CodePreparation.cpp create mode 100644 tools/polly/lib/DeadCodeElimination.cpp create mode 100644 tools/polly/lib/Exchange/CMakeLists.txt create mode 100755 tools/polly/lib/Exchange/JSONExporter.cpp create mode 100755 tools/polly/lib/Exchange/Makefile create mode 100755 tools/polly/lib/Exchange/OpenScopExporter.cpp create mode 100755 tools/polly/lib/Exchange/OpenScopImporter.cpp create mode 100644 tools/polly/lib/Exchange/ScopLib.cpp create mode 100755 tools/polly/lib/Exchange/ScopLibExporter.cpp create mode 100755 tools/polly/lib/Exchange/ScopLibImporter.cpp create mode 100644 tools/polly/lib/IndependentBlocks.cpp create mode 100755 tools/polly/lib/JSON/CMakeLists.txt create mode 100644 tools/polly/lib/JSON/LICENSE.txt create mode 100755 tools/polly/lib/JSON/Makefile create mode 100644 tools/polly/lib/JSON/include/json/autolink.h create mode 100644 tools/polly/lib/JSON/include/json/config.h create mode 100644 tools/polly/lib/JSON/include/json/features.h create mode 100644 tools/polly/lib/JSON/include/json/forwards.h create mode 100644 tools/polly/lib/JSON/include/json/json.h create mode 100644 tools/polly/lib/JSON/include/json/reader.h create mode 100644 tools/polly/lib/JSON/include/json/value.h create mode 100644 tools/polly/lib/JSON/include/json/writer.h create mode 100644 tools/polly/lib/JSON/json_batchallocator.h create mode 100644 tools/polly/lib/JSON/json_internalarray.inl create mode 100644 tools/polly/lib/JSON/json_internalmap.inl create mode 100644 tools/polly/lib/JSON/json_reader.cpp create mode 100644 tools/polly/lib/JSON/json_value.cpp create mode 100644 tools/polly/lib/JSON/json_valueiterator.inl create mode 100644 tools/polly/lib/JSON/json_writer.cpp create mode 100644 tools/polly/lib/JSON/sconscript create mode 100755 tools/polly/lib/Makefile create mode 100755 tools/polly/lib/MayAliasSet.cpp create mode 100644 tools/polly/lib/Pocc.cpp create mode 100644 tools/polly/lib/RegionSimplify.cpp create mode 100644 tools/polly/lib/RegisterPasses.cpp create mode 100644 tools/polly/lib/ScheduleOptimizer.cpp create mode 100755 tools/polly/lib/Support/CMakeLists.txt create mode 100644 tools/polly/lib/Support/GICHelper.cpp create mode 100755 tools/polly/lib/Support/Makefile create mode 100644 tools/polly/lib/Support/SCEVValidator.cpp create mode 100644 tools/polly/lib/Support/ScopHelper.cpp create mode 100644 tools/polly/svn.log create mode 100644 tools/polly/test/CMakeLists.txt create mode 100644 tools/polly/test/Cloog/ambigous_schedule.ll create mode 100644 tools/polly/test/Cloog/ambigous_schedule___%for.cond---%for.end30.jscop create mode 100644 tools/polly/test/CodeGen/20100617.ll create mode 100644 tools/polly/test/CodeGen/20100622.ll create mode 100644 tools/polly/test/CodeGen/20100707.ll create mode 100644 tools/polly/test/CodeGen/20100707_2.ll create mode 100644 tools/polly/test/CodeGen/20100708.ll create mode 100644 tools/polly/test/CodeGen/20100708_2.ll create mode 100644 tools/polly/test/CodeGen/20100713.ll create mode 100644 tools/polly/test/CodeGen/20100713_2.ll create mode 100644 tools/polly/test/CodeGen/20100717.ll create mode 100644 tools/polly/test/CodeGen/20100718-DomInfo-2.ll create mode 100644 tools/polly/test/CodeGen/20100718-DomInfo.ll create mode 100644 tools/polly/test/CodeGen/20100720-MultipleConditions.c create mode 100644 tools/polly/test/CodeGen/20100720-MultipleConditions.ll create mode 100644 tools/polly/test/CodeGen/20100809-IndependentBlock.ll create mode 100644 tools/polly/test/CodeGen/20100811-ScalarDependencyBetweenBrAndCnd.ll create mode 100644 tools/polly/test/CodeGen/20101030-Overflow.ll create mode 100644 tools/polly/test/CodeGen/20101103-Overflow3.ll create mode 100644 tools/polly/test/CodeGen/20101103-signmissmatch.ll create mode 100644 tools/polly/test/CodeGen/20110226-Ignore-Dead-Code.ll create mode 100644 tools/polly/test/CodeGen/20110226-PHI-Node-removed.ll create mode 100644 tools/polly/test/CodeGen/20110312-Fail-without-basicaa.ll create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_constant_offset.c create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_constant_offset.ll create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_constant_offset___%for.cond---%for.end.jscop create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_constant_offset___%for.cond---%for.end.jscop.transformed create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_simple.c create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_simple.ll create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_simple___%for.cond---%for.end.jscop create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_codegen_simple___%for.cond---%for.end.jscop.transformed create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_simple.c create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_simple.ll create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_simple___%for.cond---%for.end.jscop create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_simple___%for.cond---%for.end.jscop.transformed create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_simple___%for.cond4---%for.end14.jscop create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_simple___%for.cond4---%for.end14.jscop.transformed create mode 100644 tools/polly/test/CodeGen/MemAccess/memaccess_simple_analyze.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/add_memref.c create mode 100644 tools/polly/test/CodeGen/OpenMP/add_memref.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/extract_memref.c create mode 100644 tools/polly/test/CodeGen/OpenMP/extract_memref.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/invalidate_subfn_scops.c create mode 100644 tools/polly/test/CodeGen/OpenMP/invalidate_subfn_scops.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop.c create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop.tiled create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop_simple.c create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop_simple.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop_simple2.c create mode 100644 tools/polly/test/CodeGen/OpenMP/parallel_loop_simple2.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/simple_nested_loop.c create mode 100644 tools/polly/test/CodeGen/OpenMP/simple_nested_loop.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/structnames.c create mode 100644 tools/polly/test/CodeGen/OpenMP/structnames.ll create mode 100644 tools/polly/test/CodeGen/OpenMP/two_loop.c create mode 100644 tools/polly/test/CodeGen/OpenMP/two_loop.ll create mode 100644 tools/polly/test/CodeGen/PHIInExit.ll create mode 100644 tools/polly/test/CodeGen/constant_condition.c create mode 100644 tools/polly/test/CodeGen/constant_condition.ll create mode 100644 tools/polly/test/CodeGen/do_pluto_matmult.c create mode 100644 tools/polly/test/CodeGen/do_pluto_matmult.ll create mode 100644 tools/polly/test/CodeGen/do_pluto_matmult.ll.result create mode 100644 tools/polly/test/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop create mode 100644 tools/polly/test/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.invalid_reverse create mode 100644 tools/polly/test/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.valid_reverse create mode 100644 tools/polly/test/CodeGen/loop_with_condition.c create mode 100644 tools/polly/test/CodeGen/loop_with_condition.ll create mode 100644 tools/polly/test/CodeGen/loop_with_condition_2.ll create mode 100644 tools/polly/test/CodeGen/loop_with_condition_ineq.c create mode 100644 tools/polly/test/CodeGen/loop_with_condition_ineq.ll create mode 100644 tools/polly/test/CodeGen/loop_with_condition_nested.c create mode 100644 tools/polly/test/CodeGen/loop_with_condition_nested.ll create mode 100644 tools/polly/test/CodeGen/matmul_vec.c create mode 100644 tools/polly/test/CodeGen/matmul_vec.ll create mode 100644 tools/polly/test/CodeGen/matmul_vec___%1---%17.jscop create mode 100644 tools/polly/test/CodeGen/pluto_matmult.c create mode 100644 tools/polly/test/CodeGen/pluto_matmult.ll create mode 100644 tools/polly/test/CodeGen/pluto_matmult___%for.cond---%for.end47.jscop create mode 100644 tools/polly/test/CodeGen/reduction.c create mode 100644 tools/polly/test/CodeGen/reduction.ll create mode 100644 tools/polly/test/CodeGen/reduction_2.c create mode 100644 tools/polly/test/CodeGen/reduction_2.ll create mode 100644 tools/polly/test/CodeGen/scev.ll create mode 100644 tools/polly/test/CodeGen/sequential_loops.c create mode 100644 tools/polly/test/CodeGen/sequential_loops.ll create mode 100644 tools/polly/test/CodeGen/simple_nonaffine_loop.c create mode 100644 tools/polly/test/CodeGen/simple_nonaffine_loop.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_assign_scalar.c create mode 100644 tools/polly/test/CodeGen/simple_vec_assign_scalar.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_assign_scalar_2.c create mode 100644 tools/polly/test/CodeGen/simple_vec_assign_scalar_2.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_cast.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_const.c create mode 100644 tools/polly/test/CodeGen/simple_vec_const.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_large_width.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_stride_one.c create mode 100644 tools/polly/test/CodeGen/simple_vec_stride_one.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_stride_one___%1---%5.jscop create mode 100644 tools/polly/test/CodeGen/simple_vec_stride_x.c create mode 100644 tools/polly/test/CodeGen/simple_vec_stride_x.ll create mode 100644 tools/polly/test/CodeGen/simple_vec_two_stmts.ll create mode 100644 tools/polly/test/CodeGen/single_do_loop_int_max_iterations.c create mode 100644 tools/polly/test/CodeGen/single_do_loop_int_max_iterations.ll create mode 100644 tools/polly/test/CodeGen/single_do_loop_int_max_iterations___%do.body---%do.end.jscop create mode 100644 tools/polly/test/CodeGen/single_do_loop_int_param_iterations.c create mode 100644 tools/polly/test/CodeGen/single_do_loop_int_param_iterations.ll create mode 100644 tools/polly/test/CodeGen/single_do_loop_ll_max_iterations.c create mode 100644 tools/polly/test/CodeGen/single_do_loop_ll_max_iterations.ll create mode 100644 tools/polly/test/CodeGen/single_do_loop_one_iteration.c create mode 100644 tools/polly/test/CodeGen/single_do_loop_one_iteration.ll create mode 100644 tools/polly/test/CodeGen/single_do_loop_scev_replace.c create mode 100644 tools/polly/test/CodeGen/single_do_loop_scev_replace.ll create mode 100644 tools/polly/test/CodeGen/single_loop.c create mode 100644 tools/polly/test/CodeGen/single_loop.ll create mode 100644 tools/polly/test/CodeGen/single_loop_int_max_iterations.c create mode 100644 tools/polly/test/CodeGen/single_loop_int_max_iterations.ll create mode 100644 tools/polly/test/CodeGen/single_loop_ll_max_iterations.c create mode 100644 tools/polly/test/CodeGen/single_loop_ll_max_iterations.ll create mode 100644 tools/polly/test/CodeGen/single_loop_one_iteration.c create mode 100644 tools/polly/test/CodeGen/single_loop_one_iteration.ll create mode 100644 tools/polly/test/CodeGen/single_loop_param.ll create mode 100644 tools/polly/test/CodeGen/single_loop_uint_max_iterations.c create mode 100644 tools/polly/test/CodeGen/single_loop_uint_max_iterations.ll create mode 100644 tools/polly/test/CodeGen/single_loop_ull_max_iterations.c create mode 100644 tools/polly/test/CodeGen/single_loop_ull_max_iterations.ll create mode 100644 tools/polly/test/CodeGen/single_loop_zero_iterations.c create mode 100644 tools/polly/test/CodeGen/single_loop_zero_iterations.ll create mode 100644 tools/polly/test/CodeGen/split_edges.ll create mode 100644 tools/polly/test/CodeGen/split_edges_2.ll create mode 100644 tools/polly/test/CodeGen/test.c create mode 100644 tools/polly/test/CodeGen/test.ll create mode 100755 tools/polly/test/Makefile create mode 100644 tools/polly/test/README create mode 100644 tools/polly/test/ScheduleOptimizer/2011-08-25-crash_in_vectorizer.ll create mode 100644 tools/polly/test/ScopDetection/single_function_only.ll create mode 100644 tools/polly/test/ScopInfo/20111108-Parameter-not-detected.ll create mode 100755 tools/polly/test/ScopInfo/Alias-0.ll create mode 100755 tools/polly/test/ScopInfo/Alias-1.ll create mode 100755 tools/polly/test/ScopInfo/Alias-2.ll create mode 100755 tools/polly/test/ScopInfo/Alias-3.ll create mode 100755 tools/polly/test/ScopInfo/Alias-4.ll create mode 100644 tools/polly/test/ScopInfo/bad_loop_0.ll create mode 100755 tools/polly/test/ScopInfo/bug_2010_10_22.ll create mode 100755 tools/polly/test/ScopInfo/bug_2011_1_5.ll create mode 100644 tools/polly/test/ScopInfo/bug_scev_not_fully_eval.ll create mode 100644 tools/polly/test/ScopInfo/cond_in_loop.ll create mode 100644 tools/polly/test/ScopInfo/indvar_out_of_loop.ll create mode 100644 tools/polly/test/ScopInfo/indvar_out_of_loop_1.ll create mode 100644 tools/polly/test/ScopInfo/indvar_out_of_loop_2.ll create mode 100644 tools/polly/test/ScopInfo/loop_affine_bound_0.ll create mode 100644 tools/polly/test/ScopInfo/loop_affine_bound_1.ll create mode 100644 tools/polly/test/ScopInfo/loop_affine_bound_2.ll create mode 100644 tools/polly/test/ScopInfo/loop_carry.ll create mode 100644 tools/polly/test/ScopInfo/loop_complex_parameter.ll create mode 100644 tools/polly/test/ScopInfo/loop_depth_0.ll create mode 100644 tools/polly/test/ScopInfo/loop_multi_exits.ll create mode 100644 tools/polly/test/ScopInfo/out_of_loop_0.ll create mode 100755 tools/polly/test/ScopInfo/phi_not_grouped_at_top.ll create mode 100755 tools/polly/test/ScopInfo/phi_with_invoke_edge.ll create mode 100644 tools/polly/test/ScopInfo/simple_loop_1.ll create mode 100644 tools/polly/test/ScopInfo/simple_nonaffine_loop.ll create mode 100644 tools/polly/test/ScopInfo/simple_nonaffine_loop_not.ll create mode 100644 tools/polly/test/ScopInfo/undef_in_cond.ll create mode 100644 tools/polly/test/TempScop/not-a-reduction.c create mode 100644 tools/polly/test/TempScop/not-a-reduction.ll create mode 100755 tools/polly/test/create_ll.sh create mode 100644 tools/polly/test/lit.cfg create mode 100644 tools/polly/test/lit.site.cfg.in create mode 100644 tools/polly/test/polly.ll create mode 100755 tools/polly/test/polybench/README create mode 100755 tools/polly/test/polybench/datamining/correlation/correlation.c create mode 100644 tools/polly/test/polybench/datamining/correlation/correlation_with_param.ll create mode 100644 tools/polly/test/polybench/datamining/correlation/correlation_without_param.ll create mode 100755 tools/polly/test/polybench/datamining/covariance/covariance.c create mode 100644 tools/polly/test/polybench/datamining/covariance/covariance_with_param.ll create mode 100644 tools/polly/test/polybench/datamining/covariance/covariance_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/2mm/2mm.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/2mm/2mm_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/2mm/2mm_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/2mm/compiler.opts create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/3mm/3mm.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/3mm/3mm_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/3mm/3mm_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/3mm/compiler.opts create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/atax/atax.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/atax/atax_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/atax/atax_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/bicg/bicg.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/bicg/bicg_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/bicg/bicg_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/doitgen/doitgen.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/doitgen/doitgen_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/doitgen/doitgen_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/gemm/compiler.opts create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/gemm/gemm.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/gemm/gemm_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/gemm/gemm_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/gemver/gemver.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/gemver/gemver_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/gemver/gemver_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/kernels/gesummv/gesummv.c create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/gesummv/gesummv_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/kernels/gesummv/gesummv_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/solvers/gramschmidt/gramschmidt.c create mode 100644 tools/polly/test/polybench/linear-algebra/solvers/gramschmidt/gramschmidt_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/solvers/gramschmidt/gramschmidt_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/solvers/lu/lu.c create mode 100644 tools/polly/test/polybench/linear-algebra/solvers/lu/lu_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/solvers/lu/lu_without_param.ll create mode 100755 tools/polly/test/polybench/linear-algebra/solvers/ludcmp/ludcmp.c create mode 100644 tools/polly/test/polybench/linear-algebra/solvers/ludcmp/ludcmp_with_param.ll create mode 100644 tools/polly/test/polybench/linear-algebra/solvers/ludcmp/ludcmp_without_param.ll create mode 100755 tools/polly/test/polybench/scripts/compile.sh create mode 100755 tools/polly/test/polybench/scripts/runall.sh create mode 100755 tools/polly/test/polybench/stencils/adi/adi.c create mode 100644 tools/polly/test/polybench/stencils/adi/adi_with_param.ll create mode 100644 tools/polly/test/polybench/stencils/adi/adi_without_param.ll create mode 100755 tools/polly/test/polybench/stencils/jacobi-2d-imper/jacobi-2d-imper.c create mode 100644 tools/polly/test/polybench/stencils/jacobi-2d-imper/jacobi-2d-imper_with_param.ll create mode 100644 tools/polly/test/polybench/stencils/jacobi-2d-imper/jacobi-2d-imper_without_param.ll create mode 100755 tools/polly/test/polybench/stencils/seidel/seidel.c create mode 100644 tools/polly/test/polybench/stencils/seidel/seidel_with_param.ll create mode 100644 tools/polly/test/polybench/stencils/seidel/seidel_without_param.ll create mode 100755 tools/polly/test/polybench/utilities/instrument.c create mode 100755 tools/polly/test/polybench/utilities/instrument.h create mode 100755 tools/polly/test/polybench/utilities/template-for-new-benchmark.c create mode 100644 tools/polly/tools/CMakeLists.txt create mode 100644 tools/polly/tools/Makefile create mode 100644 tools/polly/utils/argparse.py create mode 100755 tools/polly/utils/checkout_cloog.sh create mode 100644 tools/polly/utils/cloog_src/ChangeLog create mode 100644 tools/polly/utils/cloog_src/LICENSE create mode 100644 tools/polly/utils/cloog_src/Makefile.am create mode 100644 tools/polly/utils/cloog_src/Makefile.in create mode 100644 tools/polly/utils/cloog_src/README create mode 100644 tools/polly/utils/cloog_src/aclocal.m4 create mode 100644 tools/polly/utils/cloog_src/autoconf/Doxyfile.in create mode 100644 tools/polly/utils/cloog_src/autoconf/c-ced.ssh create mode 100755 tools/polly/utils/cloog_src/autoconf/config.guess create mode 100755 tools/polly/utils/cloog_src/autoconf/config.sub create mode 100755 tools/polly/utils/cloog_src/autoconf/depcomp create mode 100755 tools/polly/utils/cloog_src/autoconf/install-sh create mode 100755 tools/polly/utils/cloog_src/autoconf/ltmain.sh create mode 100755 tools/polly/utils/cloog_src/autoconf/missing create mode 100755 tools/polly/utils/cloog_src/autogen.sh create mode 100755 tools/polly/utils/cloog_src/configure create mode 100644 tools/polly/utils/cloog_src/configure.ac create mode 100644 tools/polly/utils/cloog_src/doc/Makefile.am create mode 100644 tools/polly/utils/cloog_src/doc/Makefile.in create mode 100644 tools/polly/utils/cloog_src/doc/ROADMAP create mode 100644 tools/polly/utils/cloog_src/doc/SubmittingPatches create mode 100644 tools/polly/utils/cloog_src/doc/TODO create mode 100644 tools/polly/utils/cloog_src/doc/cloog.texi create mode 100644 tools/polly/utils/cloog_src/doc/images/basic.eps create mode 100644 tools/polly/utils/cloog_src/doc/images/basic.fig create mode 100644 tools/polly/utils/cloog_src/doc/images/basic.jpg create mode 100644 tools/polly/utils/cloog_src/doc/images/basic.pdf create mode 100644 tools/polly/utils/cloog_src/doc/images/basic.txt create mode 100644 tools/polly/utils/cloog_src/doc/images/tree.eps create mode 100644 tools/polly/utils/cloog_src/doc/images/tree.fig create mode 100644 tools/polly/utils/cloog_src/doc/images/tree.jpg create mode 100644 tools/polly/utils/cloog_src/doc/images/tree.pdf create mode 100644 tools/polly/utils/cloog_src/doc/images/tree.txt create mode 100644 tools/polly/utils/cloog_src/examples/README create mode 100644 tools/polly/utils/cloog_src/examples/example/Makefile create mode 100644 tools/polly/utils/cloog_src/examples/example/example.c create mode 100755 tools/polly/utils/cloog_src/genversion.sh.in create mode 100755 tools/polly/utils/cloog_src/get_submodules.sh create mode 100644 tools/polly/utils/cloog_src/include/cloog/block.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/clast.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/cloog.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/constraints.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/domain.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/input.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/int.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/isl/backend.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/isl/cloog.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/isl/constraintset.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/isl/domain.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/loop.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/matrix.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/matrix/constraintset.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/names.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/options.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/pprint.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/program.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/state.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/statement.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/stride.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/union_domain.h create mode 100644 tools/polly/utils/cloog_src/include/cloog/version.h.in create mode 100644 tools/polly/utils/cloog_src/isl/AUTHORS create mode 100644 tools/polly/utils/cloog_src/isl/ChangeLog create mode 100644 tools/polly/utils/cloog_src/isl/LICENSE create mode 100644 tools/polly/utils/cloog_src/isl/Makefile.am create mode 100644 tools/polly/utils/cloog_src/isl/Makefile.in create mode 100644 tools/polly/utils/cloog_src/isl/aclocal.m4 create mode 100755 tools/polly/utils/cloog_src/isl/autogen.sh create mode 100644 tools/polly/utils/cloog_src/isl/basis_reduction_tab.c create mode 100644 tools/polly/utils/cloog_src/isl/basis_reduction_templ.c create mode 100644 tools/polly/utils/cloog_src/isl/bound.c create mode 100755 tools/polly/utils/cloog_src/isl/bound_test.sh.in create mode 100644 tools/polly/utils/cloog_src/isl/cat.c create mode 100644 tools/polly/utils/cloog_src/isl/closure.c create mode 100755 tools/polly/utils/cloog_src/isl/config.guess create mode 100755 tools/polly/utils/cloog_src/isl/config.sub create mode 100755 tools/polly/utils/cloog_src/isl/configure create mode 100644 tools/polly/utils/cloog_src/isl/configure.ac create mode 100755 tools/polly/utils/cloog_src/isl/depcomp create mode 100644 tools/polly/utils/cloog_src/isl/doc/Makefile.am create mode 100644 tools/polly/utils/cloog_src/isl/doc/Makefile.in create mode 100644 tools/polly/utils/cloog_src/isl/doc/SubmittingPatches create mode 100644 tools/polly/utils/cloog_src/isl/doc/chicago.bst create mode 100644 tools/polly/utils/cloog_src/isl/doc/chicago.sty create mode 100644 tools/polly/utils/cloog_src/isl/doc/implementation.tex create mode 100644 tools/polly/utils/cloog_src/isl/doc/isl.bib create mode 100644 tools/polly/utils/cloog_src/isl/doc/manual.tex create mode 100755 tools/polly/utils/cloog_src/isl/doc/mypod2latex create mode 100644 tools/polly/utils/cloog_src/isl/doc/user.pod create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/aff.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/aff_type.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/arg.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/band.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/blk.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/config.h.in create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/constraint.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/ctx.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/dim.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/flow.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/hash.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/id.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/ilp.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/int.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/list.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/local_space.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/lp.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/map.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/map_type.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/mat.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/multi.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/obj.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/options.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/point.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/polynomial.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/polynomial_type.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/printer.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/schedule.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/seq.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/set.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/set_type.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/space.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/stream.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/union_map.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/union_set.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/vec.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/version.h create mode 100644 tools/polly/utils/cloog_src/isl/include/isl/vertices.h create mode 100755 tools/polly/utils/cloog_src/isl/install-sh create mode 100644 tools/polly/utils/cloog_src/isl/interface/Makefile.am create mode 100644 tools/polly/utils/cloog_src/isl/interface/Makefile.in create mode 100644 tools/polly/utils/cloog_src/isl/interface/all.h create mode 100644 tools/polly/utils/cloog_src/isl/interface/extract_interface.cc create mode 100644 tools/polly/utils/cloog_src/isl/interface/extract_interface.h create mode 100644 tools/polly/utils/cloog_src/isl/interface/isl.py.top create mode 100644 tools/polly/utils/cloog_src/isl/interface/python.cc create mode 100644 tools/polly/utils/cloog_src/isl/interface/python.h create mode 100644 tools/polly/utils/cloog_src/isl/isl.py create mode 100644 tools/polly/utils/cloog_src/isl/isl_aff.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_aff_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_affine_hull.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_arg.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_band.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_band_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_basis_reduction.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_bernstein.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_bernstein.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_blk.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_bound.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_bound.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_coalesce.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_config.h.in create mode 100644 tools/polly/utils/cloog_src/isl/isl_config_post.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_constraint.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_constraint_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_convex_hull.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_ctx.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_ctx_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_dim.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_dim_map.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_dim_map.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_equalities.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_equalities.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_factorization.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_factorization.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_farkas.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_flow.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_fold.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_gmp.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_hash.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_hmap_map_basic_set.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_hmap_map_basic_set.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_id.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_id_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_ilp.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_input.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_list.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_list_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_list_templ.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_list_templ.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_local_space.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_local_space_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_lp.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_lp_no_piplib.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_lp_piplib.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_lp_piplib.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_map.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_map_no_piplib.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_map_piplib.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_map_piplib.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_map_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_map_simplify.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_map_subtract.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_mat.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_mat_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_morph.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_morph.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_multi_templ.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_multi_templ.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_obj.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_options.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_options_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_output.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_piplib.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_piplib.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_point.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_point_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_polynomial.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_polynomial_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_printer.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_printer_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_pw_templ.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_qsort.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_qsort.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_range.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_range.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_reordering.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_reordering.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_sample.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_sample.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_sample_no_piplib.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_sample_piplib.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_sample_piplib.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_scan.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_scan.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_schedule.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_schedule_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_seq.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_space.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_space_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_stream.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_stream_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_tab.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_tab.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_tab_pip.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_test.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_transitive_closure.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_union_map.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_union_map_private.h create mode 100644 tools/polly/utils/cloog_src/isl/isl_union_templ.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_vec.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_version.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_vertices.c create mode 100644 tools/polly/utils/cloog_src/isl/isl_vertices_private.h create mode 100755 tools/polly/utils/cloog_src/isl/ltmain.sh create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_c___attribute__.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_cc_maxopt.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_cflags_warn_all.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_check_compiler_flags.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_compiler_vendor.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_create_pkgconfig_info.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_create_stdint_h.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_detect_git_head.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_gcc_archflag.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_gcc_warn_unused_result.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_gcc_x86_cpuid.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_set_warning_flags.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ax_submodule.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/libtool.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ltoptions.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ltsugar.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/ltversion.m4 create mode 100644 tools/polly/utils/cloog_src/isl/m4/lt~obsolete.m4 create mode 100755 tools/polly/utils/cloog_src/isl/missing create mode 100644 tools/polly/utils/cloog_src/isl/mp_get_memory_functions.c create mode 100644 tools/polly/utils/cloog_src/isl/pip.c create mode 100755 tools/polly/utils/cloog_src/isl/pip_test.sh.in create mode 100644 tools/polly/utils/cloog_src/isl/polyhedron_detect_equalities.c create mode 100644 tools/polly/utils/cloog_src/isl/polyhedron_minimize.c create mode 100644 tools/polly/utils/cloog_src/isl/polyhedron_sample.c create mode 100644 tools/polly/utils/cloog_src/isl/polytope_scan.c create mode 100644 tools/polly/utils/cloog_src/isl/print.c create mode 100644 tools/polly/utils/cloog_src/isl/print_templ.c create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/affine.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/affine2.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/affine3.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/application.omega create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/application2.omega create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/basicLinear.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/basicLinear2.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/basicTest.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/basicTestParameterPosNeg.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/boulet.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/brisebarre.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/cg1.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex0.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex1.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex10.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex11.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex12.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex13.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex14.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex15.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex2.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex3.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex4.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex5.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex6.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex7.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex8.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/convex9.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/devos.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/equality1.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/equality2.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/equality3.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/equality4.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/equality5.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/esced.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/ex.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/ex2.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/faddeev.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/fimmel.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/gist1.polylib create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/linearExample.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/max.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/neg.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/negative.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/philippe.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/philippe3vars.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/philippe3vars3pars.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/philippeNeg.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/philippePolynomialCoeff.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/philippePolynomialCoeff1P.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/product.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/seghir-vd.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/set.omega create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/small.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/sor1d.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/split.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/square.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/sven.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/test3Deg3Var.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/tobi.pip create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/toplas.pwqp create mode 100644 tools/polly/utils/cloog_src/isl/test_inputs/unexpanded.pwqp create mode 100644 tools/polly/utils/cloog_src/m4/ax_cc_maxopt.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ax_cflags_warn_all.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ax_check_compiler_flags.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ax_compiler_vendor.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ax_create_pkgconfig_info.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ax_gcc_archflag.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ax_gcc_x86_cpuid.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ax_submodule.m4 create mode 100644 tools/polly/utils/cloog_src/m4/libtool.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ltoptions.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ltsugar.m4 create mode 100644 tools/polly/utils/cloog_src/m4/ltversion.m4 create mode 100644 tools/polly/utils/cloog_src/m4/lt~obsolete.m4 create mode 100644 tools/polly/utils/cloog_src/source/block.c create mode 100644 tools/polly/utils/cloog_src/source/clast.c create mode 100644 tools/polly/utils/cloog_src/source/cloog.c create mode 100644 tools/polly/utils/cloog_src/source/input.c create mode 100644 tools/polly/utils/cloog_src/source/int.c create mode 100644 tools/polly/utils/cloog_src/source/isl/backend.c create mode 100644 tools/polly/utils/cloog_src/source/isl/constraints.c create mode 100644 tools/polly/utils/cloog_src/source/isl/domain.c create mode 100644 tools/polly/utils/cloog_src/source/loop.c create mode 100644 tools/polly/utils/cloog_src/source/matrix.c create mode 100644 tools/polly/utils/cloog_src/source/matrix/constraintset.c create mode 100644 tools/polly/utils/cloog_src/source/mp_get_memory_functions.c create mode 100644 tools/polly/utils/cloog_src/source/names.c create mode 100644 tools/polly/utils/cloog_src/source/options.c create mode 100644 tools/polly/utils/cloog_src/source/pprint.c create mode 100644 tools/polly/utils/cloog_src/source/program.c create mode 100644 tools/polly/utils/cloog_src/source/state.c create mode 100644 tools/polly/utils/cloog_src/source/statement.c create mode 100644 tools/polly/utils/cloog_src/source/stride.c create mode 100644 tools/polly/utils/cloog_src/source/union_domain.c create mode 100644 tools/polly/utils/cloog_src/source/version.c.in create mode 100644 tools/polly/utils/cloog_src/test/0D-1.c create mode 100644 tools/polly/utils/cloog_src/test/0D-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/0D-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/0D-2.c create mode 100644 tools/polly/utils/cloog_src/test/0D-2.cloog create mode 100644 tools/polly/utils/cloog_src/test/0D-2.good.c create mode 100644 tools/polly/utils/cloog_src/test/0D-3.c create mode 100644 tools/polly/utils/cloog_src/test/0D-3.cloog create mode 100644 tools/polly/utils/cloog_src/test/0D-3.good.c create mode 100644 tools/polly/utils/cloog_src/test/1point-1.c create mode 100644 tools/polly/utils/cloog_src/test/1point-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/1point-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/1point-2.c create mode 100644 tools/polly/utils/cloog_src/test/1point-2.cloog create mode 100644 tools/polly/utils/cloog_src/test/1point-2.good.c create mode 100644 tools/polly/utils/cloog_src/test/4-param.c create mode 100644 tools/polly/utils/cloog_src/test/4-param.cloog create mode 100644 tools/polly/utils/cloog_src/test/4-param.good.c create mode 100644 tools/polly/utils/cloog_src/test/Makefile.am create mode 100644 tools/polly/utils/cloog_src/test/Makefile.in create mode 100644 tools/polly/utils/cloog_src/test/ard.cloog create mode 100644 tools/polly/utils/cloog_src/test/ard.dat create mode 100644 tools/polly/utils/cloog_src/test/backtrack.c create mode 100644 tools/polly/utils/cloog_src/test/backtrack.cloog create mode 100644 tools/polly/utils/cloog_src/test/backtrack.good.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-1.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-2.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-2.cloog create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-2.good.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-3.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-3.cloog create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-3.good.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-4.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-4.cloog create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-4.good.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-5.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-5.cloog create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-5.good.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-6.c create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-6.cloog create mode 100644 tools/polly/utils/cloog_src/test/basic-bounds-6.good.c create mode 100644 tools/polly/utils/cloog_src/test/bigs/applu.N.w2p12 create mode 100644 tools/polly/utils/cloog_src/test/bigs/applu.N.w2p21 create mode 100644 tools/polly/utils/cloog_src/test/bigs/applu12.loopgen create mode 100644 tools/polly/utils/cloog_src/test/bigs/applu21.loopgen create mode 100644 tools/polly/utils/cloog_src/test/bigs/apsi.N.w2p82 create mode 100644 tools/polly/utils/cloog_src/test/bigs/apsi.N.w2p89 create mode 100644 tools/polly/utils/cloog_src/test/bigs/dyfesm.N.w2p20 create mode 100644 tools/polly/utils/cloog_src/test/bigs/lucas_distrib_spec.N.w2p1 create mode 100644 tools/polly/utils/cloog_src/test/bigs/lucas_distrib_spec.N.w2p10 create mode 100644 tools/polly/utils/cloog_src/test/bigs/mg3d.N.w2p26 create mode 100644 tools/polly/utils/cloog_src/test/bigs/qcd.N.w2p47 create mode 100644 tools/polly/utils/cloog_src/test/bigs/qcd.N.w2p49 create mode 100644 tools/polly/utils/cloog_src/test/bigs/qcd.N.w2p8 create mode 100644 tools/polly/utils/cloog_src/test/bigs/quake.N.w2p26 create mode 100644 tools/polly/utils/cloog_src/test/block.c create mode 100644 tools/polly/utils/cloog_src/test/block.cloog create mode 100644 tools/polly/utils/cloog_src/test/block.good.c create mode 100644 tools/polly/utils/cloog_src/test/block2.c create mode 100644 tools/polly/utils/cloog_src/test/block2.cloog create mode 100644 tools/polly/utils/cloog_src/test/block2.good.c create mode 100644 tools/polly/utils/cloog_src/test/block3.c create mode 100644 tools/polly/utils/cloog_src/test/block3.cloog create mode 100644 tools/polly/utils/cloog_src/test/block3.good.c create mode 100644 tools/polly/utils/cloog_src/test/byu98-1-2-3.c create mode 100644 tools/polly/utils/cloog_src/test/byu98-1-2-3.cloog create mode 100644 tools/polly/utils/cloog_src/test/byu98-1-2-3.good.c create mode 100644 tools/polly/utils/cloog_src/test/ceilfloor.cloog create mode 100644 tools/polly/utils/cloog_src/test/challenges/apsi.N.w2p56 create mode 100644 tools/polly/utils/cloog_src/test/challenges/challenge1.cloog create mode 100644 tools/polly/utils/cloog_src/test/challenges/lucas.N.w2p11 create mode 100644 tools/polly/utils/cloog_src/test/challenges/motionek1945.cloog create mode 100644 tools/polly/utils/cloog_src/test/challenges/test2.N.cloog create mode 100644 tools/polly/utils/cloog_src/test/challenges/test3.N.cloog create mode 100755 tools/polly/utils/cloog_src/test/check_c.sh create mode 100755 tools/polly/utils/cloog_src/test/check_fortran.sh create mode 100755 tools/polly/utils/cloog_src/test/check_openscop.sh create mode 100755 tools/polly/utils/cloog_src/test/check_run.sh create mode 100755 tools/polly/utils/cloog_src/test/check_special.sh create mode 100755 tools/polly/utils/cloog_src/test/check_strided.sh create mode 100755 tools/polly/utils/cloog_src/test/checker.sh create mode 100644 tools/polly/utils/cloog_src/test/cholesau_allocation.cloog create mode 100644 tools/polly/utils/cloog_src/test/cholesau_original.cloog create mode 100644 tools/polly/utils/cloog_src/test/cholesky.c create mode 100644 tools/polly/utils/cloog_src/test/cholesky.cloog create mode 100644 tools/polly/utils/cloog_src/test/cholesky.good.c create mode 100644 tools/polly/utils/cloog_src/test/cholesky2.c create mode 100644 tools/polly/utils/cloog_src/test/cholesky2.cloog create mode 100644 tools/polly/utils/cloog_src/test/cholesky2.good.c create mode 100644 tools/polly/utils/cloog_src/test/christian.c create mode 100644 tools/polly/utils/cloog_src/test/christian.cloog create mode 100644 tools/polly/utils/cloog_src/test/christian.good.c create mode 100644 tools/polly/utils/cloog_src/test/classen.c create mode 100644 tools/polly/utils/cloog_src/test/classen.cloog create mode 100644 tools/polly/utils/cloog_src/test/classen.good.c create mode 100644 tools/polly/utils/cloog_src/test/classen2.c create mode 100644 tools/polly/utils/cloog_src/test/classen2.cloog create mode 100644 tools/polly/utils/cloog_src/test/classen2.good.c create mode 100644 tools/polly/utils/cloog_src/test/constant.c create mode 100644 tools/polly/utils/cloog_src/test/constant.cloog create mode 100644 tools/polly/utils/cloog_src/test/constant.good.c create mode 100644 tools/polly/utils/cloog_src/test/constbound.c create mode 100644 tools/polly/utils/cloog_src/test/constbound.cloog create mode 100644 tools/polly/utils/cloog_src/test/constbound.good.c create mode 100644 tools/polly/utils/cloog_src/test/daegon_lu_osp.cloog create mode 100644 tools/polly/utils/cloog_src/test/darte.c create mode 100644 tools/polly/utils/cloog_src/test/darte.cloog create mode 100644 tools/polly/utils/cloog_src/test/darte.good.c create mode 100644 tools/polly/utils/cloog_src/test/dartef.c create mode 100644 tools/polly/utils/cloog_src/test/dartef.cloog create mode 100644 tools/polly/utils/cloog_src/test/dartef.f create mode 100644 tools/polly/utils/cloog_src/test/dealII.c create mode 100644 tools/polly/utils/cloog_src/test/dealII.cloog create mode 100644 tools/polly/utils/cloog_src/test/dealII.good.c create mode 100644 tools/polly/utils/cloog_src/test/diagonal.cloog create mode 100644 tools/polly/utils/cloog_src/test/donotsimp.c create mode 100644 tools/polly/utils/cloog_src/test/donotsimp.cloog create mode 100644 tools/polly/utils/cloog_src/test/donotsimp.good.c create mode 100644 tools/polly/utils/cloog_src/test/dot.c create mode 100644 tools/polly/utils/cloog_src/test/dot.cloog create mode 100644 tools/polly/utils/cloog_src/test/dot.good.c create mode 100644 tools/polly/utils/cloog_src/test/dot2.c create mode 100644 tools/polly/utils/cloog_src/test/dot2.cloog create mode 100644 tools/polly/utils/cloog_src/test/dot2.good.c create mode 100644 tools/polly/utils/cloog_src/test/double.c create mode 100644 tools/polly/utils/cloog_src/test/double.cloog create mode 100644 tools/polly/utils/cloog_src/test/double.good.c create mode 100644 tools/polly/utils/cloog_src/test/durbin_e_s.c create mode 100644 tools/polly/utils/cloog_src/test/durbin_e_s.cloog create mode 100644 tools/polly/utils/cloog_src/test/durbin_e_s.good.c create mode 100644 tools/polly/utils/cloog_src/test/elimination.cloog create mode 100644 tools/polly/utils/cloog_src/test/emploi.c create mode 100644 tools/polly/utils/cloog_src/test/emploi.cloog create mode 100644 tools/polly/utils/cloog_src/test/emploi.good.c create mode 100644 tools/polly/utils/cloog_src/test/equality.c create mode 100644 tools/polly/utils/cloog_src/test/equality.cloog create mode 100644 tools/polly/utils/cloog_src/test/equality.good.c create mode 100644 tools/polly/utils/cloog_src/test/equality2.c create mode 100644 tools/polly/utils/cloog_src/test/equality2.cloog create mode 100644 tools/polly/utils/cloog_src/test/equality2.good.c create mode 100644 tools/polly/utils/cloog_src/test/esced.c create mode 100644 tools/polly/utils/cloog_src/test/esced.cloog create mode 100644 tools/polly/utils/cloog_src/test/esced.good.c create mode 100644 tools/polly/utils/cloog_src/test/ex1.c create mode 100644 tools/polly/utils/cloog_src/test/ex1.cloog create mode 100644 tools/polly/utils/cloog_src/test/ex1.good.c create mode 100644 tools/polly/utils/cloog_src/test/faber.c create mode 100644 tools/polly/utils/cloog_src/test/faber.cloog create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-1-1-2.c create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-1-1-2.cloog create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-1-1-2.good.c create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-2-1-2-3.c create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-2-1-2-3.cloog create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-2-1-2-3.good.c create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-3-1-2.c create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-3-1-2.cloog create mode 100644 tools/polly/utils/cloog_src/test/forwardsub-3-1-2.good.c create mode 100644 tools/polly/utils/cloog_src/test/gauss.c create mode 100644 tools/polly/utils/cloog_src/test/gauss.cloog create mode 100644 tools/polly/utils/cloog_src/test/gauss.good.c create mode 100644 tools/polly/utils/cloog_src/test/generate_test.c create mode 100644 tools/polly/utils/cloog_src/test/gesced.c create mode 100644 tools/polly/utils/cloog_src/test/gesced.cloog create mode 100644 tools/polly/utils/cloog_src/test/gesced.good.c create mode 100644 tools/polly/utils/cloog_src/test/gesced2.c create mode 100644 tools/polly/utils/cloog_src/test/gesced2.cloog create mode 100644 tools/polly/utils/cloog_src/test/gesced2.good.c create mode 100644 tools/polly/utils/cloog_src/test/gesced3.c create mode 100644 tools/polly/utils/cloog_src/test/gesced3.cloog create mode 100644 tools/polly/utils/cloog_src/test/gesced3.good.c create mode 100644 tools/polly/utils/cloog_src/test/guide.c create mode 100644 tools/polly/utils/cloog_src/test/guide.cloog create mode 100644 tools/polly/utils/cloog_src/test/guide.good.c create mode 100644 tools/polly/utils/cloog_src/test/iftest.c create mode 100644 tools/polly/utils/cloog_src/test/iftest.cloog create mode 100644 tools/polly/utils/cloog_src/test/iftest.good.c create mode 100644 tools/polly/utils/cloog_src/test/iftest2.c create mode 100644 tools/polly/utils/cloog_src/test/iftest2.cloog create mode 100644 tools/polly/utils/cloog_src/test/iftest2.good.c create mode 100644 tools/polly/utils/cloog_src/test/iftestf.cloog create mode 100644 tools/polly/utils/cloog_src/test/iftestf.f create mode 100644 tools/polly/utils/cloog_src/test/infinite.c create mode 100644 tools/polly/utils/cloog_src/test/infinite.cloog create mode 100644 tools/polly/utils/cloog_src/test/infinite.omega create mode 100644 tools/polly/utils/cloog_src/test/infinite2.c create mode 100644 tools/polly/utils/cloog_src/test/infinite2.cloog create mode 100644 tools/polly/utils/cloog_src/test/infinite3.c create mode 100644 tools/polly/utils/cloog_src/test/infinite3.cloog create mode 100644 tools/polly/utils/cloog_src/test/infinite4.c create mode 100644 tools/polly/utils/cloog_src/test/infinite4.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/jacobi-shared.c create mode 100644 tools/polly/utils/cloog_src/test/isl/jacobi-shared.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/jacobi-shared.good.c create mode 100644 tools/polly/utils/cloog_src/test/isl/mod.c create mode 100644 tools/polly/utils/cloog_src/test/isl/mod.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/mod2.c create mode 100644 tools/polly/utils/cloog_src/test/isl/mod2.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/mod3.c create mode 100644 tools/polly/utils/cloog_src/test/isl/mod3.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/mod4.c create mode 100644 tools/polly/utils/cloog_src/test/isl/mod4.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/mxm-shared.c create mode 100644 tools/polly/utils/cloog_src/test/isl/mxm-shared.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/unroll.c create mode 100644 tools/polly/utils/cloog_src/test/isl/unroll.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/unroll.good.c create mode 100644 tools/polly/utils/cloog_src/test/isl/unroll2.c create mode 100644 tools/polly/utils/cloog_src/test/isl/unroll2.cloog create mode 100644 tools/polly/utils/cloog_src/test/isl/unroll2.good.c create mode 100644 tools/polly/utils/cloog_src/test/ispdc.cloog create mode 100644 tools/polly/utils/cloog_src/test/issues create mode 100644 tools/polly/utils/cloog_src/test/largeur.c create mode 100644 tools/polly/utils/cloog_src/test/largeur.cloog create mode 100644 tools/polly/utils/cloog_src/test/largeur.good.c create mode 100644 tools/polly/utils/cloog_src/test/levenshtein-1-2-3.c create mode 100644 tools/polly/utils/cloog_src/test/levenshtein-1-2-3.cloog create mode 100644 tools/polly/utils/cloog_src/test/levenshtein-1-2-3.good.c create mode 100644 tools/polly/utils/cloog_src/test/levenshtein-1-2-3f.c create mode 100644 tools/polly/utils/cloog_src/test/levenshtein-1-2-3f.cloog create mode 100644 tools/polly/utils/cloog_src/test/levenshtein-1-2-3f.f create mode 100644 tools/polly/utils/cloog_src/test/lex.c create mode 100644 tools/polly/utils/cloog_src/test/lex.cloog create mode 100644 tools/polly/utils/cloog_src/test/lex.good.c create mode 100644 tools/polly/utils/cloog_src/test/lineality-1-2.c create mode 100644 tools/polly/utils/cloog_src/test/lineality-1-2.cloog create mode 100644 tools/polly/utils/cloog_src/test/lineality-1-2.good.c create mode 100644 tools/polly/utils/cloog_src/test/lineality-2-1-2.c create mode 100644 tools/polly/utils/cloog_src/test/lineality-2-1-2.cloog create mode 100644 tools/polly/utils/cloog_src/test/lineality-2-1-2.good.c create mode 100644 tools/polly/utils/cloog_src/test/logo.c create mode 100644 tools/polly/utils/cloog_src/test/logo.cloog create mode 100644 tools/polly/utils/cloog_src/test/logo.good.c create mode 100644 tools/polly/utils/cloog_src/test/logopar.c create mode 100644 tools/polly/utils/cloog_src/test/logopar.cloog create mode 100644 tools/polly/utils/cloog_src/test/logopar.good.c create mode 100644 tools/polly/utils/cloog_src/test/lu.c create mode 100644 tools/polly/utils/cloog_src/test/lu.cloog create mode 100644 tools/polly/utils/cloog_src/test/lu.good.c create mode 100644 tools/polly/utils/cloog_src/test/lu2.c create mode 100644 tools/polly/utils/cloog_src/test/lu2.cloog create mode 100644 tools/polly/utils/cloog_src/test/lu2.good.c create mode 100644 tools/polly/utils/cloog_src/test/lub.c create mode 100644 tools/polly/utils/cloog_src/test/lub.cloog create mode 100644 tools/polly/utils/cloog_src/test/lub.good.c create mode 100644 tools/polly/utils/cloog_src/test/lux.c create mode 100644 tools/polly/utils/cloog_src/test/lux.cloog create mode 100644 tools/polly/utils/cloog_src/test/lux.good.c create mode 100644 tools/polly/utils/cloog_src/test/manual_basic.cloog create mode 100644 tools/polly/utils/cloog_src/test/manual_gauss.cloog create mode 100644 tools/polly/utils/cloog_src/test/manual_scattering.cloog create mode 100644 tools/polly/utils/cloog_src/test/merge.c create mode 100644 tools/polly/utils/cloog_src/test/merge.cloog create mode 100644 tools/polly/utils/cloog_src/test/merge.good.c create mode 100644 tools/polly/utils/cloog_src/test/min-1-1.c create mode 100644 tools/polly/utils/cloog_src/test/min-1-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/min-1-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/min-2-1.c create mode 100644 tools/polly/utils/cloog_src/test/min-2-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/min-2-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/min-3-1.c create mode 100644 tools/polly/utils/cloog_src/test/min-3-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/min-3-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/min-4-1.c create mode 100644 tools/polly/utils/cloog_src/test/min-4-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/min-4-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/mod4.c create mode 100644 tools/polly/utils/cloog_src/test/mod4.cloog create mode 100644 tools/polly/utils/cloog_src/test/mode.c create mode 100644 tools/polly/utils/cloog_src/test/mode.cloog create mode 100644 tools/polly/utils/cloog_src/test/mode.good.c create mode 100644 tools/polly/utils/cloog_src/test/multi-mm-1.c create mode 100644 tools/polly/utils/cloog_src/test/multi-mm-1.cloog create mode 100644 tools/polly/utils/cloog_src/test/multi-mm-1.good.c create mode 100644 tools/polly/utils/cloog_src/test/multi-stride.c create mode 100644 tools/polly/utils/cloog_src/test/multi-stride.cloog create mode 100644 tools/polly/utils/cloog_src/test/multi-stride2.c create mode 100644 tools/polly/utils/cloog_src/test/multi-stride2.cloog create mode 100644 tools/polly/utils/cloog_src/test/no_lindep.c create mode 100644 tools/polly/utils/cloog_src/test/no_lindep.cloog create mode 100644 tools/polly/utils/cloog_src/test/no_lindep.good.c create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/deuxpts.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/dreamupT1.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/dreamupT3-delta-gamma.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/dreamupT3.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/dreamupT3.omega create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/interpolation-duration.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/nul_complex1.c create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/nul_complex1.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/nul_complex1.good.c create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/usvd_e_t.c create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/usvd_e_t.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/usvd_e_t.good.c create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/youcef.c create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/youcef.cloog create mode 100644 tools/polly/utils/cloog_src/test/non_optimal/youcef.good.c create mode 100644 tools/polly/utils/cloog_src/test/nul_basic1.c create mode 100644 tools/polly/utils/cloog_src/test/nul_basic1.cloog create mode 100644 tools/polly/utils/cloog_src/test/nul_basic2.c create mode 100644 tools/polly/utils/cloog_src/test/nul_basic2.cloog create mode 100644 tools/polly/utils/cloog_src/test/nul_girbal.cloog create mode 100644 tools/polly/utils/cloog_src/test/nul_ispdc.cloog create mode 100644 tools/polly/utils/cloog_src/test/nul_lcpc.c create mode 100644 tools/polly/utils/cloog_src/test/nul_lcpc.cloog create mode 100644 tools/polly/utils/cloog_src/test/oc.out create mode 100644 tools/polly/utils/cloog_src/test/openscop/empty.c create mode 100644 tools/polly/utils/cloog_src/test/openscop/empty.scop create mode 100644 tools/polly/utils/cloog_src/test/openscop/matmult.c create mode 100644 tools/polly/utils/cloog_src/test/openscop/matmult.scop create mode 100644 tools/polly/utils/cloog_src/test/openscop/union.c create mode 100644 tools/polly/utils/cloog_src/test/openscop/union.scop create mode 100644 tools/polly/utils/cloog_src/test/orc.c create mode 100644 tools/polly/utils/cloog_src/test/orc.cloog create mode 100644 tools/polly/utils/cloog_src/test/orc.good.c create mode 100644 tools/polly/utils/cloog_src/test/otl.c create mode 100644 tools/polly/utils/cloog_src/test/otl.cloog create mode 100644 tools/polly/utils/cloog_src/test/otl.good.c create mode 100644 tools/polly/utils/cloog_src/test/overlap.cloog create mode 100644 tools/polly/utils/cloog_src/test/param-split.c create mode 100644 tools/polly/utils/cloog_src/test/param-split.cloog create mode 100644 tools/polly/utils/cloog_src/test/param-split.good.c create mode 100644 tools/polly/utils/cloog_src/test/pouchet.c create mode 100644 tools/polly/utils/cloog_src/test/pouchet.cloog create mode 100644 tools/polly/utils/cloog_src/test/pouchet.good.c create mode 100644 tools/polly/utils/cloog_src/test/published/CC2003/esced.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/CC2006/QR.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/CC2006/classen2.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/CC2006/dreamupT3.cloog create mode 100755 tools/polly/utils/cloog_src/test/published/CC2006/swim.B.MAIN__.scop7.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/PACT2004/youcefn.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/Web/web1.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/Web/web2.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/Web/web3.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/Web/web4.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/Web/web5.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/Web/web6.cloog create mode 100644 tools/polly/utils/cloog_src/test/published/Web/web7.cloog create mode 100644 tools/polly/utils/cloog_src/test/quillere.cloog create mode 100644 tools/polly/utils/cloog_src/test/rational.cloog create mode 100644 tools/polly/utils/cloog_src/test/readme.cloog create mode 100644 tools/polly/utils/cloog_src/test/rectangle.c create mode 100644 tools/polly/utils/cloog_src/test/rectangle.cloog create mode 100644 tools/polly/utils/cloog_src/test/rectangle.good.c create mode 100644 tools/polly/utils/cloog_src/test/reports/fabrice_baray_29-10-2004 create mode 100644 tools/polly/utils/cloog_src/test/reports/kim_daegon_27-04-2005.eml create mode 100644 tools/polly/utils/cloog_src/test/reports/kristof_beyls_16-05-2005.txt create mode 100644 tools/polly/utils/cloog_src/test/reports/michael_classen_03-05-2005.eml create mode 100644 tools/polly/utils/cloog_src/test/reports/michael_classen_27-10-2004.txt create mode 100644 tools/polly/utils/cloog_src/test/reports/nicolas_vasilache_03-05-2005.eml create mode 100644 tools/polly/utils/cloog_src/test/reports/nicolas_vasilache_09-05-2005.txt create mode 100644 tools/polly/utils/cloog_src/test/reports/sergej_schwenk_01-06-2004.txt create mode 100644 tools/polly/utils/cloog_src/test/reports/sylvain_girbal_01-11-2004.txt create mode 100644 tools/polly/utils/cloog_src/test/reports/sylvain_girbal_24-02-2004.txt create mode 100644 tools/polly/utils/cloog_src/test/reservoir/QR.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/QR.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/QR.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/bastoul3.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/bastoul3.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/cholesky2.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/cholesky2.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/cholesky2.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/fusion1.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/fusion1.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/fusion1.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/fusion2.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/fusion2.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/fusion2.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/jacobi2.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/jacobi2.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/jacobi2.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/jacobi3.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/jacobi3.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/jacobi3.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam1.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam1.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam1.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam2.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/lim-lam2.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam2.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam3.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/lim-lam3.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam3.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam4.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/lim-lam4.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam4.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam5.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/lim-lam5.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam5.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam6.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/lim-lam6.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/lim-lam6.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/liu-zhuge1.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/liu-zhuge1.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/liu-zhuge1.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/loechner3.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/loechner3.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/loechner3.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/loechner4.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/loechner4.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/loechner4.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/loechner5.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/loechner5.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/loechner5.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/long.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/long.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/makefile create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-interp.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/mg-interp.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-interp.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-interp2.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/mg-interp2.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-interp2.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-psinv.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/mg-psinv.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-psinv.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-resid.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/mg-resid.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-resid.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-rprj3.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/mg-rprj3.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/mg-rprj3.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali1.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/pingali1.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali1.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali2.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/pingali2.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali2.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali3.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/pingali3.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali3.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali4.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/pingali4.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali4.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali5.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/pingali5.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali5.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali6.c create mode 100755 tools/polly/utils/cloog_src/test/reservoir/pingali6.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/pingali6.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/stride.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/stride.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/stride2.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/stride2.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/tang-xue1.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/tang-xue1.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/tang-xue1.good.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/two.c create mode 100644 tools/polly/utils/cloog_src/test/reservoir/two.cloog create mode 100644 tools/polly/utils/cloog_src/test/reservoir/two.good.c create mode 100644 tools/polly/utils/cloog_src/test/singleton.c create mode 100644 tools/polly/utils/cloog_src/test/singleton.cloog create mode 100644 tools/polly/utils/cloog_src/test/singleton.good.c create mode 100644 tools/polly/utils/cloog_src/test/sor1d.c create mode 100644 tools/polly/utils/cloog_src/test/sor1d.cloog create mode 100644 tools/polly/utils/cloog_src/test/sor1d.good.c create mode 100644 tools/polly/utils/cloog_src/test/square+triangle-1-1-2-3.c create mode 100644 tools/polly/utils/cloog_src/test/square+triangle-1-1-2-3.cloog create mode 100644 tools/polly/utils/cloog_src/test/square+triangle-1-1-2-3.good.c create mode 100755 tools/polly/utils/cloog_src/test/stage.cloog create mode 100644 tools/polly/utils/cloog_src/test/stride.c create mode 100644 tools/polly/utils/cloog_src/test/stride.cloog create mode 100644 tools/polly/utils/cloog_src/test/stride.good.c create mode 100644 tools/polly/utils/cloog_src/test/stride2.c create mode 100644 tools/polly/utils/cloog_src/test/stride2.cloog create mode 100644 tools/polly/utils/cloog_src/test/stride2.good.c create mode 100644 tools/polly/utils/cloog_src/test/stride3.c create mode 100644 tools/polly/utils/cloog_src/test/stride3.cloog create mode 100644 tools/polly/utils/cloog_src/test/stride4.c create mode 100644 tools/polly/utils/cloog_src/test/stride4.cloog create mode 100644 tools/polly/utils/cloog_src/test/swim.c create mode 100644 tools/polly/utils/cloog_src/test/swim.cloog create mode 100644 tools/polly/utils/cloog_src/test/swim.good.c create mode 100644 tools/polly/utils/cloog_src/test/test.c create mode 100644 tools/polly/utils/cloog_src/test/test.cloog create mode 100644 tools/polly/utils/cloog_src/test/test.good.c create mode 100644 tools/polly/utils/cloog_src/test/tete.cloog create mode 100644 tools/polly/utils/cloog_src/test/thomasset.c create mode 100644 tools/polly/utils/cloog_src/test/thomasset.cloog create mode 100644 tools/polly/utils/cloog_src/test/thomasset.good.c create mode 100644 tools/polly/utils/cloog_src/test/tiling.c create mode 100644 tools/polly/utils/cloog_src/test/tiling.cloog create mode 100644 tools/polly/utils/cloog_src/test/tiling.good.c create mode 100644 tools/polly/utils/cloog_src/test/tiling2.cloog create mode 100644 tools/polly/utils/cloog_src/test/tiling3.cloog create mode 100644 tools/polly/utils/cloog_src/test/uday_scalars.c create mode 100644 tools/polly/utils/cloog_src/test/uday_scalars.cloog create mode 100644 tools/polly/utils/cloog_src/test/uday_scalars.good.c create mode 100644 tools/polly/utils/cloog_src/test/union.c create mode 100644 tools/polly/utils/cloog_src/test/union.cloog create mode 100644 tools/polly/utils/cloog_src/test/union.good.c create mode 100755 tools/polly/utils/cloog_src/test/urgent/matmul.B.main.scop1.cloog create mode 100644 tools/polly/utils/cloog_src/test/urgent/matmul.cloog create mode 100644 tools/polly/utils/cloog_src/test/urgent/matmul1.cloog create mode 100644 tools/polly/utils/cloog_src/test/urgent/scop7.cloog create mode 100644 tools/polly/utils/cloog_src/test/urgent/swim.cloog create mode 100644 tools/polly/utils/cloog_src/test/urgent/swim7.cloog create mode 100644 tools/polly/utils/cloog_src/test/vasilache.c create mode 100644 tools/polly/utils/cloog_src/test/vasilache.cloog create mode 100644 tools/polly/utils/cloog_src/test/vasilache.good.c create mode 100644 tools/polly/utils/cloog_src/test/vivien.c create mode 100644 tools/polly/utils/cloog_src/test/vivien.cloog create mode 100644 tools/polly/utils/cloog_src/test/vivien.good.c create mode 100644 tools/polly/utils/cloog_src/test/vivien2.c create mode 100644 tools/polly/utils/cloog_src/test/vivien2.cloog create mode 100644 tools/polly/utils/cloog_src/test/vivien2.good.c create mode 100644 tools/polly/utils/cloog_src/test/walters.c create mode 100644 tools/polly/utils/cloog_src/test/walters.cloog create mode 100644 tools/polly/utils/cloog_src/test/walters.good.c create mode 100644 tools/polly/utils/cloog_src/test/walters2.c create mode 100644 tools/polly/utils/cloog_src/test/walters2.cloog create mode 100644 tools/polly/utils/cloog_src/test/walters2.good.c create mode 100644 tools/polly/utils/cloog_src/test/walters3.c create mode 100644 tools/polly/utils/cloog_src/test/walters3.cloog create mode 100644 tools/polly/utils/cloog_src/test/walters3.good.c create mode 100644 tools/polly/utils/cloog_src/test/wavefront.c create mode 100644 tools/polly/utils/cloog_src/test/wavefront.cloog create mode 100644 tools/polly/utils/cloog_src/test/wavefront.good.c create mode 100644 tools/polly/utils/cloog_src/test/yosr.c create mode 100644 tools/polly/utils/cloog_src/test/yosr.cloog create mode 100644 tools/polly/utils/cloog_src/test/yosr.good.c create mode 100644 tools/polly/utils/cloog_src/test/yosr.omega create mode 100644 tools/polly/utils/cloog_src/test/yosr2.c create mode 100644 tools/polly/utils/cloog_src/test/yosr2.cloog create mode 100644 tools/polly/utils/cloog_src/test/yosr2.good.c create mode 100644 tools/polly/utils/cloog_src/test/yosr_sync.cloog create mode 100644 tools/polly/utils/cloog_src/test/yosrf.cloog create mode 100644 tools/polly/utils/cloog_src/test/yosrf.f create mode 100644 tools/polly/utils/cloog_src/test/youcefn.cloog create mode 100755 tools/polly/utils/jscop2cloog.py create mode 100644 tools/polly/utils/pyscop/isl.py create mode 100755 tools/polly/utils/pyscop/jscop2iscc.py create mode 100644 tools/polly/utils/pyscop/pyscop.py create mode 100644 tools/polly/www/.htaccess create mode 100644 tools/polly/www/bugs.html create mode 100644 tools/polly/www/content.css create mode 100644 tools/polly/www/contributors.html create mode 100644 tools/polly/www/documentation.html create mode 100644 tools/polly/www/documentation/memaccess.html create mode 100644 tools/polly/www/documentation/passes.html create mode 100644 tools/polly/www/example_load_Polly_into_clang.html create mode 100644 tools/polly/www/example_manual_matmul.html create mode 100644 tools/polly/www/examples.html create mode 100644 tools/polly/www/experiments/matmul/.htaccess create mode 100644 tools/polly/www/experiments/matmul/init_array___%1---%19.jscop create mode 100644 tools/polly/www/experiments/matmul/main___%1---%17.jscop create mode 100644 tools/polly/www/experiments/matmul/main___%1---%17.jscop.interchanged create mode 100644 tools/polly/www/experiments/matmul/main___%1---%17.jscop.interchanged+tiled create mode 100644 tools/polly/www/experiments/matmul/main___%1---%17.jscop.interchanged+tiled+vector create mode 100644 tools/polly/www/experiments/matmul/matmul.c create mode 100755 tools/polly/www/experiments/matmul/matmul.normalopt.exe create mode 100644 tools/polly/www/experiments/matmul/matmul.normalopt.ll create mode 100644 tools/polly/www/experiments/matmul/matmul.normalopt.s create mode 100755 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.exe create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.ll create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.s create mode 100755 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.exe create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.ll create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.s create mode 100755 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled.exe create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled.ll create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged+tiled.s create mode 100755 tools/polly/www/experiments/matmul/matmul.polly.interchanged.exe create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged.ll create mode 100644 tools/polly/www/experiments/matmul/matmul.polly.interchanged.s create mode 100644 tools/polly/www/experiments/matmul/matmul.preopt.ll create mode 100644 tools/polly/www/experiments/matmul/matmul.s create mode 100755 tools/polly/www/experiments/matmul/runall.sh create mode 100644 tools/polly/www/experiments/matmul/scops.init_array.dot create mode 100644 tools/polly/www/experiments/matmul/scops.init_array.dot.png create mode 100644 tools/polly/www/experiments/matmul/scops.main.dot create mode 100644 tools/polly/www/experiments/matmul/scops.main.dot.png create mode 100644 tools/polly/www/experiments/matmul/scops.print_array.dot create mode 100644 tools/polly/www/experiments/matmul/scops.print_array.dot.png create mode 100644 tools/polly/www/experiments/matmul/scopsonly.init_array.dot create mode 100644 tools/polly/www/experiments/matmul/scopsonly.init_array.dot.png create mode 100644 tools/polly/www/experiments/matmul/scopsonly.main.dot create mode 100644 tools/polly/www/experiments/matmul/scopsonly.main.dot.png create mode 100644 tools/polly/www/experiments/matmul/scopsonly.print_array.dot create mode 100644 tools/polly/www/experiments/matmul/scopsonly.print_array.dot.png create mode 100644 tools/polly/www/get_started.html create mode 100644 tools/polly/www/images/architecture.png create mode 100644 tools/polly/www/images/iit-madras.png create mode 100644 tools/polly/www/images/osu.png create mode 100644 tools/polly/www/images/performance/parallel-large.png create mode 100644 tools/polly/www/images/performance/parallel-small.png create mode 100644 tools/polly/www/images/performance/sequential-large.png create mode 100644 tools/polly/www/images/performance/sequential-small.png create mode 100644 tools/polly/www/images/sys-uni.png create mode 100644 tools/polly/www/images/uni-passau.png create mode 100644 tools/polly/www/images/video-summit-2011.png create mode 100644 tools/polly/www/index.html create mode 100644 tools/polly/www/menu.css create mode 100644 tools/polly/www/menu.html.incl create mode 100644 tools/polly/www/performance.html create mode 100644 tools/polly/www/phonecall.html create mode 100644 tools/polly/www/polly.sh create mode 100644 tools/polly/www/publications.html create mode 100644 tools/polly/www/publications/grosser-diploma-thesis.pdf create mode 100644 tools/polly/www/publications/grosser-impact-2011-slides.pdf create mode 100644 tools/polly/www/publications/grosser-impact-2011.pdf create mode 100644 tools/polly/www/publications/raghesh-a-masters-thesis.pdf create mode 100644 tools/polly/www/todo.html create mode 100644 tools/polly/www/video-js/video-js.css create mode 100644 tools/polly/www/video-js/video.js diff --git a/tools/polly/CMakeLists.txt b/tools/polly/CMakeLists.txt new file mode 100644 index 00000000000..e6d53cf19f3 --- /dev/null +++ b/tools/polly/CMakeLists.txt @@ -0,0 +1,166 @@ +# Check if this is a in tree build. +if (NOT DEFINED LLVM_MAIN_SRC_DIR) + project(Polly) + cmake_minimum_required(VERSION 2.8) + + # Where is LLVM installed? + set(LLVM_INSTALL_ROOT "" CACHE PATH "Root of LLVM install.") + # Check if the LLVM_INSTALL_ROOT valid. + if( NOT EXISTS ${LLVM_INSTALL_ROOT}/include/llvm ) + message(FATAL_ERROR "LLVM_INSTALL_ROOT (${LLVM_INSTALL_ROOT}) is not a valid LLVM installation.") + endif(NOT EXISTS ${LLVM_INSTALL_ROOT}/include/llvm) + # Add the llvm header path. + include_directories(${LLVM_INSTALL_ROOT}/include/) + + # Get the system librarys that will link into LLVM. + function(get_system_libs return_var) + # Returns in `return_var' a list of system libraries used by LLVM. + if( NOT MSVC ) + if( MINGW ) + set(system_libs ${system_libs} imagehlp psapi) + elseif( CMAKE_HOST_UNIX ) + if( HAVE_LIBDL ) + set(system_libs ${system_libs} ${CMAKE_DL_LIBS}) + endif() + if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD ) + set(system_libs ${system_libs} pthread) + endif() + endif( MINGW ) + endif( NOT MSVC ) + set(${return_var} ${system_libs} PARENT_SCOPE) + endfunction(get_system_libs) + + # Now set the header paths. + execute_process(COMMAND "${LLVM_INSTALL_ROOT}/bin/llvm-config" --includedir + OUTPUT_VARIABLE LLVM_INCLUDE_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE) + include_directories( ${LLVM_INCLUDE_DIR} ) + + # And then set the cxx flags. + execute_process(COMMAND "${LLVM_INSTALL_ROOT}/bin/llvm-config" --cxxflags + OUTPUT_VARIABLE LLVM_CXX_FLAGS + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${LLVM_CXX_FLAGS}) +endif(NOT DEFINED LLVM_MAIN_SRC_DIR) + +set(POLLY_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(POLLY_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +# Add appropriate flags for GCC +if (CMAKE_COMPILER_IS_GNUCXX) + # FIXME: Turn off exceptions, RTTI: + # -fno-exceptions -fno-rtti + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -fno-exceptions -fno-rtti") +endif () + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti") + +# Add path for custom modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${POLLY_SOURCE_DIR}/cmake") + +FIND_PACKAGE(Cloog REQUIRED) +FIND_PACKAGE(Isl REQUIRED) +FIND_PACKAGE(Gmp REQUIRED) + +option(POLLY_ENABLE_OPENSCOP "Enable Openscop library for scop import/export" ON) +if (POLLY_ENABLE_OPENSCOP) + FIND_PACKAGE(OpenScop) +endif(POLLY_ENABLE_OPENSCOP) + +option(POLLY_ENABLE_SCOPLIB "Enable SCoPLib library for scop import/export" ON) +if (POLLY_ENABLE_SCOPLIB) + FIND_PACKAGE(SCoPLib) +endif(POLLY_ENABLE_SCOPLIB) + +INCLUDE_DIRECTORIES( ${CLOOG_INCLUDE_DIR} ) +INCLUDE_DIRECTORIES( ${ISL_INCLUDE_DIR} ) +INCLUDE_DIRECTORIES( ${GMP_INCLUDE_DIR} ) + +# Support OpenScop export/import if the library is available. +if (OPENSCOP_FOUND) + INCLUDE_DIRECTORIES( ${OPENSCOP_INCLUDE_DIR} ) +endif(OPENSCOP_FOUND) +if (SCOPLIB_FOUND) + INCLUDE_DIRECTORIES( ${SCOPLIB_INCLUDE_DIR} ) +endif(SCOPLIB_FOUND) + +macro(add_polly_library name) + set(srcs ${ARGN}) + if(MSVC_IDE OR XCODE) + file( GLOB_RECURSE headers *.h *.td *.def) + set(srcs ${srcs} ${headers}) + string( REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR}) + list( GET split_path -1 dir) + file( GLOB_RECURSE headers + ../../include/polly${dir}/*.h) + set(srcs ${srcs} ${headers}) + endif(MSVC_IDE OR XCODE) + if (MODULE) + set(libkind MODULE) + elseif (SHARED_LIBRARY) + set(libkind SHARED) + else() + set(libkind) + endif() + add_library( ${name} ${libkind} ${srcs} ) + if( LLVM_COMMON_DEPENDS ) + add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} ) + endif( LLVM_COMMON_DEPENDS ) + if( LLVM_USED_LIBS ) + foreach(lib ${LLVM_USED_LIBS}) + target_link_libraries( ${name} ${lib} ) + endforeach(lib) + endif( LLVM_USED_LIBS ) + + target_link_libraries( ${name} ${CLOOG_LIBRARY} ${ISL_LIBRARY} ${GMP_LIBRARY}) + if (OPENSCOP_FOUND) + target_link_libraries( ${name} ${OPENSCOP_LIBRARY}) + endif(OPENSCOP_FOUND) + if (SCOPLIB_FOUND) + target_link_libraries( ${name} ${SCOPLIB_LIBRARY}) + endif(SCOPLIB_FOUND) + + if( LLVM_LINK_COMPONENTS ) + llvm_config(${name} ${LLVM_LINK_COMPONENTS}) + endif( LLVM_LINK_COMPONENTS ) + get_system_libs(llvm_system_libs) + if( llvm_system_libs ) + target_link_libraries(${name} ${llvm_system_libs}) + endif( llvm_system_libs ) + + if(MSVC) + get_target_property(cflag ${name} COMPILE_FLAGS) + if(NOT cflag) + set(cflag "") + endif(NOT cflag) + set(cflag "${cflag} /Za") + set_target_properties(${name} PROPERTIES COMPILE_FLAGS ${cflag}) + endif(MSVC) + install(TARGETS ${name} + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) +endmacro(add_polly_library) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/lib/JSON/include + ${CMAKE_CURRENT_BINARY_DIR}/include + ) + +install(DIRECTORY include + DESTINATION . + PATTERN ".svn" EXCLUDE + ) + +add_definitions( -D_GNU_SOURCE ) + +add_subdirectory(include) +add_subdirectory(lib) +add_subdirectory(test) +add_subdirectory(tools) +# TODO: docs. + + +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/include/polly/Config/config.h.cmake + ${POLLY_BINARY_DIR}/include/polly/Config/config.h ) + diff --git a/tools/polly/CREDITS.txt b/tools/polly/CREDITS.txt new file mode 100644 index 00000000000..1757df62bd3 --- /dev/null +++ b/tools/polly/CREDITS.txt @@ -0,0 +1,30 @@ +This file is a partial list of people who have contributed to Polly. +If you have contributed a patch or made some other contribution to +Polly, please submit a patch to this file to add yourself, and it will be +done! + +The list is sorted by surname and formatted to allow easy grepping and +beautification by scripts. The fields are: name (N), email (E), web-address +(W), PGP key ID and fingerprint (P), description (D), and snail-mail address +(S). + +N: Raghesh Aloor +E: raghesh.a@gmail.com +D: OpenMP code generation +D: Google Summer of Code student 2011 + +N: Tobias Grosser +E: tobias@grosser.es +W: http://www.grosser.es +D: Co-founder, design of the overall architecture + +N: Andreas Simbuerger +E: simbuerg@fim.uni-passau.de +W: http://www.infosun.fim.uni-passau.de/cl/staff/simbuerger/ +D: Profiling infrastructure + +N: Hongbin Zheng +E: etherzhhb@gmail.com +D: Co-founder +D: scop detection, automake/cmake infrastructure, scopinfo, scoppasses, ... +D: Google Summer of Code student 2010 diff --git a/tools/polly/LICENSE.txt b/tools/polly/LICENSE.txt new file mode 100644 index 00000000000..8081b7d1905 --- /dev/null +++ b/tools/polly/LICENSE.txt @@ -0,0 +1,61 @@ +============================================================================== +Polly Release License +============================================================================== +University of Illinois/NCSA +Open Source License + +Copyright (c) 2009-2012 Polly Team +All rights reserved. + +Developed by: + + Polly Team + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal with +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the Polly Team, copyright holders, nor the names of + its contributors may be used to endorse or promote products derived from + this Software without specific prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE +SOFTWARE. + +============================================================================== +Copyrights and Licenses for Third Party Software Distributed with LLVM: +============================================================================== +The Polly software contains code written by third parties. Such software will +have its own individual LICENSE.TXT file in the directory in which it appears. +This file will describe the copyrights, license, and restrictions which apply +to that code. + +The disclaimer of warranty in the University of Illinois Open Source License +applies to all code in the Polly Distribution, and nothing in any of the other +licenses gives permission to use the names of the Polly Team or promote products +derived from this Software. + +The following pieces of software have additional or alternate copyrights, +licenses, and/or restrictions: + +Program Directory +------- --------- +jsoncpp lib/JSON + + + diff --git a/tools/polly/Makefile b/tools/polly/Makefile new file mode 100644 index 00000000000..2ad5b363e2f --- /dev/null +++ b/tools/polly/Makefile @@ -0,0 +1,17 @@ +##===- projects/polly/Makefile -----------------------------*- Makefile -*-===## +# +# This is a polly Makefile for a project that uses LLVM. +# +##===----------------------------------------------------------------------===## + +# +# Indicates our relative path to the top of the project's root directory. +# +LEVEL = . +DIRS = lib test tools +EXTRA_DIST = include + +# +# Include the Master Makefile that knows how to build all. +# +include $(LEVEL)/Makefile.common diff --git a/tools/polly/Makefile.common.in b/tools/polly/Makefile.common.in new file mode 100755 index 00000000000..8a5b945840b --- /dev/null +++ b/tools/polly/Makefile.common.in @@ -0,0 +1,34 @@ +#===-- Makefile.common - Common make rules for Polly -------*- Makefile -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# +# Configuration file to set paths specific to local installation of LLVM +# +PROJECT_NAME := polly +PROJ_VERSION := 0.9 +# Set this variable to the top of the LLVM source tree. +LLVM_SRC_ROOT = @LLVM_SRC@ + +# Set the name of the project here + +# (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config). +LLVM_OBJ_ROOT = @LLVM_OBJ@ + +PROJ_SRC_ROOT := $(subst //,/,@abs_top_srcdir@) + +# Set the root directory of this project's object files +PROJ_OBJ_ROOT := $(subst //,/,@abs_top_builddir@) + +ifndef LLVM_OBJ_ROOT +include $(LEVEL)/Makefile.config +else +include $(PROJ_OBJ_ROOT)/Makefile.config +endif + +# Include LLVM's Master Makefile. +include $(LLVM_SRC_ROOT)/Makefile.common diff --git a/tools/polly/Makefile.config.in b/tools/polly/Makefile.config.in new file mode 100755 index 00000000000..197a3aa113c --- /dev/null +++ b/tools/polly/Makefile.config.in @@ -0,0 +1,42 @@ +#===-- Makefile.config - Local configuration for LLVM ------*- Makefile -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# +# +# This file is included by Makefile.common. It defines paths and other +# values specific to a particular installation of LLVM. +# +#===------------------------------------------------------------------------===# + +# Set the root directory of this polly's object files +POLLY_SRC_ROOT := $(subst //,/,@abs_top_srcdir@) + +# Set this variable to the top level directory where LLVM was built +POLLY_OBJ_ROOT := $(subst //,/,@abs_top_builddir@) + +# Set the root directory of this project's install prefix +PROJ_INSTALL_ROOT := @prefix@ + +# Set the C++ flags +ifeq (@GXX@,yes) +POLLY_CXXFLAGS := "-fno-common -Woverloaded-virtual -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings" +endif + +POLLY_CXXFLAGS += "-fno-rtti -fno-exceptions" + +# Do us work with scoplib? +OPENSCOP_FOUND := @openscop_found@ +SCOPLIB_FOUND := @scoplib_found@ + +# Set include directroys +POLLY_INC := @gmp_inc@ @isl_inc@ \ + @cloog_inc@ @openscop_inc@ @scoplib_inc@ \ + -I$(POLLY_SRC_ROOT)/lib/JSON/include + +POLLY_LD := @gmp_ld@ @isl_ld@ @cloog_ld@ @openscop_ld@ @scoplib_ld@ @scoplib_rpath@ + +POLLY_LIB := @gmp_lib@ @isl_lib@ @cloog_lib@ @openscop_lib@ @scoplib_lib@ diff --git a/tools/polly/README b/tools/polly/README new file mode 100644 index 00000000000..cbfb9d449ab --- /dev/null +++ b/tools/polly/README @@ -0,0 +1,10 @@ +Polly - Polyhedral optimizations for LLVM + +Polly uses a mathematical representation, the polyhedral model, to represent and +transform loops and other control flow structures. Using an abstract +representation it is possible to reason about transformations in a more general +way and to use highly optimized linear programming libraries to figure out the +optimal loop structure. These transformations can be used to do constant +propagation through arrays, remove dead loop iterations, optimize loops for +cache locality, optimize arrays, apply advanced automatic parallelization, drive +vectorization, or they can be used to do software pipelining. diff --git a/tools/polly/autoconf/AutoRegen.sh b/tools/polly/autoconf/AutoRegen.sh new file mode 100755 index 00000000000..bafef3449b8 --- /dev/null +++ b/tools/polly/autoconf/AutoRegen.sh @@ -0,0 +1,33 @@ +#!/bin/sh +die () { + echo "$@" 1>&2 + exit 1 +} + +test -d autoconf && test -f autoconf/configure.ac && cd autoconf +test -f configure.ac || die "Can't find 'autoconf' dir; please cd into it first" +autoconf --version | egrep '2\.[5-6][0-9]' > /dev/null +if test $? -ne 0 ; then + die "Your autoconf was not detected as being 2.5x" +fi +cwd=`pwd` +if test -d ../../../autoconf/m4 ; then + cd ../../../autoconf/m4 + llvm_m4=`pwd` + cd $cwd +elif test -d ../../llvm/autoconf/m4 ; then + cd ../../llvm/autoconf/m4 + llvm_m4=`pwd` + cd $cwd +else + die "Can't find the LLVM autoconf/m4 directory. polly should be checked out to projects directory" +fi +echo "Regenerating aclocal.m4 with aclocal" +rm -f aclocal.m4 +aclocal -I $llvm_m4 -I "$llvm_m4/.." -I $(pwd)/m4 || die "aclocal failed" +echo "Regenerating configure with autoconf 2.5x" +autoconf --force --warnings=all -o ../configure configure.ac || die "autoconf failed" +cd .. +echo "Regenerating config.h.in with autoheader" +autoheader --warnings=all -I autoconf -I autoconf/m4 -I $llvm_m4 -I "$llvm_m4/.." autoconf/configure.ac || die "autoheader failed" +exit 0 diff --git a/tools/polly/autoconf/LICENSE.TXT b/tools/polly/autoconf/LICENSE.TXT new file mode 100644 index 00000000000..72fdd39edcc --- /dev/null +++ b/tools/polly/autoconf/LICENSE.TXT @@ -0,0 +1,24 @@ +------------------------------------------------------------------------------ +Autoconf Files +------------------------------------------------------------------------------ +All autoconf files are licensed under the LLVM license with the following +additions: + +llvm/autoconf/install-sh: + This script is licensed under the LLVM license, with the following + additional copyrights and restrictions: + + Copyright 1991 by the Massachusetts Institute of Technology + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of M.I.T. not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. M.I.T. makes no representations about the + suitability of this software for any purpose. It is provided "as is" + without express or implied warranty. + +Please see the source files for additional copyrights. + diff --git a/tools/polly/autoconf/aclocal.m4 b/tools/polly/autoconf/aclocal.m4 new file mode 100644 index 00000000000..720f8ee7131 --- /dev/null +++ b/tools/polly/autoconf/aclocal.m4 @@ -0,0 +1,75 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +dnl find_lib_and_headers(name, verify-header, library-name, requirded?) +dnl Export +dnl name_inc in -I"include-path" form +dnl name_lib in -l"library-name" form +dnl name_ld in -L"library-path" form +dnl name_found set to "yes" if found + +AC_DEFUN([find_lib_and_headers], +[ + AC_LANG_PUSH(C++) + OLD_CXXFLAGS=$CXXFLAGS; + OLD_LDFLAGS=$LDFLAGS; + OLD_LIBS=$LIBS; + + LIBS="$LIBS -l$3"; + + # Get include path and lib path + AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1], [prefix of $1 ])], + [given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS"; + given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"], + [given_inc_path=inc_not_give_$1; + given_lib_path=lib_not_give_$1] + ) + # Check for library and headers works + AC_MSG_CHECKING([for $1 in $given_inc_path, $given_lib_path]) + # try to compile a file that includes a header of the library + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <$2>]], [[;]])], + [AC_MSG_RESULT([ok]) + AC_SUBST([$1_found],["yes"]) + AS_IF([test "x$given_inc_path" != "xinc_not_give_$1"], + [AC_SUBST([$1_inc],["-I$given_inc_path"])]) + AC_SUBST([$1_lib],["-l$3"]) + AS_IF([test "x$given_lib_path" != "xlib_not_give_$1"], + [AC_SUBST([$1_ld],["-L$given_lib_path"])])], + [AS_IF([test "x$4" = "xrequired"], + [AC_MSG_ERROR([$1 required but not found])], + [AC_MSG_RESULT([not found])])] + ) + + # reset original CXXFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS; + LIBS=$OLD_LIBS + AC_LANG_POP(C++) +]) + +# +# Provide the arguments and other processing needed for an LLVM project +# +AC_DEFUN([LLVM_CONFIG_PROJECT], + [AC_ARG_WITH([llvmsrc], + AS_HELP_STRING([--with-llvmsrc],[Location of LLVM Source Code]), + [llvm_src="$withval"],[llvm_src="]$1["]) + AC_SUBST(LLVM_SRC,$llvm_src) + AC_ARG_WITH([llvmobj], + AS_HELP_STRING([--with-llvmobj],[Location of LLVM Object Code]), + [llvm_obj="$withval"],[llvm_obj="]$2["]) + AC_SUBST(LLVM_OBJ,$llvm_obj) + AC_CONFIG_COMMANDS([setup],,[llvm_src="${LLVM_SRC}"]) +]) + diff --git a/tools/polly/autoconf/config.guess b/tools/polly/autoconf/config.guess new file mode 100644 index 00000000000..cc726cd15a9 --- /dev/null +++ b/tools/polly/autoconf/config.guess @@ -0,0 +1,1388 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-02-22' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i586-pc-interix3 + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/tools/polly/autoconf/config.sub b/tools/polly/autoconf/config.sub new file mode 100644 index 00000000000..9772e87d241 --- /dev/null +++ b/tools/polly/autoconf/config.sub @@ -0,0 +1,1489 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-02-22' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic4x | c4x*) + basic_machine=tic4x-unknown + os=-coff + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/tools/polly/autoconf/configure.ac b/tools/polly/autoconf/configure.ac new file mode 100644 index 00000000000..db48a26717f --- /dev/null +++ b/tools/polly/autoconf/configure.ac @@ -0,0 +1,114 @@ +dnl ************************************************************************** +dnl * Initialize +dnl ************************************************************************** +AC_INIT([Polly],[0.01],[polly-dev@googlegroups.com]) + +dnl Identify where LLVM source tree is +LLVM_SRC_ROOT="`(cd $srcdir/../..; pwd)`" +LLVM_OBJ_ROOT="`(cd ../..; pwd)`" + +dnl Tell autoconf that this is an LLVM project being configured +dnl This provides the --with-llvmsrc and --with-llvmobj options +LLVM_CONFIG_PROJECT($LLVM_SRC_ROOT,$LLVM_OBJ_ROOT) + +dnl Tell autoconf that the auxilliary files are actually located in +dnl the LLVM autoconf directory, not here. +AC_CONFIG_AUX_DIR($LLVM_SRC/autoconf) + +dnl Indicate that we require autoconf 2.59 or later. Ths is needed because we +dnl use some autoconf macros only available in 2.59. +AC_PREREQ(2.59) + +dnl Verify that the source directory is valid +AC_CONFIG_SRCDIR(["lib/Analysis/ScopInfo.cpp"]) + +dnl Configure a common Makefile +AC_CONFIG_FILES(Makefile.config) +AC_CONFIG_FILES(Makefile.common) + +dnl Configure project makefiles +dnl List every Makefile that exists within your source tree + +dnl Quit if the source directory has already been configured. +dnl NOTE: This relies upon undocumented autoconf behavior. +if test ${srcdir} != "." ; then + if test -f ${srcdir}/include/polly/Config/config.h ; then + AC_MSG_ERROR([Already configured in ${srcdir}]) + fi +fi + +AC_DEFINE([CLOOG_INT_GMP], [1], [Use gmp for isl]) + +dnl ************************************************************************** +dnl * Determine which system we are building on +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Check for programs. +dnl ************************************************************************** + +dnl AC_PROG_CPP +dnl AC_PROG_CC(gcc) +dnl AC_PROG_CXX(g++) + +dnl ************************************************************************** +dnl * Check for libraries. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Checks for header files. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Checks for typedefs, structures, and compiler characteristics. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Checks for library functions. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Enable various compile-time options +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Set the location of various third-party software packages +dnl ************************************************************************** +dnl Find Gmp +find_lib_and_headers([gmp], [gmp.h], [gmp], [required]) + +dnl Find Isl +find_lib_and_headers([isl], [isl/config.h], [isl], [required]) + +dnl Find cloog +saved_CXXFLAGS=$CXXFLAGS +CXXFLAGS="$CXXFLAGS $gmp_inc $isl_inc" +find_lib_and_headers([cloog], [cloog/isl/cloog.h], [cloog-isl], [required]) +CXXFLAGS=$saved_CXXFLAGS + + +dnl Check if Scoplib there +find_lib_and_headers([openscop], [openscop/scop.h], [openscop]) +AS_IF([test "x$openscop_found" = "xyes"], + [AC_DEFINE([OPENSCOP_FOUND],[1],[Define if openscop found])]) + +dnl Check if Scoplib there +find_lib_and_headers([scoplib], [scoplib/scop.h], [scoplib]) +AS_IF([test "x$scoplib_found" = "xyes"], + [AC_DEFINE([SCOPLIB_FOUND],[1],[Define if scoplib found])]) + +if test "x$scoplib_found" = "xyes"; then : + scoplib_rpath="-Wl,-rpath=$given_lib_path" +else + scoplib_rpath="" +fi + +AC_SUBST(scoplib_rpath) + +dnl ************************************************************************** +dnl * Create the output files +dnl ************************************************************************** + +dnl This must be last +AC_CONFIG_HEADERS(include/polly/Config/config.h) +AC_OUTPUT diff --git a/tools/polly/autoconf/configure.bak b/tools/polly/autoconf/configure.bak new file mode 100644 index 00000000000..1f16056e2dd --- /dev/null +++ b/tools/polly/autoconf/configure.bak @@ -0,0 +1,65 @@ +dnl ************************************************************************** +dnl * Initialize +dnl ************************************************************************** +AC_INIT([Polly],[0.01],[etherzhhb@gmail.com grosser@fim.uni-passau.de ojomojo@gmail.com]) + +dnl Identify where LLVM source tree is +LLVM_SRC_ROOT="../.." +LLVM_OBJ_ROOT="../.." +dnl Tell autoconf that the auxilliary files are actually located in +dnl the LLVM autoconf directory, not here. +AC_CONFIG_AUX_DIR($LLVM_SRC_ROOT/autoconf) + +dnl Tell autoconf that this is an LLVM project being configured +dnl This provides the --with-llvmsrc and --with-llvmobj options +LLVM_CONFIG_PROJECT($LLVM_SRC_ROOT,$LLVM_OBJ_ROOT) + +dnl Verify that the source directory is valid +AC_CONFIG_SRCDIR(["Makefile.common.in"]) + +dnl Configure a common Makefile +AC_CONFIG_FILES(Makefile.common) + +dnl Configure project makefiles +dnl List every Makefile that exists within your source tree +AC_CONFIG_MAKEFILE(Makefile) +AC_CONFIG_MAKEFILE(lib/Makefile) + +dnl ************************************************************************** +dnl * Determine which system we are building on +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Check for programs. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Check for libraries. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Checks for header files. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Checks for typedefs, structures, and compiler characteristics. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Checks for library functions. +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Enable various compile-time options +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Set the location of various third-party software packages +dnl ************************************************************************** + +dnl ************************************************************************** +dnl * Create the output files +dnl ************************************************************************** + +dnl This must be last +AC_OUTPUT diff --git a/tools/polly/autoconf/m4/find_lib_and_headers.m4 b/tools/polly/autoconf/m4/find_lib_and_headers.m4 new file mode 100755 index 00000000000..88880619ffd --- /dev/null +++ b/tools/polly/autoconf/m4/find_lib_and_headers.m4 @@ -0,0 +1,46 @@ +dnl find_lib_and_headers(name, verify-header, library-name, requirded?) +dnl Export +dnl name_inc in -I"include-path" form +dnl name_lib in -l"library-name" form +dnl name_ld in -L"library-path" form +dnl name_found set to "yes" if found + +AC_DEFUN([find_lib_and_headers], +[ + AC_LANG_PUSH(C++) + OLD_CXXFLAGS=$CXXFLAGS; + OLD_LDFLAGS=$LDFLAGS; + OLD_LIBS=$LIBS; + + LIBS="$LIBS -l$3"; + + # Get include path and lib path + AC_ARG_WITH([$1], + [AS_HELP_STRING([--with-$1], [prefix of $1 ])], + [given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS"; + given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"], + [given_inc_path=inc_not_give_$1; + given_lib_path=lib_not_give_$1] + ) + # Check for library and headers works + AC_MSG_CHECKING([for $1 in $given_inc_path, $given_lib_path]) + # try to compile a file that includes a header of the library + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <$2>]], [[;]])], + [AC_MSG_RESULT([ok]) + AC_SUBST([$1_found],["yes"]) + AS_IF([test "x$given_inc_path" != "xinc_not_give_$1"], + [AC_SUBST([$1_inc],["-I$given_inc_path"])]) + AC_SUBST([$1_lib],["-l$3"]) + AS_IF([test "x$given_lib_path" != "xlib_not_give_$1"], + [AC_SUBST([$1_ld],["-L$given_lib_path"])])], + [AS_IF([test "x$4" = "xrequired"], + [AC_MSG_ERROR([$1 required but not found])], + [AC_MSG_RESULT([not found])])] + ) + + # reset original CXXFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS; + LIBS=$OLD_LIBS + AC_LANG_POP(C++) +]) diff --git a/tools/polly/cmake/FindCloog.cmake b/tools/polly/cmake/FindCloog.cmake new file mode 100644 index 00000000000..057756f0085 --- /dev/null +++ b/tools/polly/cmake/FindCloog.cmake @@ -0,0 +1,19 @@ +FIND_PATH(CLOOG_INCLUDE_DIR cloog/isl/cloog.h) + +FIND_LIBRARY(CLOOG_LIBRARY NAMES cloog-isl) + +IF (CLOOG_INCLUDE_DIR AND CLOOG_LIBRARY) + SET(CLOOG_FOUND TRUE) +ENDIF (CLOOG_INCLUDE_DIR AND CLOOG_LIBRARY) + + +IF (CLOOG_FOUND) + IF (NOT CLOOG_FIND_QUIETLY) + MESSAGE(STATUS "Found Cloog: ${CLOOG_LIBRARY}") + ENDIF (NOT CLOOG_FIND_QUIETLY) +ELSE (CLOOG_FOUND) + IF (CLOOG_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Cloog") + ENDIF (CLOOG_FIND_REQUIRED) +ENDIF (CLOOG_FOUND) + diff --git a/tools/polly/cmake/FindGmp.cmake b/tools/polly/cmake/FindGmp.cmake new file mode 100644 index 00000000000..60def58152c --- /dev/null +++ b/tools/polly/cmake/FindGmp.cmake @@ -0,0 +1,19 @@ +FIND_PATH(GMP_INCLUDE_DIR gmp.h) + +FIND_LIBRARY(GMP_LIBRARY NAMES gmp) + +IF (GMP_INCLUDE_DIR AND GMP_LIBRARY) + SET(GMP_FOUND TRUE) +ENDIF (GMP_INCLUDE_DIR AND GMP_LIBRARY) + + +IF (GMP_FOUND) + IF (NOT GMP_FIND_QUIETLY) + MESSAGE(STATUS "Found GMP: ${GMP_LIBRARY}") + ENDIF (NOT GMP_FIND_QUIETLY) +ELSE (GMP_FOUND) + IF (GMP_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find GMP") + ENDIF (GMP_FIND_REQUIRED) +ENDIF (GMP_FOUND) + diff --git a/tools/polly/cmake/FindIsl.cmake b/tools/polly/cmake/FindIsl.cmake new file mode 100644 index 00000000000..bbebbaa8f88 --- /dev/null +++ b/tools/polly/cmake/FindIsl.cmake @@ -0,0 +1,19 @@ +FIND_PATH(ISL_INCLUDE_DIR isl/set.h) + +FIND_LIBRARY(ISL_LIBRARY NAMES isl) + +IF (ISL_INCLUDE_DIR AND ISL_LIBRARY) + SET(ISL_FOUND TRUE) +ENDIF (ISL_INCLUDE_DIR AND ISL_LIBRARY) + + +IF (ISL_FOUND) + IF (NOT Isl_FIND_QUIETLY) + MESSAGE(STATUS "Found Isl: ${ISL_LIBRARY}") + ENDIF (NOT Isl_FIND_QUIETLY) +ELSE (ISL_FOUND) + IF (Isl_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Isl") + ENDIF (Isl_FIND_REQUIRED) +ENDIF (ISL_FOUND) + diff --git a/tools/polly/cmake/FindOpenScop.cmake b/tools/polly/cmake/FindOpenScop.cmake new file mode 100644 index 00000000000..a1fbc636b82 --- /dev/null +++ b/tools/polly/cmake/FindOpenScop.cmake @@ -0,0 +1,19 @@ +FIND_PATH(OPENSCOP_INCLUDE_DIR openscop/scop.h) + +FIND_LIBRARY(OPENSCOP_LIBRARY NAMES openscop) + +IF (OPENSCOP_INCLUDE_DIR AND OPENSCOP_LIBRARY) + SET(OPENSCOP_FOUND TRUE) +ENDIF (OPENSCOP_INCLUDE_DIR AND OPENSCOP_LIBRARY) + + +IF (OPENSCOP_FOUND) + IF (NOT Isl_FIND_QUIETLY) + MESSAGE(STATUS "Found OpenScop: ${OPENSCOP_LIBRARY}") + ENDIF (NOT Isl_FIND_QUIETLY) +ELSE (OPENSCOP_FOUND) + IF (Isl_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find OpenScop") + ENDIF (Isl_FIND_REQUIRED) +ENDIF (OPENSCOP_FOUND) + diff --git a/tools/polly/cmake/FindSCoPLib.cmake b/tools/polly/cmake/FindSCoPLib.cmake new file mode 100644 index 00000000000..cb8307faf2d --- /dev/null +++ b/tools/polly/cmake/FindSCoPLib.cmake @@ -0,0 +1,19 @@ +FIND_PATH(SCOPLIB_INCLUDE_DIR scoplib/scop.h) + +FIND_LIBRARY(SCOPLIB_LIBRARY NAMES scoplib) + +IF (SCOPLIB_INCLUDE_DIR AND SCOPLIB_LIBRARY) + SET(SCOPLIB_FOUND TRUE) +ENDIF (SCOPLIB_INCLUDE_DIR AND SCOPLIB_LIBRARY) + + +IF (SCOPLIB_FOUND) + IF (NOT Isl_FIND_QUIETLY) + MESSAGE(STATUS "Found SCoPLib: ${SCOPLIB_LIBRARY}") + ENDIF (NOT Isl_FIND_QUIETLY) +ELSE (SCOPLIB_FOUND) + IF (Isl_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find SCoPLib") + ENDIF (Isl_FIND_REQUIRED) +ENDIF (SCOPLIB_FOUND) + diff --git a/tools/polly/configure b/tools/polly/configure new file mode 100755 index 00000000000..6e97251dc57 --- /dev/null +++ b/tools/polly/configure @@ -0,0 +1,4088 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.67 for Polly 0.01. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: polly-dev@googlegroups.com about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='Polly' +PACKAGE_TARNAME='polly' +PACKAGE_VERSION='0.01' +PACKAGE_STRING='Polly 0.01' +PACKAGE_BUGREPORT='polly-dev@googlegroups.com' +PACKAGE_URL='' + +ac_unique_file=""lib/Analysis/ScopInfo.cpp"" +ac_subst_vars='LTLIBOBJS +LIBOBJS +scoplib_rpath +scoplib_ld +scoplib_lib +scoplib_inc +scoplib_found +openscop_ld +openscop_lib +openscop_inc +openscop_found +cloog_ld +cloog_lib +cloog_inc +cloog_found +isl_ld +isl_lib +isl_inc +isl_found +gmp_ld +gmp_lib +gmp_inc +gmp_found +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +LLVM_OBJ +LLVM_SRC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_llvmsrc +with_llvmobj +with_gmp +with_isl +with_cloog +with_openscop +with_scoplib +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures Polly 0.01 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/polly] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of Polly 0.01:";; + esac + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-llvmsrc Location of LLVM Source Code + --with-llvmobj Location of LLVM Object Code + --with-gmp prefix of gmp + --with-isl prefix of isl + --with-cloog prefix of cloog + --with-openscop prefix of openscop + --with-scoplib prefix of scoplib + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +Polly configure 0.01 +generated by GNU Autoconf 2.67 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by Polly $as_me 0.01, which was +generated by GNU Autoconf 2.67. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5 ; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +LLVM_SRC_ROOT="`(cd $srcdir/../..; pwd)`" +LLVM_OBJ_ROOT="`(cd ../..; pwd)`" + + +# Check whether --with-llvmsrc was given. +if test "${with_llvmsrc+set}" = set; then : + withval=$with_llvmsrc; llvm_src="$withval" +else + llvm_src="$LLVM_SRC_ROOT" +fi + + LLVM_SRC=$llvm_src + + +# Check whether --with-llvmobj was given. +if test "${with_llvmobj+set}" = set; then : + withval=$with_llvmobj; llvm_obj="$withval" +else + llvm_obj="$LLVM_OBJ_ROOT" +fi + + LLVM_OBJ=$llvm_obj + + ac_config_commands="$ac_config_commands setup" + + + +ac_aux_dir= +for ac_dir in $LLVM_SRC/autoconf "$srcdir"/$LLVM_SRC/autoconf; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in $LLVM_SRC/autoconf \"$srcdir\"/$LLVM_SRC/autoconf" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + + + + + + +ac_config_files="$ac_config_files Makefile.config" + +ac_config_files="$ac_config_files Makefile.common" + + + +if test ${srcdir} != "." ; then + if test -f ${srcdir}/include/polly/Config/config.h ; then + as_fn_error $? "Already configured in ${srcdir}" "$LINENO" 5 + fi +fi + + +$as_echo "#define CLOOG_INT_GMP 1" >>confdefs.h + + + + + + + + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5 ; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5 ; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5 ; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5 ; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + OLD_CXXFLAGS=$CXXFLAGS; + OLD_LDFLAGS=$LDFLAGS; + OLD_LIBS=$LIBS; + + LIBS="$LIBS -lgmp"; + + # Get include path and lib path + +# Check whether --with-gmp was given. +if test "${with_gmp+set}" = set; then : + withval=$with_gmp; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS"; + given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS" +else + given_inc_path=inc_not_give_gmp; + given_lib_path=lib_not_give_gmp + +fi + + # Check for library and headers works + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmp in $given_inc_path, $given_lib_path" >&5 +$as_echo_n "checking for gmp in $given_inc_path, $given_lib_path... " >&6; } + # try to compile a file that includes a header of the library + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + gmp_found="yes" + + if test "x$given_inc_path" != "xinc_not_give_gmp"; then : + gmp_inc="-I$given_inc_path" + +fi + gmp_lib="-lgmp" + + if test "x$given_lib_path" != "xlib_not_give_gmp"; then : + gmp_ld="-L$given_lib_path" + +fi +else + if test "xrequired" = "xrequired"; then : + as_fn_error $? "gmp required but not found" "$LINENO" 5 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } +fi + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + # reset original CXXFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS; + LIBS=$OLD_LIBS + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + OLD_CXXFLAGS=$CXXFLAGS; + OLD_LDFLAGS=$LDFLAGS; + OLD_LIBS=$LIBS; + + LIBS="$LIBS -lisl"; + + # Get include path and lib path + +# Check whether --with-isl was given. +if test "${with_isl+set}" = set; then : + withval=$with_isl; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS"; + given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS" +else + given_inc_path=inc_not_give_isl; + given_lib_path=lib_not_give_isl + +fi + + # Check for library and headers works + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isl in $given_inc_path, $given_lib_path" >&5 +$as_echo_n "checking for isl in $given_inc_path, $given_lib_path... " >&6; } + # try to compile a file that includes a header of the library + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + isl_found="yes" + + if test "x$given_inc_path" != "xinc_not_give_isl"; then : + isl_inc="-I$given_inc_path" + +fi + isl_lib="-lisl" + + if test "x$given_lib_path" != "xlib_not_give_isl"; then : + isl_ld="-L$given_lib_path" + +fi +else + if test "xrequired" = "xrequired"; then : + as_fn_error $? "isl required but not found" "$LINENO" 5 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } +fi + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + # reset original CXXFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS; + LIBS=$OLD_LIBS + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +saved_CXXFLAGS=$CXXFLAGS +CXXFLAGS="$CXXFLAGS $gmp_inc $isl_inc" + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + OLD_CXXFLAGS=$CXXFLAGS; + OLD_LDFLAGS=$LDFLAGS; + OLD_LIBS=$LIBS; + + LIBS="$LIBS -lcloog-isl"; + + # Get include path and lib path + +# Check whether --with-cloog was given. +if test "${with_cloog+set}" = set; then : + withval=$with_cloog; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS"; + given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS" +else + given_inc_path=inc_not_give_cloog; + given_lib_path=lib_not_give_cloog + +fi + + # Check for library and headers works + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cloog in $given_inc_path, $given_lib_path" >&5 +$as_echo_n "checking for cloog in $given_inc_path, $given_lib_path... " >&6; } + # try to compile a file that includes a header of the library + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + cloog_found="yes" + + if test "x$given_inc_path" != "xinc_not_give_cloog"; then : + cloog_inc="-I$given_inc_path" + +fi + cloog_lib="-lcloog-isl" + + if test "x$given_lib_path" != "xlib_not_give_cloog"; then : + cloog_ld="-L$given_lib_path" + +fi +else + if test "xrequired" = "xrequired"; then : + as_fn_error $? "cloog required but not found" "$LINENO" 5 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } +fi + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + # reset original CXXFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS; + LIBS=$OLD_LIBS + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +CXXFLAGS=$saved_CXXFLAGS + + + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + OLD_CXXFLAGS=$CXXFLAGS; + OLD_LDFLAGS=$LDFLAGS; + OLD_LIBS=$LIBS; + + LIBS="$LIBS -lopenscop"; + + # Get include path and lib path + +# Check whether --with-openscop was given. +if test "${with_openscop+set}" = set; then : + withval=$with_openscop; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS"; + given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS" +else + given_inc_path=inc_not_give_openscop; + given_lib_path=lib_not_give_openscop + +fi + + # Check for library and headers works + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openscop in $given_inc_path, $given_lib_path" >&5 +$as_echo_n "checking for openscop in $given_inc_path, $given_lib_path... " >&6; } + # try to compile a file that includes a header of the library + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + openscop_found="yes" + + if test "x$given_inc_path" != "xinc_not_give_openscop"; then : + openscop_inc="-I$given_inc_path" + +fi + openscop_lib="-lopenscop" + + if test "x$given_lib_path" != "xlib_not_give_openscop"; then : + openscop_ld="-L$given_lib_path" + +fi +else + if test "x" = "xrequired"; then : + as_fn_error $? "openscop required but not found" "$LINENO" 5 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } +fi + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + # reset original CXXFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS; + LIBS=$OLD_LIBS + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +if test "x$openscop_found" = "xyes"; then : + +$as_echo "#define OPENSCOP_FOUND 1" >>confdefs.h + +fi + + + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + OLD_CXXFLAGS=$CXXFLAGS; + OLD_LDFLAGS=$LDFLAGS; + OLD_LIBS=$LIBS; + + LIBS="$LIBS -lscoplib"; + + # Get include path and lib path + +# Check whether --with-scoplib was given. +if test "${with_scoplib+set}" = set; then : + withval=$with_scoplib; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS"; + given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS" +else + given_inc_path=inc_not_give_scoplib; + given_lib_path=lib_not_give_scoplib + +fi + + # Check for library and headers works + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for scoplib in $given_inc_path, $given_lib_path" >&5 +$as_echo_n "checking for scoplib in $given_inc_path, $given_lib_path... " >&6; } + # try to compile a file that includes a header of the library + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +; + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + scoplib_found="yes" + + if test "x$given_inc_path" != "xinc_not_give_scoplib"; then : + scoplib_inc="-I$given_inc_path" + +fi + scoplib_lib="-lscoplib" + + if test "x$given_lib_path" != "xlib_not_give_scoplib"; then : + scoplib_ld="-L$given_lib_path" + +fi +else + if test "x" = "xrequired"; then : + as_fn_error $? "scoplib required but not found" "$LINENO" 5 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +$as_echo "not found" >&6; } +fi + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + # reset original CXXFLAGS + CXXFLAGS=$OLD_CXXFLAGS + LDFLAGS=$OLD_LDFLAGS; + LIBS=$OLD_LIBS + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +if test "x$scoplib_found" = "xyes"; then : + +$as_echo "#define SCOPLIB_FOUND 1" >>confdefs.h + +fi + +if test "x$scoplib_found" = "xyes"; then : + scoplib_rpath="-Wl,-rpath=$given_lib_path" +else + scoplib_rpath="" +fi + + + + +ac_config_headers="$ac_config_headers include/polly/Config/config.h" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by Polly $as_me 0.01, which was +generated by GNU Autoconf 2.67. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +Polly config.status 0.01 +configured by $0, generated by GNU Autoconf 2.67, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +llvm_src="${LLVM_SRC}" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "setup") CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;; + "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;; + "Makefile.common") CONFIG_FILES="$CONFIG_FILES Makefile.common" ;; + "include/polly/Config/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/polly/Config/config.h" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/tools/polly/docs/index.html b/tools/polly/docs/index.html new file mode 100644 index 00000000000..d2e67863177 --- /dev/null +++ b/tools/polly/docs/index.html @@ -0,0 +1,6 @@ + + +

SAMPLE PROJECT DOCUMENTATION

+

This is just a placeholder

+ + diff --git a/tools/polly/docs/polly.png b/tools/polly/docs/polly.png new file mode 100644 index 0000000000000000000000000000000000000000..fedec561dc2a4a59832ab9a4aea050fd0db433a1 GIT binary patch literal 15526 zcmeAS@N?(olHy`uVBq!ia0y~yV4TFj!0?`fje&vThG$S90|NtFlDE4H!+#K5uy^@n z1_lKNPZ!6KiaBrZme&M-{l)&lf0A0}F7~_Cn{I7t_nDc>FKKkNHEL?LtH|E#tK)WB ztcza%+R9PiIZ)C_)a6^7Q*@d7-Rkuwmiz6q&g(aB@h#rx>38e-->R>vljhkxpB?e( zNzL)kQwwB{Hwq|e{rCMT*ekX5fkm;>vBUQ-b~|=+WL_<^&feZ2P_+E~yTS_Q zB<`!#m?*G$a@20d76GRmX;mR74#lPbCB+s2B@Qf{8@w~V*sfaDdOqA-eP#$#s}tMO zAhxAWY^^a|Q}@c++0pa&s zcKuRY+&BHC3I}(QV@Zp2m0RV5b^rFgxOO*@MTW zo*7w}qIP?>2qXz>OuVx!aP2|%__!ly*vpg+m)^K_RNvKR9$TBJ*fL>Vn^33VH~F2dKl|S;ZLDzOFl-R& zoVafJ)W`ewzgeDns70Vi+Dk=t!qni_RR6c`nU#CD&UWHZT;$lfq&dh~>%)Ol%x>5J zDz!{F*C*7;x$cg}Vf*`*xo^`1oH{fNw2e%&R@mFzeH+<&`SOJoj+L&;T3XTpaW@-2 zopQT!C2ISZzt?OtCGK2jFJ9&ru~oK3ASw5ZkmsRVLkWTBXSHH>&ziNxV}EGp<<3@% z;)M+9dSZ)K9NEPDF#Dc$bDd!v2Y=zl7nPifEBqL?XR(hp6UH5 zcg^jr+5?^cWLDqzQ+v9};TLja&O) z;f)+u3FFPHHws|YRFxjXypX6FshZYrjA*4wU?Iez}xOjR?*mX65jo+`Rx zXL=4bb63q${q{@##i|y8OJ7TNx-c=Ex4S1_&if%%?)!(8F(DzQM*ZF#ib>a0g*$z; z4zg#vDIGZ9nHkgDc3A#+@r+|CEdm=~PwHf0xDzwA;`!2tXCBL0RCQPSIB^JW)|>6Y zu%Ld8_-DO!ht-QOuDE8<>j^SysW2ylicWW`)cS4fI8TOq&jgub`1(_4N=Ci>m+p^A zQpPW{I4@VU2q>k++D&9Qko^6qLGSdERv}KsC9fB_FeN-muwU`!W@z_Lm(CV}ORXiZ zqN0y&+B|tte2@6%sV`^VoVp_a!htx=WTEp>U0$z1Npj7cED^Emi?;3KEG_l@Q!jlr zYQ>bYfR%3+Y?^-1F_m52o%K(xjG)YemIn;!7M7>h{x#xIOmpje;_v+Hr-8SM4Eq!D zYY|I&Y_%;bub!RVqAK>_(p8~5r&gwI(%;)Y+t#Uhj-kRi>E_>6$qsYORmGjGB)wGX zrS9~^^u>7ly3Xu^iLa#>)HI~>O15)_C}ryj*9EQ^r>o&zt$mf=^%y4UKfl{ z$tt(~NDiy9c&q2>6EVE1TeiSXte3nz^XO!lo^-~{h&YvuJ`?B!n zM~4k_oiy&mP8G}N-x%vP)mm@v4-N)(jlSl|{7R3XZO)v+>$!Um?{vRE?g2cVE^Qy~ zZI;rQ_{URkx{}5L&g;RaXC5)WZe9~ScXvn!|NdPq!p}dgy(?nt8SXWqWGPF2U6I`P zb3KO^dsiJk9h~|$O;Gy56Df}U6LwFSUKtZGXZA_^vXd^8X8oD`K;mEG;s;NpLi{&x zE7`Go!*4g8X^(oJPwoO06%jvvtY74pR{M?Om zcAC7sQfq!c)H-(de%t@QCA@Ps#BpCb$?EFY5cE{fg0DOO`8E~PpY8_@-^khs3K+66 zs0!KUt>a4DC?&NfJU{!seB_KhPsHEcnV-1Tj3YGsev9e*xd$(a?pM@ae(Kg)MJ3g# zCk5|iPkUhTa{Bh>%VoV%m9v(yrNrD-weX8rKXZcDY2UiZ&bFSg4fzWj&MT#1|UtQ_L@)ip!ii z^D28^TJp)R_`r~?pQeh}3Z8`My{pZcAA0S8z(=mmc{&w=3&U==d^vqva;wLjpy0Z; z3#H~|MWRksK3A)IggW~^b+M&w4EgqK{pQj?IdcC#JxaV1U6^oRDsRd3$N!e|Eoe%7 zq`vK}-#Vv=^Dmnom%MwY%a?i5p1V&-MwEZ&p}_ZsUMg0nv~Q{kEuG12rnXE(`QcCJ zfYn>mZ2Kebdgvc_J}={tJGXRsr0~ZC!xwRJMa-%{r%P;ctNFCqZ_zFz_W~K`_r|J1 zvO2<@mbn{q#Da;;X%@R^%K}Udwc{dLF9*A=erI}-10@#v8hYk0u$+^oN}FzCQhPsSf6_W74)Brr6% z9ex-Sr1(vKU+es`<%?F`sxe->?Vac033YZm(!E-4o^#A`jyNxAQUAl&WTo%?o{OIr zN?$8xJ3K8i{MXgF7fd*#qp!s*DBO1NexTCN;3O}@%X&ig^2fjNzgm!Q7Ju;l@l7+2 z=Ne{p*vmy-;V$R>AS&anHaVdnUY_UO>*nRtz8~$k&VRJpclyNejCre0tlv}3R=9VU zqS2MBIv+c8Cuq+Vlo9RUa{4yQQBU808-rDa)L5mQ-47f*dHliqjGia{%k@Q!dXN9= zdUENh(4Mb1S(h0`v#?t{?%sav!Rhj2MxILBivw;x+*fJ4q5LtA&88jZZ{FPafAi{9 z^N0HXE$%!$-pe5%S-$>(#Lvj(GkAQu8CP?%2yQHn{wu3G$$qY%PJ)=X5@XHYo3Rr! zOl1E3JH}~Zx^e!(tto!xZ+_)Tx!o5%VDs&5$hWczwT1HA>Wz=;NJrg0v*LjI>&Y{Z zt8P1Loxl)dbBNXLq1D-t2O(^e*{5igv$*wSfBinigJH$hC>1qv!)|e*7l%sre|ulI ztL=4WPWal}+Nl+oz@v%`&vWE$L?%~{eQncJAER-;+kttut@W# zPnnw0iX|WCZ7q!Ay|n&~fQ&urdv zMz|*`MfPSU`^+h|7j-XWaHt9~%&$GZ&01wzqEhAS%b$JHZ7i)$e7tI%d~tiZd77cG z>O=Py3|LozV)NQS|lBzd&s;rb0y|K-_*HedK!{*74KARt30IJ+)==>?Zn(!>#J-@!J z(d_7}M-gjE_LqJ(S5v*dcHzEl5|%I9S&nyRJkMfT;L>z{Uuw1KqD|YK-@lXdNvhrW z(daV&Vex-f0?ogwHglioaAEqB{WaiASK8-&j1Ez0s(dm_S5I1ZM!&>jPE3ohQszCD zEcL}=kzrA%%nr^jJ^AL1;I-ta-N#E`x)j;1DiRfd&1H2z z>bx$eI?(7stFULKD|6Ud%VRe0eoSoic~tZHuV~uk+P}3jA3t4go_WM*xr4p>o-LDN zt%ZZT3e_gQ{iTo;t(5f4NlEbA(RE7{B%dDLw$(X3@EvQ&lx19f!jjoLR8GC!m7;Vp z!}8D9rOGExu1=E*SDTt}#^7P+l4W7N@5}F`Tv(L0-o{vhPwTcul0mJLh8yq4bg}oR zdrLwuO|`W6dB8qr$pedR+m@-Ax>i)rjcI-$Y;t5p^6nI+%GZ-WTNLWeue>AZ{AXs# z**CwHxlOm`q-FWa%4bbH+NQJj)0u=7Z*HpWJFH$D7<0?=+j{k7ohciZsr>y^ma%nP zpy@)-*!DB4cY}(qo$SZ*zTSE&bn@9-^ABI2X{UA8-j6ZMR;v4{+w3Vb)2C^<{L9lS z(^Of1SSEh7%{f+V62-ThKgFQaH77XXhr|k**0UjN)@!?#y?Wmhl@b?e{>|~O#+vP} zN)we9eYbU!zn?198MXH4>HPV}yz}Q8dH?w!Al@UPv&VbcjxBQPlCipXja8W({~g*U zzjfNv?rP)LeYZbK@Al+A^37w(Cj0%d+{xP6UJ)gSf41_pH*cPQ@pyTsOHe>a_fh|U zUB0)^m?vy2$>aCv+0B)6`5m+5g^bqoKeuk4{ODuq#zWF6s_)i$>CC;|?77B!y7z>s z&Z)t>Hg(LXG}tzKnd#1#?g8P4*G-vZ84`ZS>EPPSO^>&1d+(8LRjPC`%kquggw9C* zcWy~u8*iQye(<_uXYkE8ts8%T_facU>)~-~(ElCuZCc6wJMSi(lt@Wu*!^vDWqfCD zQ5knz{)R&4<7*#UoSpx5`;pZ@vs`Y72e$6jW>U5e6I~FjCbTuGTfXehktMFyAFiBs z4+u)TcktR(|1asA%0MZjd-_e4J=N)MMxDvNar3m)Ha}o^aAT&8T4BfAB*PcylFX*; zESMvX~ zw0mpQpScCs86N*OKlYT5(N5c{SH^VeSH}jST5R+-K{a7FxH)v`r7= zOA_n9s`Xn^`0$LL>m3JADE|BKDPZA>kQ?I7Zd=*JCv_QI;gK#Eysa=^mH0cO8=yrg{~8-@uS_Q?sV=S?A}UQ#^L6Xp2=^Ryjo(b*N$VqxKi%l(YNrce)=f-u+Bso+q+wTEl}^}OxrcxEwxm6-5nia znd7H}TkqYyId!9W^G0Q+nJSZldtR>+y#4r@WNThsZQz{g8AUv$$-GAE-@m+I#a-;Z zf0wY7@8Sg#M%JoM)qdtLcg`)^aQDt3=a>(#ipvdqE1$YaZsA$>w@*^;LgucmQ9SZb zj;9T@w&Y2z%rLhj*kEQBL4rYu(0O5UHi7o z{PNA5rPeF@`6pW>C9R*LxNiA}-W{)A%`VWMer<9|sp8$`PU{5BO!pc5)>(CGv&2@9 z8JiYmYv>BZ1)rPZ_)Tnzht+}ew;Au(8OYhi@tsMI_g|eLGHjcE-~{&pinT7A~kcRIHoJ`rNrFL1d!Qe&corpX1#`*jwKjCId6Ee}0nK6m)6 zoMPkK_p%AyzYM%4m`kYUB;Af!qY3J^$Q(~w%^sX-nzbbUrlN&k1v{6ClvC#s4(0YA zkB{rC&;IH>%k_F#%=&YtC)Tab&o{fx9G`xr)gx#2^87WPmt#t=hCNl*|E#fCY^Iv^ z+j5gDoU@l)zR1+u7NC@Q9Mu2+y#3gLqn&rp)o$0;T%Oyt6WNCb?A?U zj&nChuXc@?kZJ5y61nOTqu~AxamEUpg|~gvwf@Q=^?L2+r%TrD64)tuXnn^l?kFzj z&L?JNWkEJ&@jP`u%cR=AZ9l`aVv$f-r^^rawKFzW)TWB^`kcBTaC>>cE(Hs%xB#Bs zWfMS zjo-v{)_H7+;ycQ8dhLXB%|~Ymi7oZ?IhdsD9nqgDt9K!z)r0`tv+;kxq0)o zl7%jhUML)2u%FyWuw zi_5E}H{bmhk)0u6mcYg!m*>T%D`@UtZnl2o!h^r2F7B+jVO^nQkR-Dy?~SpgoA=kd z6W#?&Y&)~zO!n@JOV){sEZ(`~ACH^vrimc47X+MGFu{9az=;JRCl+kl-n@LbP~1GN zipo_F?w)0|yBos6UFMiFLtCWi_RRw;76w)*6_%O&H&@IqE=&6?B`vjfx75rI|CBp6 zj-4zS@A5XeC?#(6PEL4Iq4DPCTI=L#9%i*hg3OQhM7F*Tiinwb;_2Larg?Yz&SvMN zOxWT1{E@g3Q=i_y6)Vq}TDrwOGrSV^^zgx(HP!b*rlv14_`T+Vh0gA+472`ebLp(} z5Q$Zos3GBdGVNpCCe95iP{A8B9f*M+dhpNwt{jth- z?{s02x_apMo5<4N9kSheHe&D1U)IRX`TIcJ$|;~{)h8d3l=*2_lxiy_-28-gRtw|A~z=e3xA;>E%DJ#`e_rh*foeM107by-mq8vcJ2CX}_p#Za;9+bb@2{ zmp~;!MzN<6SA6H%Pb`qRaO6R0)TTeY8+986lM~-7Y?kc)25aG`xUq*PFYpx(!3K94`L~aYn$36i7m$ryi}APywTb7t03G% zWlfjvE(5KtPFCw5tf)As>T*dhUwF^Qkk7{=_j7bHG6?Ry>HqVpYo`m#9?3V#hZZ$$ zxG{Cw=E~kR-%J(fPCw(Pxno6Qtgm3vWq$6iiM7T1AFQoeYGiq+>a2*!;=9E&Osx#N z#G73fg=Gf@UOlnE^wH5*T`fm{`&#W^Vev5At7YBagpF#d21zngw8{?_-g4@6VTq{S zaQD>OG$HpjMw?g9II_^ispsJ}U8#Bd3Y(IiERl1mja}(^e(l;*?s3ly9iOw`5YI4a z5$fdF@GIf;p3svjeG#b!6}9L5if(9UZkQ|K{vxy!GTPuVv>c`&LHBwThC$t6P%9KsNbCPwd(ke&Hv>=XELjWmSbhT8|exC@toX*|>8;&=D2B*ogwc9DB7gb5xj!d4x<~-fEdPef>J{ zSXcA@)4ujSyQC76=LD^sdz0Hl%4Yr1^Bz&AQ!bi6OHThZVe)m$S9yOoJXW)Kc-mb+ z_8nh&cw+O?7MCM;m^(vmSVU(xzjNZYVRCRdB5`B24a@PD8eS?&kM8;&O$ie`&KO;` z%qU}Gsi|q^$Io(R>yvLdyt<}z=%#gvbHb4bN5j0kKX_lU{VlTpTDtUvr>%yDUcyXB z!kXE+_~sgyzlGO*S6tn;xBvJ0_WXrArue@6@ng5{=0np<>YT1m$(Z$OVqNL-d&w`S zZ+BiTx^3!~QzxbWB`#(;Y9OjAG;yY#;uOz0haOqw+^n4Jsgr#n%d%$Ey5z5&QNjT{LLb*omzHI{{H-CUo@sw!kB@Z;?99~-_*3*abxGEG~)5dp$Ux2!8rrc;v`MN1vq7(A68C?KSpEiga=-6SYe- zF=JxjzjJ$Xq>fXG>oHF0lJ)C#51y>8cTaBKpzmAMs_e8#ox4kM%G}WNeoSoXDAC=Y#w|)euZOplPD1QF-GT}9O zh2K|JR9;wo<}sUFPxIbp^;g-x@dmRiYx^IRwUo?H0<}3Wh<17${q`j#$Y|-&`|(o=MuY<+p>{zMD0zkv8GttncOup45?3Y};_dHjpE{pQGaE_sv<-3|=aW z%!)efFMs9FoH^B_;vfH&tK88)j@;U4Tv_q%>SLc|z4$xQTGg+1sy=)ANRI3M0mm@w z{Y$^4DWw*B4Gxx8v zJ7Kf(@8gw?6HdSMpB>@m@kK>r%C!5H#s)P!Z)A5x{@K%ZVZWL5hcC*t4__@xkotUQ zsneOdjP0S{Dz0Z(?)iApa?PLTfzLcs{+v+gk$QCAL`^Yw;?0}NYo3>M&kxrD52nw4 z@NCtQVt<|lx$O&9h;`5VA(~%bbuj6%+R1QlgZ~%z{+RXfKoz&TyJg&u*ACALIWzrJ z?(7w_oqy^gH)CRX^p`og3tf_wpZWD32r*vMnUQtr(Pv)Gj`%Iix4$i0xbmcpXmc@l z)`v^c%MHFy-0QJRsb;a3b6jnm22+jfS)thzw(Y3?+OXWe=jb`{YuU>l)CNW@a!GQ& zwoa~Tf*3lfIB8 z`6ej!z@wWN7sVHNTA6#tO^wLDKk?dyKOWMcmN0v^ThhP9zt4nS-M(Q5-}~B$9pCr+ zxSZGEzf&8|@auS`qR|!6e|EX`x5Lv^A4V}S$oPZS0<7NZaemd2ty_v@Z0B}6s}}`E z<^5y)d+(y$kK6G#%Kr*p5?pAz?BN~x^$R_7@7*ek`}g_g1 ze=hRNo~@<6J7xwZUM${r^lD^d{yph-g?jaD^Hu?dv)Nu}W_rANqSf+kM%K0;%N7|5 zNq;@iG|wXxl5j51-z%o1fR%d^BJ0!ixluYL}$LVS4Yo zmlp4i-YqG%JmkcOm(q(bZr^SpmMpmF^c?NGM*|jI6!20pdv|m>TjJHlwY$%RZMtjo z=Hvc;wS*fEiPdSsNqUKU(;U^3cQ;7<*t{;h!9soN1qn~}4=*lBw6N?-_0?){dhk+dDoGsiN)XZwv`EYbWYJSXL0pS+4Om#o+00+?F+Og`6XSNk&yEvL#bxZ zk?ZxR4&6P>wBhIFA9@pAI^HJ7#>FX3RNV93)+c$BOXm{d&bKc+WAFPOesl8CtYp2G z$%|#O!}*Us&+luTy!g(ovx-MF_8oM7@J8&6&b;~?8Y^UO=4u|4Qk~>??5JmB{eAPb_1oLuAj`?Boz`M3Srmb~uj*xBxBt5ePH&*IXPctPp&#O_z|XJu zrc>W6=Gd{d*Il<;FIxA2A>F31UMKBHyW_C}V|}MJ2k#ve_Nq3&a-B;%Na|X)+LEBc z`jGD3r7fKN=G8XeUFvQ2tPtOKzmWO%w%cAx%bTbXo+=$Gz~ zPWvVFLBrEAJ0sgJi*psIZ4^k?7hSYxQRB~_PRw%+SIp;U`~LOdgE~8tZ;n=5kF|NF zESD3IQJ?g%VXtN2^)PYusa_YXZ!zy(Z2RHBUfY9(4rOtsMtPx1+S{cfZ-$;YwbCik zQ#R}Mtbp+AEw_F>`@d@TmJQ*j9xT|@eCi&b)>PR!GEY8yFLWtrFm_^^UGLO9=i$S& z{I}D+I*vjbiyQP)KvQlm5#Z$N((l5=^3yudHP(s6!&~s)T2b&+npqo<#zcXnwEcR2 z?%eX-u0Y7Z>s)xx^p_nNLv6ma5jUdgl0ZO&b%2f`K| zj@dfRLY#^%28Rlzmc-suv+yf!bh|y1%fGWlz)9ldX^Xa9ubdnWXK|aHOS__UdVz}* zhhoo$7uP;<%kr_S%d@TBDC4ElB5=sTIaYF0{yTA*<8!QaW^tpaz8;I@%si$LS1VE#p`Y`hC(qTgI&(wHdV z)R7Q=u2$KiZF+tEjw%;}jNYe#pfyB{UR;v`3tmroU=djO-6*5CGyp6*$*)GmqHXV~ z!)f4#N{fJ#Pe{~+o;O$SvmWp4naw}b=ima@YmOjq`INl7u%Gq#1dr5?cbhvLv)6!K zHACU`uQ;`2<%5AA3ktraUQl|y5ae0eD-rRH#{2(wd#<_HJk7W>*>~IaPptynJHOxQ zzLv)%sLH4Q?JsYsscVxmXtcS#|80J`U${z(z$Hd;zWu$?JXu+c4(|{48+9h-XCcEz$3gc?0i#~zC3Z-rY*ZuIv{e^F_T^OFElFH`BJ1V&jN*()!IjUT%IhG&-`w&b{prb zHZK#CkVOl(v8b|YW~^Cn;5}PKNb*;2)iIroYr(5BE^D3hJ+f5z|Hd-oFD~CB8Oqno zUCUz&Hp%W5aMC#v_q5UO@cd0>#xoX!0zu5E;0$-bjoneZCC`A|DZtIqIj`r!JWv|j z3{Dei&mO$#KKM9(W0~=pHc%wbn0V%#T>1GwEM8M*Z=IcFHpPQO@raL#kY<~26|z9T|9luccTO-SPnHfy=>a29Im+Qyi>OM(MO<==wMhkZ{mx4`J9KU&$i8tNqze) zf)$h=Un;0ySEyj;afnzS`GH$9?d`J&S&;b7-nlWXt$Vend|MZw5xa0hdE@42j$J>$ zH@#(Tqf-5dZ!{yGm2j|2N^e=D@@-Ers69fQ(WSFGze5>H^;B!;$rvh(y!NUzjvwn zT!)~tPu679&brmHTcdgp9dZ&86H_uY6r5lCO)@Dt`QzK|_ZQ{g-xro0o|2+c_U=yQ z@y9})N4VB1&K3PTcjMNAhfaUq*Z*f`m@<8O^8bH-XBee=wI|K7D&>ldjQsQ0wOed! z)tiaR?i1$D?LBbdKv@6H4T;X}=k(ncy}DIYTH4y*-+!-v^5o01$5mBTAFkW|?$E=- z?Q1W1Id!a^Wst~ZV{7~Kcl5TLmjylY^?xSrUmK!Tc;5E=mMWd&g*Ucj2Cv?~zvwBK zUfiA=56wDyR|uU(?K*{eGwU)2AZsZ8HRt zyq^?VK07=6`2G9)YOSwim9{7S`EuF+&s)vlWe2Waz51Y#kB^Vx*1ks>Kj(TaeH9>m z#4V(AiRrp^>t-0Ga(#Puw|jbg-OTzuOO~*_-}`-@XtW#0MpJHay(jt8r%ru%ppn_l z{`;Ms#UB3t<`S>Vbd5RmcP+zP2{HeWr1`l7)qY*HWRPoih9O?UOK0Eyx zhLQ&d8r_cC*Zr}OtA1m60R5WB0Sv-<1R@Sn%s`sMDX-RYG!|8%@h z!mz2n=JT_&bG(*jeT`ve^?KYogW_`@0>JAXz{)FYcoETr*S?$ z*8BLjY3Zwwi^po8%}oDMF>l_yIZaM|46e}8`)*8Qol zd+oh6h)3Q|hLe-?$LaWgO`5^WKGaU$x^-*CqfYe?zh1AOz4dJykAwk3GaK)t_w|3j zUU#!EKitN9A;W~B;lYChpE(vA&pw_zckagr&HPEfzrAH>*s;Un%q&yx{XdIsd3R6U|NiOIp-HOV8;YKK=|pZ~`SfFLvkGQ&oN1 z_n3=|YlmU-u@A>Rmj=E2^769Uezh4td_TTkzyI0%=Z_v8x_ae`#MeDLc3AwYT)*d2 z*TLkH^&W2ha%UMIJbLtK2e-K13)%3nuw%ZnOg!J4%GlNHxLO<@7FN{Q*!XAT-QDHS z&&{zcK3@3q=g+G58=IS%r_Y;rFYAtR`neZd6W`t0S-wZUx3~9BxBk8pj1P8|zE1lh z>RDTBt3K81=i|+rHtn#h{q^Dda{u|~{(d;j9}^TLRQ~joD9D+2w&mX5(JO7fO{)0% zy4b3>v3sk&%HA(9mE!&WY_$yt_PcM_3h15;q^;v;O%;sa>Ay+aLS|u79sB=3{r4WZaOKLC zXCG~=zC7sn_wX>N=*d&Etp27G9vXVo(!!#E!9rhO|DVk1X}XX1??_8eFAiT9v+<=% zQgLkb)vH%;?5Q-auRk-xuv}(w*y@dWcdh=_IXN*oIXOl3zI^khCw+eHwEg?b-^YoF ziEYZVhJD@$2f*^OyurT+bUc6Ro~3l|EG7fSWA?Jj@+?7g~* z$`(u0Pe;Y$bH0|Z{rK_Y!~Flx?f)}gxZ`@`o=fXBov1Aw@ArJ>3tJ!8yZ`Uo{9HY; zE3s4So}H1Le9ryGg}1Y`^z@D$Y-W$PHM6vo3|}8-`s2>E0vUF7b@ekd44D}MLPA<5 ztNS~xzWS-#$GuOcv!Q_@IKC<4Mu<}2>Z?2c|N9*n5^}`;+l}P@yM=dNUS9q+jYBtL z!-Bgvc6E1ciPHV|<1v3?uW94EY|EM-20_8W(YD)GuI!v|#ldiTy1w}$o?p9u-MV8hFE4*@@$A;tYzuWt@6S#OCjp%Rj#F|KI!j-R|{g zlbf5Ge%xNWcl!~eMT-|3CLCb+R~Nl`dr7^xh{%c|cGQ(}K65 zAGaM*6Y?xAHLd&iGo44)>Pz2Ihc>q9=jU1wk2^Sze_eR*|t_1zu240{&_Xnc9MK5FYK=kwxD z-|u|=`c=$Y-_Ym#sifD}*8Vv%_4Z4@-?1AK9NWFF965gc^MAX#-*3(T{Cd5fVV1c2 zxw+QYr=)fFt;ot<8?lk;y#4<@_ma16-KwFf*%-F^YV{uf`F3m1{X2Q$#Do0ywzh4* z58hPL(c!VQv}9;FbLI@+mN|1`~Or$R)r3g@lGCo}8rWHh2HizpM+)nU7s~zjyE6_dhO}t5{gvSWztf=>7Zt zh0g7>{?x=yojUc#jzZ;cZ*R9xnIiJ!>C=VFmbIm&ciw1X<=#;BH7jFll!&P4!wU!&x^`tq*HZ84j~4ga8AY^nH^g1{aR2B2vaE8(ri#AS$jxa7uU{Ac`Sa(AbLWoj ztNr~&%#6{&)s?mE%?-u{JELDdY?n8)vRfU*v+I3fYU)zY*5_JUTJI{>?AkSJ|5|I= zow~>5(oZ}%*z8-kZr%HRzxlMo*FD*-(~--;!ExZkMCHO47Ze%J#zt&c7rL9bR?fBx z)S#EOJ3mR)`@_rS^B1jL*|~o0)r&1EX^Xs6+D@bxRa8}hT7i#`^&Wn7wEOnkQx|l3 zb*G>1wVVEKqwL!Khr43*jvwZ?@7bDtohd`EWWVjiKOYYB*K9v=V`H+QoLt_=GBZ2XWcyim1-@j-7xg+-a`ugL4zu#Z~{l<#G#RfSy3|LrLKD^Fo zc&2xG8e^RjAE-GieDd1b=#L+d%fJ50^r9?#=C6nLIX4ViT3bJ6-;$A)H7tJS!?;#V zJWzF#?`$(k(~R44clj6esj%El?)@uZ-0m({$+CX`KPwX{-m*708YfK>+H1&hH*alU zOz(yzAzD9gZ``=?%&{pYkEM2pySR&~+&g#k=FKP1na+l%X@{+O@V>gTGV%4bwGwtU zI}ScBe|N{T(7u=3bKJ#GXP8L?ykJTzBW@fKSrI#*W{yBPeRaI5e zw>LM#G8a#uE?z%7l{M{deN5ZB2%d|7|EFbw+6k*xt@`o%^|iIxrkxB17EfnJOmA;* zzqds8uC~D4leWz4d@d;|OHMwo{PD2;;~{SS2d(098(y&Rd%u{{>9T#by0Y@)zQ$kI zmMmTRal5jT(v0n^m4$?ae%#(QnJdcdDPzO$cf0-HOYc#AxzGOQ&6`c@xJq97v1w>& z8NFJyWNqf9XJy~sME)!D@bK6@Tjga~pX#H9w^OeM*>Nz`{d_9ke0+wIiHS(|^>s%< z&EsXV5H#c;-j|wvz&xPo{cdqfJ>hAmhulnD%&6_s| zR_o559HMn}alhTE`~Sb)&M$m&Lh#@1?;jo>?u|-L)Vp}`;){EGt?U1v*57aPs!}_A z-I43@^>?$LHq5iFepQlN_79&Kfm^J>yZAv}uvN8E)Gr!#l{$KewHaM=2K7C{An`cXI|J{~*+iY(hgY&iZ@%`WL*UR(U zei7JJ{ywk3abD2MBR@Vq{`q@;-LK5mos0JElhfb(Wm4zbbm#3~{ECW-R^MI0%gbBw zVqyCiwZaS&DJf$?!MlwmcUzmc|L?oAGFVNBp#s$GUp;BoEGeIPHj(*POS;#r(easS z)Eck)?%~74pucLxA3lA06u$4-lP4d(9*&8P{kn~N>$Kx?)jsR3(;psctvb2RH8xiE zUd3bHy-&7hUDeu~xp7yCa7bC1*|T$VtB?O$^yW>@nK_oiot>Rk&9|q;{aL>InS#Cj z{RGpdOP7Mq%(Im~-YpjM5V@2r-#Hny0(RicK5h7y)VDoM%73$JDs{`{0GV_DQP|J&*SjSYp5 z-72c9w@ZDW>~D8bTkFQO=ku!9U47JXzyAN;z{~$Zy~2IV!o01;b)$}ae;zeCXyuV< zy3qzzUoxglpT2n6GB)q&dPi5U-`ACRxXp2C(8FtMqb*8aOt|;xFsHEEoxp<*;Wafj z%lzhc#qKU+WT^Z5HJpWwE$PLDg&#hAaLCKk1C6!xx-~yM+@5@MQ>sPT8wm!p*U?r< zkB)S9bapxx6&W==`yVf^A9rL$;Nk@rGYa0_v0M|qozKUc38Nuv~w{qqh>6^e4PK07nBdHud$T&1O@ zJ4#=RHJsbZbT?;BSj7zEy*)MVGPYGyxH&m5TK6xUzhHsFy9WoG-yW;}a?$;EZ|WKU z$jF%&*Dox8f3NDiZT-KR_Iu2CjXu@?eI0+>_FuRDz6bsN9UU3pe@vMovbQ!c>i5Kx zDR;U=wRimb^{Xs7EF`30v0HDJaol{n+8s?zOnH}=`Tj|M`!?l7p^Uh^{CWBRcZ$z% zt*)t_G-;BBy!?E#+q-Ih7S;Xl3SAv`_v7!|_tUfg%-y&k`rY2e_ReiQ8!PVImbEB& z(D!`%R`IiMOHQAVzBPNfX^30glQw?&zSZIDAD!0Uf8@%_;D_(u^IKb6pLklt!orep zYfI*jN8S1bZ*Q5_2~N796T555e%pit43oV~W(2Q~+gtGOPi4-{O{|}vpLdUlkeK47 zx+F*wG<215LE+Ea{QARNv#)=6*e)++ntJo-QC4<-xg)zuUmFxYa{2M&hr_}E&W7Uiq5-MtHNmo~ezPPxUJw!`Xgp1Y5$!SBzMI{-l z5{~)x|19@2{oi^$?r{A7U*RC*w5A@qdp9=!xm%KL`Tg4M_e4tA+1txjrwTh9Dhvtq zd-Lr4{PWj;|9r8y|HBbs|A?KgEdqyb`*pfJ>FVwl6cA`QcFavZe*|V{7}^%iH^{2p8+~ z_wVl;Bp>VfWSV{L$?jddq{7+f3pnZIzxvO3-F?;B*-xzX7#J8BJYD@<);T3K0RXb9 BNSXiu literal 0 HcmV?d00001 diff --git a/tools/polly/docs/polly.svg b/tools/polly/docs/polly.svg new file mode 100644 index 00000000000..7326ae505ce --- /dev/null +++ b/tools/polly/docs/polly.svg @@ -0,0 +1,149 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + Po + L + y + L + + Polyhedral LLVM + + + diff --git a/tools/polly/include/CMakeLists.txt b/tools/polly/include/CMakeLists.txt new file mode 100644 index 00000000000..abe73d1f16b --- /dev/null +++ b/tools/polly/include/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(polly) diff --git a/tools/polly/include/polly/CMakeLists.txt b/tools/polly/include/polly/CMakeLists.txt new file mode 100644 index 00000000000..ef9216317b8 --- /dev/null +++ b/tools/polly/include/polly/CMakeLists.txt @@ -0,0 +1,9 @@ +if( MSVC_IDE OR XCODE ) + # Creates a dummy target containing all headers for the benefit of + # Visual Studio users. + file(GLOB_RECURSE headers *.h) + add_library(polly_headers_do_not_build EXCLUDE_FROM_ALL + # We need at least one source file: + ${POLLY_SOURCE_DIR}/lib/Support/GICHelper.cpp + ${headers}) +endif() diff --git a/tools/polly/include/polly/Cloog.h b/tools/polly/include/polly/Cloog.h new file mode 100644 index 00000000000..ffd6c8f2d87 --- /dev/null +++ b/tools/polly/include/polly/Cloog.h @@ -0,0 +1,69 @@ +//===- CLooG.h - CLooG interface --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// CLooG[1] interface. +// +// The CLooG interface takes a Scop and generates a CLooG AST (clast). This +// clast can either be returned directly or it can be pretty printed to stdout. +// +// A typical clast output looks like this: +// +// for (c2 = max(0, ceild(n + m, 2); c2 <= min(511, floord(5 * n, 3)); c2++) { +// bb2(c2); +// } +// +// [1] http://www.cloog.org/ - The Chunky Loop Generator +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_CLOOG_H +#define POLLY_CLOOG_H +#include "polly/ScopPass.h" + +#define CLOOG_INT_GMP 1 +#include "cloog/cloog.h" + +struct clast_name; +namespace llvm { + class raw_ostream; +} + +namespace polly { + class Scop; + class Cloog; + + class CloogInfo : public ScopPass { + Cloog *C; + Scop *scop; + + public: + static char ID; + CloogInfo() : ScopPass(ID), C(0) {} + + /// Write a .cloog input file + void dump(FILE *F); + + /// Print a source code representation of the program. + void pprint(llvm::raw_ostream &OS); + + /// Create the CLooG AST from this program. + const struct clast_root *getClast(); + + bool runOnScop(Scop &S); + void printScop(llvm::raw_ostream &OS) const; + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual void releaseMemory(); + }; +} + +namespace llvm { + class PassRegistry; + void initializeCloogInfoPass(llvm::PassRegistry&); +} +#endif /* POLLY_CLOOG_H */ diff --git a/tools/polly/include/polly/CodeGeneration.h b/tools/polly/include/polly/CodeGeneration.h new file mode 100644 index 00000000000..56691437939 --- /dev/null +++ b/tools/polly/include/polly/CodeGeneration.h @@ -0,0 +1,20 @@ +//===------ polly/CodeGeneration.h - The Polly code generator *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_CODEGENERATION_H +#define POLLY_CODEGENERATION_H + +namespace polly { + extern bool EnablePollyVector; +} + +#endif + diff --git a/tools/polly/include/polly/Config/config.h.cmake b/tools/polly/include/polly/Config/config.h.cmake new file mode 100755 index 00000000000..cba91af8a4c --- /dev/null +++ b/tools/polly/include/polly/Config/config.h.cmake @@ -0,0 +1,19 @@ +//===- polly/Config.h ------------ Configuration of Polly -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Configuration of Polly. +// +//===----------------------------------------------------------------------===// +#ifndef POLLY_CONFIG_H +#define POLLY_CONFIG_H + +#cmakedefine OPENSCOP_FOUND +#cmakedefine SCOPLIB_FOUND + +#endif diff --git a/tools/polly/include/polly/Config/config.h.in b/tools/polly/include/polly/Config/config.h.in new file mode 100644 index 00000000000..bca1dd88a6d --- /dev/null +++ b/tools/polly/include/polly/Config/config.h.in @@ -0,0 +1,28 @@ +/* include/polly/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */ + +/* Use gmp for isl */ +#undef CLOOG_INT_GMP + +/* Define if openscop found */ +#undef OPENSCOP_FOUND + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define if scoplib found */ +#undef SCOPLIB_FOUND diff --git a/tools/polly/include/polly/Dependences.h b/tools/polly/include/polly/Dependences.h new file mode 100755 index 00000000000..a7833d54149 --- /dev/null +++ b/tools/polly/include/polly/Dependences.h @@ -0,0 +1,116 @@ +//===------ polly/Dependences.h - Polyhedral dependency analysis *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Calculate the data dependency relations for a Scop using ISL. +// +// The integer set library (ISL) from Sven, has a integrated dependency analysis +// to calculate data dependences. This pass takes advantage of this and +// calculate those dependences a Scop. +// +// The dependences in this pass are exact in terms that for a specific read +// statement instance only the last write statement instance is returned. In +// case of may writes a set of possible write instances is returned. This +// analysis will never produce redundant dependences. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_DEPENDENCES_H +#define POLLY_DEPENDENCES_H + +#include "polly/ScopPass.h" + +#include + +struct isl_union_map; +struct isl_union_set; +struct isl_map; +struct isl_set; +struct clast_for; + +using namespace llvm; + +namespace polly { + + class Scop; + class ScopStmt; + + class Dependences : public ScopPass { + + isl_union_map *must_dep, *may_dep; + isl_union_map *must_no_source, *may_no_source; + + isl_union_map *war_dep; + isl_union_map *waw_dep; + + isl_union_map *sink; + isl_union_map *must_source; + isl_union_map *may_source; + + public: + static char ID; + + /// @brief The type of the dependences. + enum Type { + // Write after read + TYPE_WAR = 0x1, + + // Read after write + TYPE_RAW = 0x2, + + // Write after write + TYPE_WAW = 0x4 + }; + + typedef std::map StatementToIslMapTy; + + Dependences(); + bool isValidScattering(StatementToIslMapTy *NewScatterings); + + /// @brief Check if a dimension of the Scop can be executed in parallel. + /// + /// @param loopDomain The subset of the scattering space that is executed in + /// parallel. + /// @param parallelDimension The scattering dimension that is being executed + /// in parallel. + /// + /// @return bool Returns true, if executing parallelDimension in parallel is + /// valid for the scattering domain subset given. + bool isParallelDimension(isl_set *loopDomain, unsigned parallelDimension); + + /// @brief Check if a loop is parallel + /// + /// Detect if a clast_for loop can be executed in parallel. + /// + /// @param f The clast for loop to check. + /// + /// @return bool Returns true if the incoming clast_for statement can + /// execute in parallel. + bool isParallelFor(const clast_for *f); + + /// @brief Get the dependences in this Scop. + /// + /// @param dependenceKinds This integer defines the different kinds of + /// dependences that will be returned. To return + /// more than one kind, the different kinds are + /// 'ored' together. + isl_union_map *getDependences(int dependenceKinds); + + bool runOnScop(Scop &S); + void printScop(raw_ostream &OS) const; + virtual void releaseMemory(); + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + }; +} // End polly namespace. + +namespace llvm { + class PassRegistry; + void initializeDependencesPass(llvm::PassRegistry&); +} + +#endif diff --git a/tools/polly/include/polly/LinkAllPasses.h b/tools/polly/include/polly/LinkAllPasses.h new file mode 100644 index 00000000000..07fb32275ff --- /dev/null +++ b/tools/polly/include/polly/LinkAllPasses.h @@ -0,0 +1,127 @@ +//===- polly/LinkAllPasses.h ------------ Reference All Passes ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header file pulls in all transformation and analysis passes for tools +// like opt and bugpoint that need this functionality. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_LINKALLPASSES_H +#define POLLY_LINKALLPASSES_H + +#include "polly/Config/config.h" +#include + +namespace llvm { + class Pass; + class PassInfo; + class PassRegistry; + class RegionPass; +} + +using namespace llvm; + +namespace polly { + Pass *createAffSCEVItTesterPass(); + Pass *createCloogExporterPass(); + Pass *createCloogInfoPass(); + Pass *createCodeGenerationPass(); + Pass *createCodePreparationPass(); + Pass *createDeadCodeElimPass(); + Pass *createDependencesPass(); + Pass *createDOTOnlyPrinterPass(); + Pass *createDOTOnlyViewerPass(); + Pass *createDOTPrinterPass(); + Pass *createDOTViewerPass(); + Pass *createIndependentBlocksPass(); + Pass *createJSONExporterPass(); + Pass *createJSONImporterPass(); + Pass *createRegionSimplifyPass(); + Pass *createScopDetectionPass(); + Pass *createScopInfoPass(); + Pass *createIslScheduleOptimizerPass(); + Pass *createTempScopInfoPass(); + +#ifdef OPENSCOP_FOUND + Pass *createScopExporterPass(); + Pass *createScopImporterPass(); +#endif + +#ifdef SCOPLIB_FOUND + Pass *createPoccPass(); + Pass *createScopLibExporterPass(); + Pass *createScopLibImporterPass(); +#endif + + extern char &IndependentBlocksID; + extern char &CodePreparationID; +} + +using namespace polly; + +namespace { + struct PollyForcePassLinking { + PollyForcePassLinking() { + // We must reference the passes in such a way that compilers will not + // delete it all as dead code, even with whole program optimization, + // yet is effectively a NO-OP. As the compiler isn't smart enough + // to know that getenv() never returns -1, this will do the job. + if (std::getenv("bar") != (char*) -1) + return; + + createAffSCEVItTesterPass(); + createCloogExporterPass(); + createCloogInfoPass(); + createCodeGenerationPass(); + createCodePreparationPass(); + createDeadCodeElimPass(); + createDependencesPass(); + createDOTOnlyPrinterPass(); + createDOTOnlyViewerPass(); + createDOTPrinterPass(); + createDOTViewerPass(); + createIndependentBlocksPass(); + createJSONExporterPass(); + createJSONImporterPass(); + createRegionSimplifyPass(); + createScopDetectionPass(); + createScopInfoPass(); + createIslScheduleOptimizerPass(); + createTempScopInfoPass(); + +#ifdef OPENSCOP_FOUND + createScopExporterPass(); + createScopImporterPass(); +#endif +#ifdef SCOPLIB_FOUND + createPoccPass(); + createScopLibExporterPass(); + createScopLibImporterPass(); +#endif + + } + } PollyForcePassLinking; // Force link by creating a global definition. +} + +namespace llvm { + class PassRegistry; + void initializeCodeGenerationPass(llvm::PassRegistry&); + void initializeCodePreparationPass(llvm::PassRegistry&); + void initializeDeadCodeElimPass(llvm::PassRegistry&); + void initializeIndependentBlocksPass(llvm::PassRegistry&); + void initializeJSONExporterPass(llvm::PassRegistry&); + void initializeJSONImporterPass(llvm::PassRegistry&); + void initializeIslScheduleOptimizerPass(llvm::PassRegistry&); +#ifdef SCOPLIB_FOUND + void initializePoccPass(llvm::PassRegistry&); +#endif + void initializeRegionSimplifyPass(llvm::PassRegistry&); +} + +#endif diff --git a/tools/polly/include/polly/MayAliasSet.h b/tools/polly/include/polly/MayAliasSet.h new file mode 100755 index 00000000000..68fa2872284 --- /dev/null +++ b/tools/polly/include/polly/MayAliasSet.h @@ -0,0 +1,157 @@ +//===- MayAliasSet.h - May-alias Set for Base Pointers ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines two classes: MayAliasSet and MayAliasSetInfo. +// MayAliasSet contains the base pointers of access functions in SCoP that +// may/must alias each others. And MayAliasSetInfo will compute and hold these +// MayAliasSets in every SCoP in a function. +// +// The difference between MayAliasSet and the original LLVM AliasSet is that +// the LLVM AliasSets are disjoint, but MayAliasSets are not. +// +// Suppose we have the following LLVM IR: +// define void @f(i32* noalias nocapture %a, i32* noalias nocapture %b)nounwind{ +// bb.nph: +// %0 = tail call i32 (...)* @rnd() nounwind +// %1 = icmp eq i32 %0, 0 +// %ptr0 = select i1 %1, i32* %b, i32* %a +// %2 = load i32* %ptr0, align 4 +// %3 = load i32* %a, align 4 +// %4 = load i32* %b, align 4 +// ret void +// } +// +// The LLVM AliasSetTracker constructs only one LLVM AliasSet that contains +// ptr0, a and b, but MayAliasSetInfo is supposed to build two MayAliasSets: +// {a, ptr0} and {b, ptr0}. +// +// Take the above LLVM IR for example, the MayAliasSetInfo builds two set: +// A: {a, ptr0} and B: {b, ptr0} and constructs base pointer to MayAliasSet +// mapping like: +// a -> A +// b -> B +// ptr0 -> A, B +// +// After that, SCoPInfo pass will build a access function for each MayAliasSet, +// so "%2 = load i32* %ptr0, align 4" will be translated to "read A" and +// "read B", while "%3 = load i32* %a, align 4" will be translated to "read A", +// and "%4 = load i32* %b, align 4" will be translated to "read B". This means +// we can treat the MayAliasSet as the identifier of the virtual array of memory +// access in SCoPs. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_MAY_ALIAS_SET_H +#define POLLY_MAY_ALIAS_SET_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/Allocator.h" +#include + +namespace llvm { + class Value; + class AliasAnalysis; + class raw_ostream; +} + +using namespace llvm; + +namespace polly { +class MayAliasSetInfo; +class TempScop; + +//===----------------------------------------------------------------------===// +/// @brief MayAliasSet of pointers in SCoPs. +/// +/// Note: Pointers in MayAliasSet only must-alias with each other now. +class MayAliasSet { + // DO NOT IMPLEMENT + MayAliasSet(const MayAliasSet &); + // DO NOT IMPLEMENT + const MayAliasSet &operator=(const MayAliasSet &); + + // TODO: Use CallbackVH to update the set when some base pointers are deleted + // by some pass. + SmallPtrSet MustAliasPtrs; + + MayAliasSet() {} + + friend class MayAliasSetInfo; +public: + + /// @name Must Alias Pointer Iterators + /// + /// These iterators iterate over all must alias pointers in the set. + //@{ + typedef SmallPtrSetIterator const_iterator; + const_iterator mustalias_begin() const { return MustAliasPtrs.begin(); } + const_iterator mustalias_end() const { return MustAliasPtrs.end(); } + //@} + + /// @brief Add a must alias pointer to this set. + /// + /// @param V The pointer to add. + void addMustAliasPtr(const Value* V) { MustAliasPtrs.insert(V); } + + void print(raw_ostream &OS) const; + void dump() const; +}; + +//===----------------------------------------------------------------------===// +/// @brief Compute and manage the may-alias sets in a TempSCoP or SCoP. +class MayAliasSetInfo { + // DO NOT IMPLEMENT + MayAliasSetInfo(const MayAliasSetInfo &); + // DO NOT IMPLEMENT + const MayAliasSetInfo &operator=(const MayAliasSetInfo &); + + SpecificBumpPtrAllocator MayASAllocator; + + // Mapping the pointers to their may-alias sets. + typedef std::multimap MayAliasSetMapType; + MayAliasSetMapType BasePtrMap; + +public: + MayAliasSetInfo() {} + + /// @name MayAliasSet Iterators + /// + /// These iterators iterate over all may-alias sets referring to a base + /// pointer. + //@{ + typedef MayAliasSetMapType::iterator alias_iterator; + typedef MayAliasSetMapType::const_iterator const_alias_iterator; + + alias_iterator alias_begin(const Value *BasePtr) { + return BasePtrMap.lower_bound(BasePtr); + } + + alias_iterator alias_end(const Value *BasePtr) { + return BasePtrMap.upper_bound(BasePtr); + } + + const_alias_iterator alias_begin(const Value *BasePtr) const { + return BasePtrMap.lower_bound(BasePtr); + } + + const_alias_iterator alias_end(const Value *BasePtr) const { + return BasePtrMap.upper_bound(BasePtr); + } + //@} + + + /// @brief Build MayAliasSets in a SCoP. + /// + /// @param Scop The SCoP to build MayAliasSets in. + /// @param AA The AliasAnalaysis provides the alias information. + void buildMayAliasSets(TempScop &Scop, AliasAnalysis &AA); +}; +} + +#endif diff --git a/tools/polly/include/polly/RegisterPasses.h b/tools/polly/include/polly/RegisterPasses.h new file mode 100644 index 00000000000..a0ce12bb72f --- /dev/null +++ b/tools/polly/include/polly/RegisterPasses.h @@ -0,0 +1,27 @@ +//===------ polly/RegisterPasses.h - Register the Polly passes *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Functions to register the Polly passes in a LLVM pass manager. +// +//===----------------------------------------------------------------------===// + +namespace llvm { + class PassManagerBase; +} + +// Register the Polly preoptimization passes. Preoptimizations are used to +// prepare the LLVM-IR for Polly. They increase the amount of code that can be +// optimized. +// (These passes are automatically included in registerPollyPasses). +void registerPollyPreoptPasses(llvm::PassManagerBase &PM); + +// Register the Polly optimizer (including its preoptimizations). +void registerPollyPasses(llvm::PassManagerBase &PM, + bool DisableScheduler = false, + bool DisableCodegen = false); diff --git a/tools/polly/include/polly/ScheduleOptimizer.h b/tools/polly/include/polly/ScheduleOptimizer.h new file mode 100644 index 00000000000..0ed1f218d98 --- /dev/null +++ b/tools/polly/include/polly/ScheduleOptimizer.h @@ -0,0 +1,19 @@ +//===------ polly/ScheduleOptimizer.h - The Schedule Optimizer *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_SCEDULE_OPTIMIZER_H +#define POLLY_SCHEDULE_OPTIMZER_H + +namespace polly { + extern bool DisablePollyTiling; +} + +#endif diff --git a/tools/polly/include/polly/ScopDetection.h b/tools/polly/include/polly/ScopDetection.h new file mode 100755 index 00000000000..f9480aa1263 --- /dev/null +++ b/tools/polly/include/polly/ScopDetection.h @@ -0,0 +1,279 @@ +//===--- ScopDetection.h - Detect Scops -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Detect the maximal Scops of a function. +// +// A static control part (Scop) is a subgraph of the control flow graph (CFG) +// that only has statically known control flow and can therefore be described +// within the polyhedral model. +// +// Every Scop fullfills these restrictions: +// +// * It is a single entry single exit region +// +// * Only affine linear bounds in the loops +// +// Every natural loop in a Scop must have a number of loop iterations that can +// be described as an affine linear function in surrounding loop iterators or +// parameters. (A parameter is a scalar that does not change its value during +// execution of the Scop). +// +// * Only comparisons of affine linear expressions in conditions +// +// * All loops and conditions perfectly nested +// +// The control flow needs to be structured such that it could be written using +// just 'for' and 'if' statements, without the need for any 'goto', 'break' or +// 'continue'. +// +// * Side effect free functions call +// +// Only function calls and intrinsics that do not have side effects are allowed +// (readnone). +// +// The Scop detection finds the largest Scops by checking if the largest +// region is a Scop. If this is not the case, its canonical subregions are +// checked until a region is a Scop. It is now tried to extend this Scop by +// creating a larger non canonical region. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_SCOP_DETECTION_H +#define POLLY_SCOP_DETECTION_H + +#include "llvm/Pass.h" +#include "llvm/Analysis/AliasSetTracker.h" + +#include +#include + +using namespace llvm; + +namespace llvm { + class RegionInfo; + class Region; + class LoopInfo; + class Loop; + class ScalarEvolution; + class SCEV; + class SCEVAddRecExpr; + class CallInst; + class Instruction; + class AliasAnalysis; + class Value; +} + +namespace polly { +typedef std::set ParamSetType; + +//===----------------------------------------------------------------------===// +/// @brief Pass to detect the maximal static control parts (Scops) of a +/// function. +class ScopDetection : public FunctionPass { + //===--------------------------------------------------------------------===// + // DO NOT IMPLEMENT + ScopDetection(const ScopDetection &); + // DO NOT IMPLEMENT + const ScopDetection &operator=(const ScopDetection &); + + /// @brief Analysis passes used. + //@{ + ScalarEvolution* SE; + LoopInfo *LI; + RegionInfo *RI; + AliasAnalysis *AA; + //@} + + /// @brief Context variables for SCoP detection. + struct DetectionContext { + Region &CurRegion; // The region to check. + AliasSetTracker AST; // The AliasSetTracker to hold the alias information. + bool Verifying; // If we are in the verification phase? + DetectionContext(Region &R, AliasAnalysis &AA, bool Verify) + : CurRegion(R), AST(AA), Verifying(Verify) {} + }; + + // Remember the valid regions + typedef std::set RegionSet; + RegionSet ValidRegions; + + // Invalid regions and the reason they fail. + std::map InvalidRegions; + + // Remember the invalid functions producted by backends; + typedef std::set FunctionSet; + FunctionSet InvalidFunctions; + mutable std::string LastFailure; + + // Try to expand the region R. If R can be expanded return the expanded + // region, NULL otherwise. + Region *expandRegion(Region &R); + + // Find the Scops in this region tree. + void findScops(Region &R); + + /// @brief Check if all basic block in the region are valid. + /// + /// @param Context The context of scop detection. + /// + /// @return True if all blocks in R are valid, false otherwise. + bool allBlocksValid(DetectionContext &Context) const; + + /// @brief Check the exit block of a region is valid. + /// + /// @param Context The context of scop detection. + /// + /// @return True if the exit of R is valid, false otherwise. + bool isValidExit(DetectionContext &Context) const; + + /// @brief Check if a region is a Scop. + /// + /// @param Context The context of scop detection. + /// + /// @return True if R is a Scop, false otherwise. + bool isValidRegion(DetectionContext &Context) const; + + /// @brief Check if a call instruction can be part of a Scop. + /// + /// @param CI The call instruction to check. + /// @return True if the call instruction is valid, false otherwise. + static bool isValidCallInst(CallInst &CI); + + /// @brief Check if a memory access can be part of a Scop. + /// + /// @param Inst The instruction accessing the memory. + /// @param Context The context of scop detection. + /// + /// @return True if the memory access is valid, false otherwise. + bool isValidMemoryAccess(Instruction &Inst, DetectionContext &Context) const; + + /// @brief Check if an instruction has any non trivial scalar dependencies + /// as part of a Scop. + /// + /// @param Inst The instruction to check. + /// @param RefRegion The region in respect to which we check the access + /// function. + /// + /// @return True if the instruction has scalar dependences, false otherwise. + bool hasScalarDependency(Instruction &Inst, Region &RefRegion) const; + + /// @brief Check if an instruction can be part of a Scop. + /// + /// @param Inst The instruction to check. + /// @param Context The context of scop detection. + /// + /// @return True if the instruction is valid, false otherwise. + bool isValidInstruction(Instruction &I, DetectionContext &Context) const; + + /// @brief Check if the BB can be part of a Scop. + /// + /// @param BB The basic block to check. + /// @param Context The context of scop detection. + /// + /// @return True if the basic block is valid, false otherwise. + bool isValidBasicBlock(BasicBlock &BB, DetectionContext &Context) const; + + /// @brief Check if the control flow in a basic block is valid. + /// + /// @param BB The BB to check the control flow. + /// @param Context The context of scop detection. + /// + /// @return True if the BB contains only valid control flow. + bool isValidCFG(BasicBlock &BB, DetectionContext &Context) const; + + /// @brief Is a loop valid with respect to a given region. + /// + /// @param L The loop to check. + /// @param Context The context of scop detection. + /// + /// @return True if the loop is valid in the region. + bool isValidLoop(Loop *L, DetectionContext &Context) const; + + /// @brief Check if a function is an OpenMP subfunction. + /// + /// An OpenMP subfunction is not valid for Scop detection. + /// + /// @param F The function to check. + /// + /// @return True if the function is not an OpenMP subfunction. + bool isValidFunction(llvm::Function &F); + +public: + static char ID; + explicit ScopDetection() : FunctionPass(ID) {} + + /// @brief Get the RegionInfo stored in this pass. + /// + /// This was added to give the DOT printer easy access to this information. + RegionInfo *getRI() const { return RI; } + + /// @brief Is the region is the maximum region of a Scop? + /// + /// @param R The Region to test if it is maximum. + /// + /// @return Return true if R is the maximum Region in a Scop, false otherwise. + bool isMaxRegionInScop(const Region &R) const; + + /// @brief Get a message why a region is invalid + /// + /// @param R The region for which we get the error message + /// + /// @return The error or "" if no error appeared. + std::string regionIsInvalidBecause(const Region *R) const; + + /// @name Maximum Region In Scops Iterators + /// + /// These iterators iterator over all maximum region in Scops of this + /// function. + //@{ + typedef RegionSet::iterator iterator; + typedef RegionSet::const_iterator const_iterator; + + iterator begin() { return ValidRegions.begin(); } + iterator end() { return ValidRegions.end(); } + + const_iterator begin() const { return ValidRegions.begin(); } + const_iterator end() const { return ValidRegions.end(); } + //@} + + /// @brief Mark the function as invalid so we will not extract any scop from + /// the function. + /// + /// @param F The function to mark as invalid. + void markFunctionAsInvalid(const Function *F) { + InvalidFunctions.insert(F); + } + + /// @brief Verify if all valid Regions in this Function are still valid + /// after some transformations. + void verifyAnalysis() const; + + /// @brief Verify if R is still a valid part of Scop after some + /// transformations. + /// + /// @param R The Region to verify. + void verifyRegion(const Region &R) const; + + /// @name FunctionPass interface + //@{ + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual void releaseMemory(); + virtual bool runOnFunction(Function &F); + virtual void print(raw_ostream &OS, const Module *) const; + //@} +}; + +} //end namespace polly + +namespace llvm { + class PassRegistry; + void initializeScopDetectionPass(llvm::PassRegistry&); +} + +#endif diff --git a/tools/polly/include/polly/ScopInfo.h b/tools/polly/include/polly/ScopInfo.h new file mode 100755 index 00000000000..dcd4c7c0235 --- /dev/null +++ b/tools/polly/include/polly/ScopInfo.h @@ -0,0 +1,639 @@ +//===------ polly/ScopInfo.h - Create Scops from LLVM IR --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Create a polyhedral description for a static control flow region. +// +// The pass creates a polyhedral description of the Scops detected by the Scop +// detection derived from their LLVM-IR code. +// +// This represantation is shared among several tools in the polyhedral +// community, which are e.g. CLooG, Pluto, Loopo, Graphite. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_SCOP_INFO_H +#define POLLY_SCOP_INFO_H + +#include "polly/ScopDetection.h" + +#include "llvm/Analysis/RegionPass.h" + +#include "isl/ctx.h" + +using namespace llvm; + +namespace llvm { + class Loop; + class LoopInfo; + class PHINode; + class ScalarEvolution; + class SCEV; + class SCEVAddRecExpr; + class Type; +} + +struct isl_ctx; +struct isl_map; +struct isl_basic_map; +struct isl_id; +struct isl_set; +struct isl_space; +struct isl_constraint; + +namespace polly { + +class IRAccess; +class Scop; +class ScopStmt; +class ScopInfo; +class TempScop; +class SCEVAffFunc; +class Comparison; + +//===----------------------------------------------------------------------===// +/// @brief Represent memory accesses in statements. +class MemoryAccess { + // DO NOT IMPLEMENT + MemoryAccess(const MemoryAccess &); + // DO NOT IMPLEMENT + const MemoryAccess &operator=(const MemoryAccess &); + +public: + /// @brief The access type of a memory access + /// + /// There are three kind of access types: + /// + /// * A read access + /// + /// A certain set of memory locations are read and may be used for internal + /// calculations. + /// + /// * A write access + /// + /// A certain set of memory locactions is definitely written. The old value is + /// replaced by a newly calculated value. The old value is not read or used at + /// all. + /// + /// * A may write access + /// + /// A certain set of memory locactions may be written. The memory location may + /// contain a new value if there is actually a write or the old value may + /// remain, if no write happens. + enum AccessType { + Read, + Write, + MayWrite + }; + +private: + isl_map *AccessRelation; + enum AccessType Type; + + const Value* BaseAddr; + std::string BaseName; + isl_basic_map *createBasicAccessMap(ScopStmt *Statement); + void setBaseName(); + ScopStmt *statement; + + /// Updated access relation read from JSCOP file. + isl_map *newAccessRelation; +public: + // @brief Create a memory access from an access in LLVM-IR. + // + // @param Access The memory access. + // @param Statement The statement that contains the access. + // @param SE The ScalarEvolution analysis. + MemoryAccess(const IRAccess &Access, ScopStmt *Statement); + + // @brief Create a memory access that reads a complete memory object. + // + // @param BaseAddress The base address of the memory object. + // @param Statement The statement that contains this access. + MemoryAccess(const Value *BaseAddress, ScopStmt *Statement); + + ~MemoryAccess(); + + /// @brief Is this a read memory access? + bool isRead() const { return Type == MemoryAccess::Read; } + + isl_map *getAccessRelation() const; + + /// @brief Get an isl string representing this access function. + std::string getAccessRelationStr() const; + + const Value *getBaseAddr() const { + return BaseAddr; + } + + const std::string &getBaseName() const { + return BaseName; + } + + /// @brief Get the new access function imported from JSCOP file + isl_map *getNewAccessRelation() const; + + /// @brief Get the stride of this memory access in the specified domain + /// subset. + isl_set *getStride(__isl_take const isl_set *domainSubset) const; + + /// @brief Is the stride of the access equal to a certain width. + bool isStrideX(__isl_take const isl_set *DomainSubset, int StrideWidth) const; + + /// @brief Is consecutive memory accessed for a given + /// statement instance set? + bool isStrideOne(__isl_take const isl_set *domainSubset) const; + + /// @brief Is always the same memory accessed for a given + /// statement instance set? + bool isStrideZero(__isl_take const isl_set *domainSubset) const; + + /// @brief Get the statement that contains this memory access. + ScopStmt *getStatement() const { return statement; } + + /// @brief Set the updated access relation read from JSCOP file. + void setNewAccessRelation(isl_map *newAccessRelation); + + /// @brief Align the parameters in the access relation to the scop context + void realignParams(); + + /// @brief Print the MemoryAccess. + /// + /// @param OS The output stream the MemoryAccess is printed to. + void print(raw_ostream &OS) const; + + /// @brief Print the MemoryAccess to stderr. + void dump() const; +}; + +//===----------------------------------------------------------------------===// +/// @brief Statement of the Scop +/// +/// A Scop statement represents an instruction in the Scop. +/// +/// It is further described by its iteration domain, its schedule and its data +/// accesses. +/// At the moment every statement represents a single basic block of LLVM-IR. +class ScopStmt { + //===-------------------------------------------------------------------===// + // DO NOT IMPLEMENT + ScopStmt(const ScopStmt &); + // DO NOT IMPLEMENT + const ScopStmt &operator=(const ScopStmt &); + + + /// Polyhedral description + //@{ + + /// The Scop containing this ScopStmt + Scop &Parent; + + /// The iteration domain describes the set of iterations for which this + /// statement is executed. + /// + /// Example: + /// for (i = 0; i < 100 + b; ++i) + /// for (j = 0; j < i; ++j) + /// S(i,j); + /// + /// 'S' is executed for different values of i and j. A vector of all + /// induction variables around S (i, j) is called iteration vector. + /// The domain describes the set of possible iteration vectors. + /// + /// In this case it is: + /// + /// Domain: 0 <= i <= 100 + b + /// 0 <= j <= i + /// + /// A pair of statment and iteration vector (S, (5,3)) is called statment + /// instance. + isl_set *Domain; + + /// The scattering map describes the execution order of the statement + /// instances. + /// + /// A statement and its iteration domain do not give any information about the + /// order in time in which the different statement instances are executed. + /// This information is provided by the scattering. + /// + /// The scattering maps every instance of each statement into a multi + /// dimensional scattering space. This space can be seen as a multi + /// dimensional clock. + /// + /// Example: + /// + /// may be mapped to (5,4) by this scattering: + /// + /// s0 = i (Year of execution) + /// s1 = j (Day of execution) + /// + /// or to (9, 20) by this scattering: + /// + /// s0 = i + j (Year of execution) + /// s1 = 20 (Day of execution) + /// + /// The order statement instances are executed is defined by the + /// scattering vectors they are mapped to. A statement instance + /// is executed before a statement instance , if + /// the scattering vector of A is lexicographic smaller than the scattering + /// vector of B. + isl_map *Scattering; + + /// The memory accesses of this statement. + /// + /// The only side effects of a statement are its memory accesses. + typedef SmallVector MemoryAccessVec; + MemoryAccessVec MemAccs; + std::map InstructionToAccess; + + //@} + + /// The BasicBlock represented by this statement. + BasicBlock *BB; + + /// @brief The loop induction variables surrounding the statement. + /// + /// This information is only needed for final code generation. + std::vector > IVS; + + std::string BaseName; + + /// Build the statment. + //@{ + __isl_give isl_set *buildConditionSet(const Comparison &Cmp); + __isl_give isl_set *addConditionsToDomain(__isl_take isl_set *Domain, + TempScop &tempScop, + const Region &CurRegion); + __isl_give isl_set *addLoopBoundsToDomain(__isl_take isl_set *Domain, + TempScop &tempScop); + __isl_give isl_set *buildDomain(TempScop &tempScop, + const Region &CurRegion); + void buildScattering(SmallVectorImpl &Scatter); + void buildAccesses(TempScop &tempScop, const Region &CurRegion); + //@} + + /// Create the ScopStmt from a BasicBlock. + ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, + BasicBlock &bb, SmallVectorImpl &NestLoops, + SmallVectorImpl &Scatter); + + /// Create the finalization statement. + ScopStmt(Scop &parent, SmallVectorImpl &Scatter); + + friend class Scop; +public: + + ~ScopStmt(); + /// @brief Get an isl_ctx pointer. + isl_ctx *getIslCtx() const; + + /// @brief Get the iteration domain of this ScopStmt. + /// + /// @return The iteration domain of this ScopStmt. + isl_set *getDomain() const; + + /// @brief Get the space of the iteration domain + /// + /// @return The space of the iteration domain + isl_space *getDomainSpace() const; + + /// @brief Get an isl string representing this domain. + std::string getDomainStr() const; + + /// @brief Get the scattering function of this ScopStmt. + /// + /// @return The scattering function of this ScopStmt. + isl_map *getScattering() const; + void setScattering(isl_map *scattering); + + /// @brief Get an isl string representing this scattering. + std::string getScatteringStr() const; + + /// @brief Get the BasicBlock represented by this ScopStmt. + /// + /// @return The BasicBlock represented by this ScopStmt. + BasicBlock *getBasicBlock() const { return BB; } + + MemoryAccess &getAccessFor(const Instruction *Inst) { + return *InstructionToAccess[Inst]; + } + + void setBasicBlock(BasicBlock *Block) { BB = Block; } + + typedef MemoryAccessVec::iterator memacc_iterator; + memacc_iterator memacc_begin() { return MemAccs.begin(); } + memacc_iterator memacc_end() { return MemAccs.end(); } + + unsigned getNumParams() const; + unsigned getNumIterators() const; + unsigned getNumScattering() const; + + Scop *getParent() { return &Parent; } + const Scop *getParent() const { return &Parent; } + + const char *getBaseName() const; + /// @brief Get the induction variable for a dimension. + /// + /// @param Dimension The dimension of the induction variable + /// @return The induction variable at a certain dimension. + const PHINode *getInductionVariableForDimension(unsigned Dimension) const; + + /// @brief Get the loop for a dimension. + /// + /// @param Dimension The dimension of the induction variable + /// @return The loop at a certain dimension. + const Loop *getLoopForDimension(unsigned Dimension) const; + + /// @brief Return the SCEV for a loop dimension. + const SCEVAddRecExpr *getSCEVForDimension(unsigned Dimension) const; + + /// @brief Is this statement the final read statement? + /// + /// A final read statement is scheduled after all statements to model + /// that all data used in the Scop is read after the Scop. + bool isFinalRead() { return getBasicBlock() == NULL; } + + /// @brief Align the parameters in the statement to the scop context + void realignParams(); + + /// @brief Print the ScopStmt. + /// + /// @param OS The output stream the ScopStmt is printed to. + void print(raw_ostream &OS) const; + + /// @brief Print the ScopStmt to stderr. + void dump() const; +}; + +/// @brief Print ScopStmt S to raw_ostream O. +static inline raw_ostream& operator<<(raw_ostream &O, const ScopStmt &S) { + S.print(O); + return O; +} + +//===----------------------------------------------------------------------===// +/// @brief Static Control Part +/// +/// A Scop is the polyhedral representation of a control flow region detected +/// by the Scop detection. It is generated by translating the LLVM-IR and +/// abstracting its effects. +/// +/// A Scop consists of a set of: +/// +/// * A set of statements executed in the Scop. +/// +/// * A set of global parameters +/// Those parameters are scalar integer values, which are constant during +/// execution. +/// +/// * A context +/// This context contains information about the values the parameters +/// can take and relations between different parameters. +class Scop { + //===-------------------------------------------------------------------===// + // DO NOT IMPLEMENT + Scop(const Scop &); + // DO NOT IMPLEMENT + const Scop &operator=(const Scop &); + + ScalarEvolution *SE; + + /// The underlying Region. + Region &R; + + /// Max loop depth. + unsigned MaxLoopDepth; + + typedef std::vector StmtSet; + /// The Statments in this Scop. + StmtSet Stmts; + + /// Parameters of this Scop + typedef SmallVector ParamVecType; + ParamVecType Parameters; + + /// The isl_ids that are used to represent the parameters + typedef std::map ParamIdType; + ParamIdType ParameterIds; + + // Isl context. + isl_ctx *IslCtx; + + /// Constraints on parameters. + isl_set *Context; + + /// Create the static control part with a region, max loop depth of this + /// region and parameters used in this region. + Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, isl_ctx *ctx); + + /// @brief Check if a basic block is trivial. + /// + /// A trivial basic block does not contain any useful calculation. Therefore, + /// it does not need to be represented as a polyhedral statement. + /// + /// @param BB The basic block to check + /// @param tempScop TempScop returning further information regarding the Scop. + /// + /// @return True if the basic block is trivial, otherwise false. + static bool isTrivialBB(BasicBlock *BB, TempScop &tempScop); + + /// @brief Build the Context of the Scop. + void buildContext(); + + /// Build the Scop and Statement with precalculate scop information. + void buildScop(TempScop &TempScop, const Region &CurRegion, + // Loops in Scop containing CurRegion + SmallVectorImpl &NestLoops, + // The scattering numbers + SmallVectorImpl &Scatter, + LoopInfo &LI); + + /// Helper function for printing the Scop. + void printContext(raw_ostream &OS) const; + void printStatements(raw_ostream &OS) const; + + friend class ScopInfo; +public: + + ~Scop(); + + ScalarEvolution *getSE() const; + + /// @brief Get the count of parameters used in this Scop. + /// + /// @return The count of parameters used in this Scop. + inline ParamVecType::size_type getNumParams() const { + return Parameters.size(); + } + + /// @brief Get a set containing the parameters used in this Scop + /// + /// @return The set containing the parameters used in this Scop. + inline const ParamVecType &getParams() const { return Parameters; } + + /// @brief Take a list of parameters and add the new ones to the scop. + void addParams(std::vector NewParameters); + + /// @brief Return the isl_id that represents a certain parameter. + /// + /// @param Parameter A SCEV that was recognized as a Parameter. + /// + /// @return The corresponding isl_id or NULL otherwise. + isl_id *getIdForParam(const SCEV *Parameter) const; + + /// @name Parameter Iterators + /// + /// These iterators iterate over all parameters of this Scop. + //@{ + typedef ParamVecType::iterator param_iterator; + typedef ParamVecType::const_iterator const_param_iterator; + + param_iterator param_begin() { return Parameters.begin(); } + param_iterator param_end() { return Parameters.end(); } + const_param_iterator param_begin() const { return Parameters.begin(); } + const_param_iterator param_end() const { return Parameters.end(); } + //@} + + /// @brief Get the maximum region of this static control part. + /// + /// @return The maximum region of this static control part. + inline const Region &getRegion() const { return R; } + inline Region &getRegion() { return R; } + + /// @brief Get the maximum depth of the loop. + /// + /// @return The maximum depth of the loop. + inline unsigned getMaxLoopDepth() const { return MaxLoopDepth; } + + /// @brief Get the scattering dimension number of this Scop. + /// + /// @return The scattering dimension number of this Scop. + inline unsigned getScatterDim() const { + unsigned maxScatterDim = 0; + + for (const_iterator SI = begin(), SE = end(); SI != SE; ++SI) + maxScatterDim = std::max(maxScatterDim, (*SI)->getNumScattering()); + + return maxScatterDim; + } + + /// @brief Get the name of this Scop. + std::string getNameStr() const; + + /// @brief Get the constraint on parameter of this Scop. + /// + /// @return The constraint on parameter of this Scop. + __isl_give isl_set *getContext() const; + __isl_give isl_space *getParamSpace() const; + + /// @brief Get an isl string representing the context. + std::string getContextStr() const; + + /// @name Statements Iterators + /// + /// These iterators iterate over all statements of this Scop. + //@{ + typedef StmtSet::iterator iterator; + typedef StmtSet::const_iterator const_iterator; + + iterator begin() { return Stmts.begin(); } + iterator end() { return Stmts.end(); } + const_iterator begin() const { return Stmts.begin(); } + const_iterator end() const { return Stmts.end(); } + + typedef StmtSet::reverse_iterator reverse_iterator; + typedef StmtSet::const_reverse_iterator const_reverse_iterator; + + reverse_iterator rbegin() { return Stmts.rbegin(); } + reverse_iterator rend() { return Stmts.rend(); } + const_reverse_iterator rbegin() const { return Stmts.rbegin(); } + const_reverse_iterator rend() const { return Stmts.rend(); } + //@} + + void setContext(isl_set* NewContext); + + /// @brief Align the parameters in the statement to the scop context + void realignParams(); + + /// @brief Print the static control part. + /// + /// @param OS The output stream the static control part is printed to. + void print(raw_ostream &OS) const; + + /// @brief Print the ScopStmt to stderr. + void dump() const; + + /// @brief Get the isl context of this static control part. + /// + /// @return The isl context of this static control part. + isl_ctx *getIslCtx() const; +}; + +/// @brief Print Scop scop to raw_ostream O. +static inline raw_ostream& operator<<(raw_ostream &O, const Scop &scop) { + scop.print(O); + return O; +} + +//===---------------------------------------------------------------------===// +/// @brief Build the Polly IR (Scop and ScopStmt) on a Region. +/// +class ScopInfo : public RegionPass { + //===-------------------------------------------------------------------===// + // DO NOT IMPLEMENT + ScopInfo(const ScopInfo &); + // DO NOT IMPLEMENT + const ScopInfo &operator=(const ScopInfo &); + + // The Scop + Scop *scop; + isl_ctx *ctx; + + void clear() { + if (scop) { + delete scop; + scop = 0; + } + } + +public: + static char ID; + explicit ScopInfo(); + ~ScopInfo(); + + /// @brief Try to build the Polly IR of static control part on the current + /// SESE-Region. + /// + /// @return If the current region is a valid for a static control part, + /// return the Polly IR representing this static control part, + /// return null otherwise. + Scop *getScop() { return scop; } + const Scop *getScop() const { return scop; } + + /// @name RegionPass interface + //@{ + virtual bool runOnRegion(Region *R, RGPassManager &RGM); + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual void releaseMemory() { clear(); } + virtual void print(raw_ostream &OS, const Module *) const { + if (scop) + scop->print(OS); + else + OS << "Invalid Scop!\n"; + } + //@} +}; + +} //end namespace polly + +namespace llvm { + class PassRegistry; + void initializeScopInfoPass(llvm::PassRegistry&); +} + +#endif diff --git a/tools/polly/include/polly/ScopLib.h b/tools/polly/include/polly/ScopLib.h new file mode 100644 index 00000000000..ce738d092ea --- /dev/null +++ b/tools/polly/include/polly/ScopLib.h @@ -0,0 +1,72 @@ +//===- ScopLib.h - ScopLib interface ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Scoplib interface. +// +// The scoplib interface allows to import/export a scop using scoplib. +//===----------------------------------------------------------------------===// + +#ifndef POLLY_SCOPLIB_H +#define POLLY_SCOPLIB_H + +#define SCOPLIB_INT_T_IS_MP +#include "isl/ctx.h" + +#include "scoplib/scop.h" + +#include + +namespace llvm { + class Value; +} + +struct isl_constraint; +struct isl_basic_map; +struct isl_basic_set; +struct isl_map; +struct isl_set; + +namespace polly { + class Dependences; + class ScopStmt; + class Scop; + class ScopLib { + Scop *PollyScop; + scoplib_scop_p scoplib; + Dependences *D; + + std::map ArrayMap; + + void initializeArrays(); + void initializeParameters(); + void initializeScattering(); + void initializeStatements(); + scoplib_statement_p initializeStatement(ScopStmt *stmt); + void freeStatement(scoplib_statement_p stmt); + static int accessToMatrix_constraint(isl_constraint *c, void *user); + static int accessToMatrix_basic_map(isl_basic_map *bmap, void *user); + scoplib_matrix_p createAccessMatrix(ScopStmt *S, bool isRead); + static int domainToMatrix_constraint(isl_constraint *c, void *user); + static int domainToMatrix_basic_set(isl_basic_set *bset, void *user); + scoplib_matrix_p domainToMatrix(__isl_take isl_set *set); + static int scatteringToMatrix_constraint(isl_constraint *c, void *user); + static int scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user); + scoplib_matrix_p scatteringToMatrix(__isl_take isl_map *map); + + public: + ScopLib(Scop *S); + ScopLib(Scop *S, FILE *F, Dependences *D); + ~ScopLib(); + void print(FILE *F); + bool updateScattering(); + + }; +} + +#endif /* POLLY_SCOPLIB_H */ diff --git a/tools/polly/include/polly/ScopPass.h b/tools/polly/include/polly/ScopPass.h new file mode 100755 index 00000000000..674ec049fe6 --- /dev/null +++ b/tools/polly/include/polly/ScopPass.h @@ -0,0 +1,64 @@ +//===--------- ScopPass.h - Pass for Static Control Parts --------*-C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ScopPass class. ScopPasses are just RegionPasses, +// except they operate on Polly IR (Scop and ScopStmt) built by ScopInfo Pass. +// Because they operate on Polly IR, not the LLVM IR, ScopPasses are not allowed +// to modify the LLVM IR. Due to this limitation, the ScopPass class takes +// care of declaring that no LLVM passes are invalidated. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_SCOP_PASS_H +#define POLLY_SCOP_PASS_H + +#include "llvm/Analysis/RegionPass.h" + +using namespace llvm; + +struct isl_ctx; + +namespace polly { +class Scop; + +/// ScopPass - This class adapts the RegionPass interface to allow convenient +/// creation of passes that operate on the Polly IR. Instead of overriding +/// runOnRegion, subclasses override runOnScop. +class ScopPass : public RegionPass { + Scop *S; +protected: + explicit ScopPass(char &ID) : RegionPass(ID), S(0) {} + + /// runOnScop - This method must be overloaded to perform the + /// desired Polyhedral transformation or analysis. + /// + virtual bool runOnScop(Scop &S) = 0; + + /// getAnalysisUsage - Subclasses that override getAnalysisUsage + /// must call this. + /// + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + +public: + /// getIslContext - Get the isl_ctx of current SCoP. + isl_ctx *getIslContext(); + + Scop &getCurScop() const { + assert(S && "Not on a Scop!"); + return *S; + } +private: + virtual bool runOnRegion(Region *R, RGPassManager &RGM); + void print(raw_ostream &OS, const Module *) const; + virtual void printScop(raw_ostream &OS) const {} +}; + +} // End llvm namespace + +#endif diff --git a/tools/polly/include/polly/Support/GICHelper.h b/tools/polly/include/polly/Support/GICHelper.h new file mode 100755 index 00000000000..14fe36c2356 --- /dev/null +++ b/tools/polly/include/polly/Support/GICHelper.h @@ -0,0 +1,50 @@ +//===- Support/GICHelper.h -- Helper functions for GMP, ISL, and Cloog -----===/ +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Helper functions for gmp, isl and Cloog objects. +// +//===----------------------------------------------------------------------===// +// +#ifndef POLLY_SUPPORT_GIC_HELPER_H +#define POLLY_SUPPORT_GIC_HELPER_H + +#include "llvm/ADT/APInt.h" +#include + +struct isl_map; +struct isl_union_map; +struct isl_set; +struct isl_union_set; +struct isl_schedule; + +namespace polly { + +/// @brief Convert APInt to mpz. +/// +/// @param v The mpz_t object your want to hold the result. +/// @param apint The APInt you want to convert. +void MPZ_from_APInt (mpz_t v, const llvm::APInt apint, bool is_signed = true); + +/// @brief Convert mpz to APInt. +/// +/// @param mpz The mpz_t you want to convert. +llvm::APInt APInt_from_MPZ (const mpz_t mpz); + +/// @brief Get c++ string from Isl objects. +//@{ +std::string stringFromIslObj(/*__isl_keep*/ isl_map *map); +std::string stringFromIslObj(/*__isl_keep*/ isl_union_map *umap); +std::string stringFromIslObj(/*__isl_keep*/ isl_set *set); +std::string stringFromIslObj(/*__isl_keep*/ isl_union_set *uset); +std::string stringFromIslObj(/*__isl_keep*/ isl_schedule *schedule); + +//@} +} //end namespace polly + +#endif diff --git a/tools/polly/include/polly/Support/SCEVValidator.h b/tools/polly/include/polly/Support/SCEVValidator.h new file mode 100755 index 00000000000..98ba09e273a --- /dev/null +++ b/tools/polly/include/polly/Support/SCEVValidator.h @@ -0,0 +1,36 @@ +//===--- SCEVValidator.h - Detect Scops -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Checks if a SCEV expression represents a valid affine expression. +//===----------------------------------------------------------------------===// + +#ifndef POLLY_SCEV_VALIDATOR_H +#define POLLY_SCEV_VALIDATOR_H + +#include + +namespace llvm { + class Region; + class SCEV; + class ScalarEvolution; + class Value; +} + +namespace polly { + bool isAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression, + llvm::ScalarEvolution &SE, + const llvm::Value *BaseAddress = 0); + std::vector getParamsInAffineExpr( + const llvm::Region *R, + const llvm::SCEV *Expression, + llvm::ScalarEvolution &SE, + const llvm::Value *BaseAddress = 0); + +} + +#endif diff --git a/tools/polly/include/polly/Support/ScopHelper.h b/tools/polly/include/polly/Support/ScopHelper.h new file mode 100755 index 00000000000..48866deb23e --- /dev/null +++ b/tools/polly/include/polly/Support/ScopHelper.h @@ -0,0 +1,85 @@ +//===------ Support/ScopHelper.h -- Some Helper Functions for Scop. --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Small functions that help with LLVM-IR. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_SUPPORT_IRHELPER_H +#define POLLY_SUPPORT_IRHELPER_H + +namespace llvm { + class Instruction; + class LoopInfo; + class Loop; + class ScalarEvolution; + class SCEV; + class Value; + class PHINode; + class Region; + class Pass; + class BasicBlock; +} + +namespace polly { + // Helper function for Scop. + //===----------------------------------------------------------------------===// + /// Temporary Hack for extended regiontree. + /// + /// @brief Cast the region to loop. + /// + /// @param R The Region to be casted. + /// @param LI The LoopInfo to help the casting. + /// + /// @return If there is a a loop that has the same entry and exit as the region, + /// return the loop, otherwise, return null. + llvm::Loop *castToLoop(const llvm::Region &R, llvm::LoopInfo &LI); + + //===----------------------------------------------------------------------===// + // Functions for checking affine functions. + bool isInvariant(const llvm::SCEV *S, llvm::Region &R); + + bool isParameter(const llvm::SCEV *Var, llvm::Region &RefRegion, + llvm::LoopInfo &LI, llvm::ScalarEvolution &SE); + + bool isIndVar(const llvm::SCEV *Var, llvm::Region &RefRegion, + llvm::LoopInfo &LI, llvm::ScalarEvolution &SE); + + /// @brief Check if the instruction I is the induction variable of a loop. + /// + /// @param I The instruction to check. + /// @param LI The LoopInfo analysis. + /// + /// @return Return true if I is the induction variable of a loop, false + /// otherwise. + bool isIndVar(const llvm::Instruction *I, const llvm::LoopInfo *LI); + + /// @brief Check if the PHINode has any incoming Invoke edge. + /// + /// @param PN The PHINode to check. + /// + /// @return If the PHINode has an incoming BB that jumps to the parent BB + /// of the PHINode with an invoke instruction, return true, + /// otherwise, return false. + bool hasInvokeEdge(const llvm::PHINode *PN); + + llvm::Value *getPointerOperand(llvm::Instruction &Inst); + + // Helper function for LLVM-IR about Scop. + llvm::BasicBlock *createSingleExitEdge(llvm::Region *R, llvm::Pass *P); + + /// @brief Split the entry block of a function to store the newly inserted + /// allocations outside of all Scops. + /// + /// @param EntryBlock The entry block of the current function. + /// @param P The pass that currently running. + /// + void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P); +} +#endif diff --git a/tools/polly/include/polly/TempScopInfo.h b/tools/polly/include/polly/TempScopInfo.h new file mode 100755 index 00000000000..8d342dbbc18 --- /dev/null +++ b/tools/polly/include/polly/TempScopInfo.h @@ -0,0 +1,298 @@ +//===-------- polly/TempScopInfo.h - Extract TempScops ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Collect information about the control flow regions detected by the Scop +// detection, such that this information can be translated info its polyhedral +// representation. +// +//===----------------------------------------------------------------------===// + +#ifndef POLLY_TEMP_SCOP_EXTRACTION_H +#define POLLY_TEMP_SCOP_EXTRACTION_H + +#include "polly/MayAliasSet.h" +#include "polly/ScopDetection.h" + +#include "llvm/Analysis/RegionPass.h" +#include "llvm/Instructions.h" + +namespace llvm { + class TargetData; +} + +using namespace llvm; + +namespace polly { +class MayAliasSetInfo; + +//===---------------------------------------------------------------------===// +/// @brief A memory access described by a SCEV expression and the access type. +class IRAccess { +public: + const Value *BaseAddress; + + const SCEV *Offset; + + // The type of the scev affine function + enum TypeKind { READ, WRITE }; + +private: + unsigned ElemBytes; + TypeKind Type; + bool IsAffine; + +public: + explicit IRAccess (TypeKind Type, const Value *BaseAddress, + const SCEV *Offset, unsigned elemBytes, bool Affine) + : BaseAddress(BaseAddress), Offset(Offset), + ElemBytes(elemBytes), Type(Type), IsAffine(Affine) {} + + enum TypeKind getType() const { return Type; } + + const Value *getBase() const { return BaseAddress; } + + const SCEV *getOffset() const { return Offset; } + + unsigned getElemSizeInBytes() const { return ElemBytes; } + + bool isAffine() const { return IsAffine; } + + bool isRead() const { return Type == READ; } + +}; + +class Comparison { + + const SCEV *LHS; + const SCEV *RHS; + + ICmpInst::Predicate Pred; + +public: + Comparison(const SCEV *LHS, const SCEV *RHS, ICmpInst::Predicate Pred) + : LHS(LHS), RHS(RHS), Pred(Pred) {} + + const SCEV *getLHS() const { return LHS; } + const SCEV *getRHS() const { return RHS; } + + ICmpInst::Predicate getPred() const { return Pred; } + void print(raw_ostream &OS) const; +}; + +//===---------------------------------------------------------------------===// +/// Types +// The condition of a Basicblock, combine brcond with "And" operator. +typedef SmallVector BBCond; + +/// Maps from a loop to the affine function expressing its backedge taken count. +/// The backedge taken count already enough to express iteration domain as we +/// only allow loops with canonical induction variable. +/// A canonical induction variable is: +/// an integer recurrence that starts at 0 and increments by one each time +/// through the loop. +typedef std::map LoopBoundMapType; + +/// Mapping BBs to its condition constrains +typedef std::map BBCondMapType; + +typedef std::vector > AccFuncSetType; +typedef std::map AccFuncMapType; + +//===---------------------------------------------------------------------===// +/// @brief Scop represent with llvm objects. +/// +/// A helper class for remembering the parameter number and the max depth in +/// this Scop, and others context. +class TempScop { + // The Region. + Region &R; + + // The max loop depth of this Scop + unsigned MaxLoopDepth; + + // Remember the bounds of loops, to help us build iteration domain of BBs. + const LoopBoundMapType &LoopBounds; + const BBCondMapType &BBConds; + + // Access function of bbs. + const AccFuncMapType &AccFuncMap; + + // The alias information about this SCoP. + MayAliasSetInfo *MayASInfo; + + friend class TempScopInfo; + + explicit TempScop(Region &r, LoopBoundMapType &loopBounds, + BBCondMapType &BBCmps, AccFuncMapType &accFuncMap) + : R(r), MaxLoopDepth(0), LoopBounds(loopBounds), BBConds(BBCmps), + AccFuncMap(accFuncMap), MayASInfo(new MayAliasSetInfo()) {} + +public: + ~TempScop(); + + /// @brief Get the maximum Region contained by this Scop. + /// + /// @return The maximum Region contained by this Scop. + Region &getMaxRegion() const { return R; } + + /// @brief Get the maximum loop depth of Region R. + /// + /// @return The maximum loop depth of Region R. + unsigned getMaxLoopDepth() const { return MaxLoopDepth; } + + /// @brief Get the loop bounds of the given loop. + /// + /// @param L The loop to get the bounds. + /// + /// @return The bounds of the loop L in { Lower bound, Upper bound } form. + /// + const SCEV *getLoopBound(const Loop *L) const { + LoopBoundMapType::const_iterator at = LoopBounds.find(L); + assert(at != LoopBounds.end() && "Only valid loop is allow!"); + return at->second; + } + + /// @brief Get the condition from entry block of the Scop to a BasicBlock + /// + /// @param BB The BasicBlock + /// + /// @return The condition from entry block of the Scop to a BB + /// + const BBCond *getBBCond(const BasicBlock *BB) const { + BBCondMapType::const_iterator at = BBConds.find(BB); + return at != BBConds.end() ? &(at->second) : 0; + } + + /// @brief Get all access functions in a BasicBlock + /// + /// @param BB The BasicBlock that containing the access functions. + /// + /// @return All access functions in BB + /// + const AccFuncSetType *getAccessFunctions(const BasicBlock* BB) const { + AccFuncMapType::const_iterator at = AccFuncMap.find(BB); + return at != AccFuncMap.end()? &(at->second) : 0; + } + //@} + + /// @brief Print the Temporary Scop information. + /// + /// @param OS The output stream the access functions is printed to. + /// @param SE The ScalarEvolution that help printing Temporary Scop + /// information. + /// @param LI The LoopInfo that help printing the access functions. + void print(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI) const; + + /// @brief Print the access functions and loop bounds in this Scop. + /// + /// @param OS The output stream the access functions is printed to. + /// @param SE The ScalarEvolution that help printing the access functions. + /// @param LI The LoopInfo that help printing the access functions. + void printDetail(raw_ostream &OS, ScalarEvolution *SE, + LoopInfo *LI, const Region *Reg, unsigned ind) const; +}; + +typedef std::map TempScopMapType; +//===----------------------------------------------------------------------===// +/// @brief The Function Pass to extract temporary information for Static control +/// part in llvm function. +/// +class TempScopInfo : public FunctionPass { + //===-------------------------------------------------------------------===// + // DO NOT IMPLEMENT + TempScopInfo(const TempScopInfo &); + // DO NOT IMPLEMENT + const TempScopInfo &operator=(const TempScopInfo &); + + // The ScalarEvolution to help building Scop. + ScalarEvolution* SE; + + // LoopInfo for information about loops + LoopInfo *LI; + + // The AliasAnalysis to build AliasSetTracker. + AliasAnalysis *AA; + + // Valid Regions for Scop + ScopDetection *SD; + + // For condition extraction support. + DominatorTree *DT; + PostDominatorTree *PDT; + + // Target data for element size computing. + TargetData *TD; + + // Remember the bounds of loops, to help us build iteration domain of BBs. + LoopBoundMapType LoopBounds; + + // And also Remember the constrains for BBs + BBCondMapType BBConds; + + // Access function of bbs. + AccFuncMapType AccFuncMap; + + // Mapping regions to the corresponding Scop in current function. + TempScopMapType TempScops; + + // Clear the context. + void clear(); + + /// @brief Build condition constrains to BBs in a valid Scop. + /// + /// @param BB The BasicBlock to build condition constrains + /// @param RegionEntry The entry block of the Smallest Region that containing + /// BB + /// @param Cond The built condition + void buildCondition(BasicBlock *BB, BasicBlock *Region, TempScop &Scop); + + // Build the affine function of the given condition + void buildAffineCondition(Value &V, bool inverted, Comparison **Comp, + TempScop &Scop) const; + + // Return the temporary Scop information of Region R, where R must be a valid + // part of Scop + TempScop *getTempScop(Region &R); + + // Build the temprory information of Region R, where R must be a valid part + // of Scop. + TempScop *buildTempScop(Region &R); + + void buildAccessFunctions(Region &RefRegion, BasicBlock &BB); + + void buildLoopBounds(TempScop &Scop); + +public: + static char ID; + explicit TempScopInfo() : FunctionPass(ID) {} + ~TempScopInfo(); + + /// @brief Get the temporay Scop information in LLVM IR represent + /// for Region R. + /// + /// @return The Scop information in LLVM IR represent. + TempScop *getTempScop(const Region *R) const; + + /// @name FunctionPass interface + //@{ + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual void releaseMemory() { clear(); } + virtual bool runOnFunction(Function &F); + virtual void print(raw_ostream &OS, const Module *) const; + //@} +}; + +} // end namespace polly + +namespace llvm { + class PassRegistry; + void initializeTempScopInfoPass(llvm::PassRegistry&); +} + +#endif diff --git a/tools/polly/lib/Analysis/CMakeLists.txt b/tools/polly/lib/Analysis/CMakeLists.txt new file mode 100644 index 00000000000..9e46527cc6d --- /dev/null +++ b/tools/polly/lib/Analysis/CMakeLists.txt @@ -0,0 +1,8 @@ +add_polly_library(PollyAnalysis + Dependences.cpp + ScopDetection.cpp + ScopInfo.cpp + ScopGraphPrinter.cpp + ScopPass.cpp + TempScopInfo.cpp +) diff --git a/tools/polly/lib/Analysis/Dependences.cpp b/tools/polly/lib/Analysis/Dependences.cpp new file mode 100644 index 00000000000..dc3f8818a7d --- /dev/null +++ b/tools/polly/lib/Analysis/Dependences.cpp @@ -0,0 +1,438 @@ +//===- Dependency.cpp - Calculate dependency information for a Scop. -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Calculate the data dependency relations for a Scop using ISL. +// +// The integer set library (ISL) from Sven, has a integrated dependency analysis +// to calculate data dependences. This pass takes advantage of this and +// calculate those dependences a Scop. +// +// The dependences in this pass are exact in terms that for a specific read +// statement instance only the last write statement instance is returned. In +// case of may writes a set of possible write instances is returned. This +// analysis will never produce redundant dependences. +// +//===----------------------------------------------------------------------===// +// +#include "polly/Dependences.h" + +#include "polly/LinkAllPasses.h" +#include "polly/ScopInfo.h" +#include "polly/Support/GICHelper.h" + +#define DEBUG_TYPE "polly-dependences" +#include "llvm/Support/Debug.h" +#include "llvm/Support/CommandLine.h" + +#include +#define CLOOG_INT_GMP 1 +#include +#include + +using namespace polly; +using namespace llvm; + +static cl::opt + LegalityCheckDisabled("disable-polly-legality", + cl::desc("Disable polly legality check"), cl::Hidden, + cl::init(false)); + +//===----------------------------------------------------------------------===// +Dependences::Dependences() : ScopPass(ID) { + must_dep = may_dep = NULL; + must_no_source = may_no_source = NULL; + sink = must_source = may_source = NULL; + war_dep = waw_dep = NULL; +} + +bool Dependences::runOnScop(Scop &S) { + isl_space *Space = S.getParamSpace(); + + if (sink) + isl_union_map_free(sink); + + if (must_source) + isl_union_map_free(must_source); + + if (may_source) + isl_union_map_free(may_source); + + sink = isl_union_map_empty(isl_space_copy(Space)); + must_source = isl_union_map_empty(isl_space_copy(Space)); + may_source = isl_union_map_empty(isl_space_copy(Space)); + isl_union_map *schedule = isl_union_map_empty(Space); + + if (must_dep) + isl_union_map_free(must_dep); + + if (may_dep) + isl_union_map_free(may_dep); + + if (must_no_source) + isl_union_map_free(must_no_source); + + if (may_no_source) + isl_union_map_free(may_no_source); + + if (war_dep) + isl_union_map_free(war_dep); + + if (waw_dep) + isl_union_map_free(waw_dep); + + must_dep = may_dep = NULL; + must_no_source = may_no_source = NULL; + + war_dep = waw_dep = NULL; + + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + for (ScopStmt::memacc_iterator MI = Stmt->memacc_begin(), + ME = Stmt->memacc_end(); MI != ME; ++MI) { + isl_set *domcp = Stmt->getDomain(); + isl_map *accdom = (*MI)->getAccessRelation(); + + accdom = isl_map_intersect_domain(accdom, domcp); + + if ((*MI)->isRead()) + sink = isl_union_map_add_map(sink, accdom); + else + must_source = isl_union_map_add_map(must_source, accdom); + } + schedule = isl_union_map_add_map(schedule, Stmt->getScattering()); + } + + DEBUG( + dbgs().indent(4) << "Sink:\n"; + dbgs().indent(8) << stringFromIslObj(sink) << "\n"; + + dbgs().indent(4) << "MustSource:\n"; + dbgs().indent(8) << stringFromIslObj(must_source) << "\n"; + + dbgs().indent(4) << "MaySource:\n"; + dbgs().indent(8) << stringFromIslObj(may_source) << "\n"; + + dbgs().indent(4) << "Schedule:\n"; + dbgs().indent(8) << stringFromIslObj(schedule) << "\n"; + ); + + isl_union_map_compute_flow(isl_union_map_copy(sink), + isl_union_map_copy(must_source), + isl_union_map_copy(may_source), + isl_union_map_copy(schedule), + &must_dep, &may_dep, &must_no_source, + &may_no_source); + + isl_union_map_compute_flow(isl_union_map_copy(must_source), + isl_union_map_copy(must_source), + isl_union_map_copy(sink), schedule, + &waw_dep, &war_dep, NULL, NULL); + + // Remove redundant statements. + must_dep = isl_union_map_coalesce(must_dep); + may_dep = isl_union_map_coalesce(may_dep); + must_no_source = isl_union_map_coalesce(must_no_source); + may_no_source = isl_union_map_coalesce(may_no_source); + waw_dep = isl_union_map_coalesce(waw_dep); + war_dep = isl_union_map_coalesce(war_dep); + + return false; +} + +bool Dependences::isValidScattering(StatementToIslMapTy *NewScattering) { + Scop &S = getCurScop(); + + if (LegalityCheckDisabled) + return true; + + isl_space *Space = S.getParamSpace(); + + isl_union_map *schedule = isl_union_map_empty(Space); + + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + isl_map *scattering; + + if (NewScattering->find(*SI) == NewScattering->end()) + scattering = Stmt->getScattering(); + else + scattering = isl_map_copy((*NewScattering)[Stmt]); + + schedule = isl_union_map_add_map(schedule, scattering); + } + + isl_union_map *temp_must_dep, *temp_may_dep; + isl_union_map *temp_must_no_source, *temp_may_no_source; + + DEBUG( + dbgs().indent(4) << "Sink :=\n"; + dbgs().indent(8) << stringFromIslObj(sink) << ";\n"; + + dbgs().indent(4) << "MustSource :=\n"; + dbgs().indent(8) << stringFromIslObj(must_source) << ";\n"; + + dbgs().indent(4) << "MaySource :=\n"; + dbgs().indent(8) << stringFromIslObj(may_source) << ";\n"; + + dbgs().indent(4) << "Schedule :=\n"; + dbgs().indent(8) << stringFromIslObj(schedule) << ";\n"; + ); + + isl_union_map_compute_flow(isl_union_map_copy(sink), + isl_union_map_copy(must_source), + isl_union_map_copy(may_source), schedule, + &temp_must_dep, &temp_may_dep, + &temp_must_no_source, &temp_may_no_source); + + DEBUG(dbgs().indent(4) << "\nDependences calculated\n"); + DEBUG( + dbgs().indent(4) << "TempMustDep:=\n"; + dbgs().indent(8) << stringFromIslObj(temp_must_dep) << ";\n"; + + dbgs().indent(4) << "MustDep:=\n"; + dbgs().indent(8) << stringFromIslObj(must_dep) << ";\n"; + ); + + // Remove redundant statements. + temp_must_dep = isl_union_map_coalesce(temp_must_dep); + temp_may_dep = isl_union_map_coalesce(temp_may_dep); + temp_must_no_source = isl_union_map_coalesce(temp_must_no_source); + temp_may_no_source = isl_union_map_coalesce(temp_may_no_source); + + bool isValid = true; + + if (!isl_union_map_is_equal(temp_must_dep, must_dep)) { + DEBUG(dbgs().indent(4) << "\nEqual 1 calculated\n"); + isValid = false; + } + + DEBUG(dbgs().indent(4) << "\nEqual 1 calculated\n"); + + if (!isl_union_map_is_equal(temp_may_dep, may_dep)) + isValid = false; + + DEBUG(dbgs().indent(4) << "\nEqual 2 calculated\n"); + + if (!isl_union_map_is_equal(temp_must_no_source, must_no_source)) + isValid = false; + + if (!isl_union_map_is_equal(temp_may_no_source, may_no_source)) + isValid = false; + + isl_union_map_free(temp_must_dep); + isl_union_map_free(temp_may_dep); + isl_union_map_free(temp_must_no_source); + isl_union_map_free(temp_may_no_source); + + return isValid; +} + +isl_union_map *getCombinedScheduleForSpace(Scop *scop, unsigned dimLevel) { + isl_space *Space = scop->getParamSpace(); + isl_union_map *schedule = isl_union_map_empty(Space); + + for (Scop::iterator SI = scop->begin(), SE = scop->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + unsigned remainingDimensions = Stmt->getNumScattering() - dimLevel; + isl_map *Scattering = isl_map_project_out(Stmt->getScattering(), + isl_dim_out, dimLevel, + remainingDimensions); + schedule = isl_union_map_add_map(schedule, Scattering); + } + + return schedule; +} + +bool Dependences::isParallelDimension(isl_set *loopDomain, + unsigned parallelDimension) { + Scop *S = &getCurScop(); + isl_union_map *schedule = getCombinedScheduleForSpace(S, parallelDimension); + + // Calculate distance vector. + isl_union_set *scheduleSubset; + isl_union_map *scheduleDeps, *restrictedDeps; + isl_union_map *scheduleDeps_war, *restrictedDeps_war; + isl_union_map *scheduleDeps_waw, *restrictedDeps_waw; + + scheduleSubset = isl_union_set_from_set(isl_set_copy(loopDomain)); + + scheduleDeps = isl_union_map_apply_range(isl_union_map_copy(must_dep), + isl_union_map_copy(schedule)); + scheduleDeps = isl_union_map_apply_domain(scheduleDeps, + isl_union_map_copy(schedule)); + + scheduleDeps_war = isl_union_map_apply_range(isl_union_map_copy(war_dep), + isl_union_map_copy(schedule)); + scheduleDeps_war = isl_union_map_apply_domain(scheduleDeps_war, + isl_union_map_copy(schedule)); + + scheduleDeps_waw = isl_union_map_apply_range(isl_union_map_copy(waw_dep), + isl_union_map_copy(schedule)); + scheduleDeps_waw = isl_union_map_apply_domain(scheduleDeps_waw, schedule); + + // Dependences need to originate and to terminate in the scheduling space + // enumerated by this loop. + restrictedDeps = isl_union_map_intersect_domain(scheduleDeps, + isl_union_set_copy(scheduleSubset)); + restrictedDeps = isl_union_map_intersect_range(restrictedDeps, + isl_union_set_copy(scheduleSubset)); + + isl_union_set *distance = isl_union_map_deltas(restrictedDeps); + + restrictedDeps_war = isl_union_map_intersect_domain(scheduleDeps_war, + isl_union_set_copy(scheduleSubset)); + restrictedDeps_war = isl_union_map_intersect_range(restrictedDeps_war, + isl_union_set_copy(scheduleSubset)); + + isl_union_set *distance_war = isl_union_map_deltas(restrictedDeps_war); + + restrictedDeps_waw = isl_union_map_intersect_domain(scheduleDeps_waw, + isl_union_set_copy(scheduleSubset)); + restrictedDeps_waw = isl_union_map_intersect_range(restrictedDeps_waw, + scheduleSubset); + + isl_union_set *distance_waw = isl_union_map_deltas(restrictedDeps_waw); + + isl_space *Space = isl_space_set_alloc(S->getIslCtx(), 0, parallelDimension); + + // [0, 0, 0, 0] - All zero + isl_set *allZero = isl_set_universe(isl_space_copy(Space)); + unsigned dimensions = isl_space_dim(Space, isl_dim_set); + + for (unsigned i = 0; i < dimensions; i++) + allZero = isl_set_fix_si(allZero, isl_dim_set, i, 0); + + allZero = isl_set_align_params(allZero, S->getParamSpace()); + + // All zero, last unknown. + // [0, 0, 0, ?] + isl_set *lastUnknown = isl_set_universe(isl_space_copy(Space)); + + for (unsigned i = 0; i < dimensions - 1; i++) + lastUnknown = isl_set_fix_si(lastUnknown, isl_dim_set, i, 0); + + lastUnknown = isl_set_align_params(lastUnknown, S->getParamSpace()); + + // Valid distance vectors + isl_set *validDistances = isl_set_subtract(lastUnknown, allZero); + validDistances = isl_set_complement(validDistances); + isl_union_set *validDistancesUS = isl_union_set_from_set(validDistances); + + isl_union_set *nonValid = isl_union_set_subtract(distance, + isl_union_set_copy(validDistancesUS)); + + isl_union_set *nonValid_war = isl_union_set_subtract(distance_war, + isl_union_set_copy(validDistancesUS)); + + isl_union_set *nonValid_waw = isl_union_set_subtract(distance_waw, + validDistancesUS); + bool is_parallel = isl_union_set_is_empty(nonValid) + && isl_union_set_is_empty(nonValid_war) + && isl_union_set_is_empty(nonValid_waw); + + isl_space_free(Space); + isl_union_set_free(nonValid); + isl_union_set_free(nonValid_war); + isl_union_set_free(nonValid_waw); + + return is_parallel; +} + +bool Dependences::isParallelFor(const clast_for *f) { + isl_set *loopDomain = isl_set_from_cloog_domain(f->domain); + assert(loopDomain && "Cannot access domain of loop"); + + return isParallelDimension(loopDomain, isl_set_n_dim(loopDomain)); +} + +void Dependences::printScop(raw_ostream &OS) const { + OS.indent(4) << "Must dependences:\n"; + OS.indent(8) << stringFromIslObj(must_dep) << "\n"; + + OS.indent(4) << "May dependences:\n"; + OS.indent(8) << stringFromIslObj(may_dep) << "\n"; + + OS.indent(4) << "Must no source:\n"; + OS.indent(8) << stringFromIslObj(must_no_source) << "\n"; + + OS.indent(4) << "May no source:\n"; + OS.indent(8) << stringFromIslObj(may_no_source) << "\n"; +} + +void Dependences::releaseMemory() { + if (must_dep) + isl_union_map_free(must_dep); + + if (may_dep) + isl_union_map_free(may_dep); + + if (must_no_source) + isl_union_map_free(must_no_source); + + if (may_no_source) + isl_union_map_free(may_no_source); + + if (war_dep) + isl_union_map_free(war_dep); + + if (waw_dep) + isl_union_map_free(waw_dep); + + must_dep = may_dep = NULL; + must_no_source = may_no_source = NULL; + war_dep = waw_dep = NULL; + + if (sink) + isl_union_map_free(sink); + + if (must_source) + isl_union_map_free(must_source); + + if (may_source) + isl_union_map_free(may_source); + + sink = must_source = may_source = NULL; +} + +isl_union_map *Dependences::getDependences(int type) { + isl_space *Space = isl_union_map_get_space(must_dep); + isl_union_map *dependences = isl_union_map_empty(Space); + + if (type & TYPE_RAW) + dependences = isl_union_map_union(dependences, + isl_union_map_copy(must_dep)); + + if (type & TYPE_WAR) + dependences = isl_union_map_union(dependences, + isl_union_map_copy(war_dep)); + + if (type & TYPE_WAW) + dependences = isl_union_map_union(dependences, + isl_union_map_copy(waw_dep)); + + return isl_union_map_coalesce(dependences); +} + +void Dependences::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); +} + +char Dependences::ID = 0; + +INITIALIZE_PASS_BEGIN(Dependences, "polly-dependences", + "Polly - Calculate dependences", false, false) +INITIALIZE_PASS_DEPENDENCY(ScopInfo) +INITIALIZE_PASS_END(Dependences, "polly-dependences", + "Polly - Calculate dependences", false, false) + +Pass *polly::createDependencesPass() { + return new Dependences(); +} diff --git a/tools/polly/lib/Analysis/Makefile b/tools/polly/lib/Analysis/Makefile new file mode 100755 index 00000000000..bf94f52ab1c --- /dev/null +++ b/tools/polly/lib/Analysis/Makefile @@ -0,0 +1,17 @@ +##===- polly/lib/Exchange/Makefile ----------------*- Makefile -*-===## + +# +# Indicate where we are relative to the top of the source tree. +# +LEVEL=../.. + +LIBRARYNAME=pollyanalysis +USEDLIBS = pollysupport.a +BUILD_ARCHIVE = 1 + +CPP.Flags += $(POLLY_INC) + +# +# Include Makefile.common so we know what to do. +# +include $(LEVEL)/Makefile.common diff --git a/tools/polly/lib/Analysis/ScopDetection.cpp b/tools/polly/lib/Analysis/ScopDetection.cpp new file mode 100644 index 00000000000..667543548d6 --- /dev/null +++ b/tools/polly/lib/Analysis/ScopDetection.cpp @@ -0,0 +1,598 @@ +//===----- ScopDetection.cpp - Detect Scops --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Detect the maximal Scops of a function. +// +// A static control part (Scop) is a subgraph of the control flow graph (CFG) +// that only has statically known control flow and can therefore be described +// within the polyhedral model. +// +// Every Scop fullfills these restrictions: +// +// * It is a single entry single exit region +// +// * Only affine linear bounds in the loops +// +// Every natural loop in a Scop must have a number of loop iterations that can +// be described as an affine linear function in surrounding loop iterators or +// parameters. (A parameter is a scalar that does not change its value during +// execution of the Scop). +// +// * Only comparisons of affine linear expressions in conditions +// +// * All loops and conditions perfectly nested +// +// The control flow needs to be structured such that it could be written using +// just 'for' and 'if' statements, without the need for any 'goto', 'break' or +// 'continue'. +// +// * Side effect free functions call +// +// Only function calls and intrinsics that do not have side effects are allowed +// (readnone). +// +// The Scop detection finds the largest Scops by checking if the largest +// region is a Scop. If this is not the case, its canonical subregions are +// checked until a region is a Scop. It is now tried to extend this Scop by +// creating a larger non canonical region. +// +//===----------------------------------------------------------------------===// + +#include "polly/ScopDetection.h" + +#include "polly/LinkAllPasses.h" +#include "polly/Support/ScopHelper.h" +#include "polly/Support/SCEVValidator.h" + +#include "llvm/LLVMContext.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/RegionIterator.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Assembly/Writer.h" + +#define DEBUG_TYPE "polly-detect" +#include "llvm/Support/Debug.h" + +#include + +using namespace llvm; +using namespace polly; + +static cl::opt +OnlyFunction("polly-detect-only", + cl::desc("Only detect scops in function"), cl::Hidden, + cl::value_desc("The function name to detect scops in"), + cl::ValueRequired, cl::init("")); + +static cl::opt +IgnoreAliasing("polly-ignore-aliasing", + cl::desc("Ignore possible aliasing of the array bases"), + cl::Hidden, cl::init(false)); + +static cl::opt +AllowNonAffine("polly-allow-nonaffine", + cl::desc("Allow non affine access functions in arrays"), + cl::Hidden, cl::init(false)); + +//===----------------------------------------------------------------------===// +// Statistics. + +STATISTIC(ValidRegion, "Number of regions that a valid part of Scop"); + +#define BADSCOP_STAT(NAME, DESC) STATISTIC(Bad##NAME##ForScop, \ + "Number of bad regions for Scop: "\ + DESC) + +#define INVALID(NAME, MESSAGE) \ + do { \ + std::string Buf; \ + raw_string_ostream fmt(Buf); \ + fmt << MESSAGE; \ + fmt.flush(); \ + LastFailure = Buf; \ + DEBUG(dbgs() << MESSAGE); \ + DEBUG(dbgs() << "\n"); \ + assert(!Context.Verifying && #NAME); \ + if (!Context.Verifying) ++Bad##NAME##ForScop; \ + return false; \ + } while (0); + + +#define INVALID_NOVERIFY(NAME, MESSAGE) \ + do { \ + std::string Buf; \ + raw_string_ostream fmt(Buf); \ + fmt << MESSAGE; \ + fmt.flush(); \ + LastFailure = Buf; \ + DEBUG(dbgs() << MESSAGE); \ + DEBUG(dbgs() << "\n"); \ + /* DISABLED: assert(!Context.Verifying && #NAME); */ \ + if (!Context.Verifying) ++Bad##NAME##ForScop; \ + return false; \ + } while (0); + + +BADSCOP_STAT(CFG, "CFG too complex"); +BADSCOP_STAT(IndVar, "Non canonical induction variable in loop"); +BADSCOP_STAT(LoopBound, "Loop bounds can not be computed"); +BADSCOP_STAT(FuncCall, "Function call with side effects appeared"); +BADSCOP_STAT(AffFunc, "Expression not affine"); +BADSCOP_STAT(Scalar, "Found scalar dependency"); +BADSCOP_STAT(Alias, "Found base address alias"); +BADSCOP_STAT(SimpleRegion, "Region not simple"); +BADSCOP_STAT(Other, "Others"); + +//===----------------------------------------------------------------------===// +// ScopDetection. +bool ScopDetection::isMaxRegionInScop(const Region &R) const { + // The Region is valid only if it could be found in the set. + return ValidRegions.count(&R); +} + +std::string ScopDetection::regionIsInvalidBecause(const Region *R) const { + if (!InvalidRegions.count(R)) + return ""; + + return InvalidRegions.find(R)->second; +} + +bool ScopDetection::isValidCFG(BasicBlock &BB, DetectionContext &Context) const +{ + Region &RefRegion = Context.CurRegion; + TerminatorInst *TI = BB.getTerminator(); + + // Return instructions are only valid if the region is the top level region. + if (isa(TI) && !RefRegion.getExit() && TI->getNumOperands() == 0) + return true; + + BranchInst *Br = dyn_cast(TI); + + if (!Br) + INVALID(CFG, "Non branch instruction terminates BB: " + BB.getName()); + + if (Br->isUnconditional()) return true; + + Value *Condition = Br->getCondition(); + + // UndefValue is not allowed as condition. + if (isa(Condition)) + INVALID(AffFunc, "Condition based on 'undef' value in BB: " + + BB.getName()); + + // Only Constant and ICmpInst are allowed as condition. + if (!(isa(Condition) || isa(Condition))) + INVALID(AffFunc, "Condition in BB '" + BB.getName() + "' neither " + "constant nor an icmp instruction"); + + // Allow perfectly nested conditions. + assert(Br->getNumSuccessors() == 2 && "Unexpected number of successors"); + + if (ICmpInst *ICmp = dyn_cast(Condition)) { + // Unsigned comparisons are not allowed. They trigger overflow problems + // in the code generation. + // + // TODO: This is not sufficient and just hides bugs. However it does pretty + // well. + if(ICmp->isUnsigned()) + return false; + + // Are both operands of the ICmp affine? + if (isa(ICmp->getOperand(0)) + || isa(ICmp->getOperand(1))) + INVALID(AffFunc, "undef operand in branch at BB: " + BB.getName()); + + const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0)); + const SCEV *RHS = SE->getSCEV(ICmp->getOperand(1)); + + if (!isAffineExpr(&Context.CurRegion, LHS, *SE) || + !isAffineExpr(&Context.CurRegion, RHS, *SE)) + INVALID(AffFunc, "Non affine branch in BB '" << BB.getName() + << "' with LHS: " << *LHS << " and RHS: " << *RHS); + } + + // Allow loop exit conditions. + Loop *L = LI->getLoopFor(&BB); + if (L && L->getExitingBlock() == &BB) + return true; + + // Allow perfectly nested conditions. + Region *R = RI->getRegionFor(&BB); + if (R->getEntry() != &BB) + INVALID(CFG, "Not well structured condition at BB: " + BB.getName()); + + return true; +} + +bool ScopDetection::isValidCallInst(CallInst &CI) { + if (CI.mayHaveSideEffects() || CI.doesNotReturn()) + return false; + + if (CI.doesNotAccessMemory()) + return true; + + Function *CalledFunction = CI.getCalledFunction(); + + // Indirect calls are not supported. + if (CalledFunction == 0) + return false; + + // TODO: Intrinsics. + return false; +} + +bool ScopDetection::isValidMemoryAccess(Instruction &Inst, + DetectionContext &Context) const { + Value *Ptr = getPointerOperand(Inst); + const SCEV *AccessFunction = SE->getSCEV(Ptr); + const SCEVUnknown *BasePointer; + Value *BaseValue; + + BasePointer = dyn_cast(SE->getPointerBase(AccessFunction)); + + if (!BasePointer) + INVALID(AffFunc, "No base pointer"); + + BaseValue = BasePointer->getValue(); + + if (isa(BaseValue)) + INVALID(AffFunc, "Undefined base pointer"); + + AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer); + + if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE, BaseValue) && !AllowNonAffine) + INVALID(AffFunc, "Bad memory address " << *AccessFunction); + + // FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions + // created by IndependentBlocks Pass. + if (isa(BaseValue)) + INVALID(Other, "Find bad intToptr prt: " << *BaseValue); + + // Check if the base pointer of the memory access does alias with + // any other pointer. This cannot be handled at the moment. + AliasSet &AS = + Context.AST.getAliasSetForPointer(BaseValue, AliasAnalysis::UnknownSize, + Inst.getMetadata(LLVMContext::MD_tbaa)); + + // INVALID triggers an assertion in verifying mode, if it detects that a SCoP + // was detected by SCoP detection and that this SCoP was invalidated by a pass + // that stated it would preserve the SCoPs. + // We disable this check as the independent blocks pass may create memory + // references which seem to alias, if -basicaa is not available. They actually + // do not, but as we can not proof this without -basicaa we would fail. We + // disable this check to not cause irrelevant verification failures. + if (!AS.isMustAlias() && !IgnoreAliasing) + INVALID_NOVERIFY(Alias, + "Possible aliasing for value: " << BaseValue->getName() + << "\n"); + + return true; +} + + +bool ScopDetection::hasScalarDependency(Instruction &Inst, + Region &RefRegion) const { + for (Instruction::use_iterator UI = Inst.use_begin(), UE = Inst.use_end(); + UI != UE; ++UI) + if (Instruction *Use = dyn_cast(*UI)) + if (!RefRegion.contains(Use->getParent())) { + // DirtyHack 1: PHINode user outside the Scop is not allow, if this + // PHINode is induction variable, the scalar to array transform may + // break it and introduce a non-indvar PHINode, which is not allow in + // Scop. + // This can be fix by: + // Introduce a IndependentBlockPrepare pass, which translate all + // PHINodes not in Scop to array. + // The IndependentBlockPrepare pass can also split the entry block of + // the function to hold the alloca instruction created by scalar to + // array. and split the exit block of the Scop so the new create load + // instruction for escape users will not break other Scops. + if (isa(Use)) + return true; + } + + return false; +} + +bool ScopDetection::isValidInstruction(Instruction &Inst, + DetectionContext &Context) const { + // Only canonical IVs are allowed. + if (PHINode *PN = dyn_cast(&Inst)) + if (!isIndVar(PN, LI)) + INVALID(IndVar, "Non canonical PHI node: " << Inst); + + // Scalar dependencies are not allowed. + if (hasScalarDependency(Inst, Context.CurRegion)) + INVALID(Scalar, "Scalar dependency found: " << Inst); + + // We only check the call instruction but not invoke instruction. + if (CallInst *CI = dyn_cast(&Inst)) { + if (isValidCallInst(*CI)) + return true; + + INVALID(FuncCall, "Call instruction: " << Inst); + } + + if (!Inst.mayWriteToMemory() && !Inst.mayReadFromMemory()) { + // Handle cast instruction. + if (isa(Inst) || isa(Inst)) + INVALID(Other, "Cast instruction: " << Inst); + + if (isa(Inst)) + INVALID(Other, "Alloca instruction: " << Inst); + + return true; + } + + // Check the access function. + if (isa(Inst) || isa(Inst)) + return isValidMemoryAccess(Inst, Context); + + // We do not know this instruction, therefore we assume it is invalid. + INVALID(Other, "Unknown instruction: " << Inst); +} + +bool ScopDetection::isValidBasicBlock(BasicBlock &BB, + DetectionContext &Context) const { + if (!isValidCFG(BB, Context)) + return false; + + // Check all instructions, except the terminator instruction. + for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) + if (!isValidInstruction(*I, Context)) + return false; + + Loop *L = LI->getLoopFor(&BB); + if (L && L->getHeader() == &BB && !isValidLoop(L, Context)) + return false; + + return true; +} + +bool ScopDetection::isValidLoop(Loop *L, DetectionContext &Context) const { + PHINode *IndVar = L->getCanonicalInductionVariable(); + // No canonical induction variable. + if (!IndVar) + INVALID(IndVar, "No canonical IV at loop header: " + << L->getHeader()->getName()); + + // Is the loop count affine? + const SCEV *LoopCount = SE->getBackedgeTakenCount(L); + if (!isAffineExpr(&Context.CurRegion, LoopCount, *SE)) + INVALID(LoopBound, "Non affine loop bound '" << *LoopCount << "' in loop: " + << L->getHeader()->getName()); + + return true; +} + +Region *ScopDetection::expandRegion(Region &R) { + Region *CurrentRegion = &R; + Region *TmpRegion = R.getExpandedRegion(); + + DEBUG(dbgs() << "\tExpanding " << R.getNameStr() << "\n"); + + while (TmpRegion) { + DetectionContext Context(*TmpRegion, *AA, false /*verifying*/); + DEBUG(dbgs() << "\t\tTrying " << TmpRegion->getNameStr() << "\n"); + + if (!allBlocksValid(Context)) + break; + + if (isValidExit(Context)) { + if (CurrentRegion != &R) + delete CurrentRegion; + + CurrentRegion = TmpRegion; + } + + Region *TmpRegion2 = TmpRegion->getExpandedRegion(); + + if (TmpRegion != &R && TmpRegion != CurrentRegion) + delete TmpRegion; + + TmpRegion = TmpRegion2; + } + + if (&R == CurrentRegion) + return NULL; + + DEBUG(dbgs() << "\tto " << CurrentRegion->getNameStr() << "\n"); + + return CurrentRegion; +} + + +void ScopDetection::findScops(Region &R) { + DetectionContext Context(R, *AA, false /*verifying*/); + + LastFailure = ""; + + if (isValidRegion(Context)) { + ++ValidRegion; + ValidRegions.insert(&R); + return; + } + + InvalidRegions[&R] = LastFailure; + + for (Region::iterator I = R.begin(), E = R.end(); I != E; ++I) + findScops(**I); + + // Try to expand regions. + // + // As the region tree normally only contains canonical regions, non canonical + // regions that form a Scop are not found. Therefore, those non canonical + // regions are checked by expanding the canonical ones. + + std::vector ToExpand; + + for (Region::iterator I = R.begin(), E = R.end(); I != E; ++I) + ToExpand.push_back(*I); + + for (std::vector::iterator RI = ToExpand.begin(), + RE = ToExpand.end(); RI != RE; ++RI) { + Region *CurrentRegion = *RI; + + // Skip invalid regions. Regions may become invalid, if they are element of + // an already expanded region. + if (ValidRegions.find(CurrentRegion) == ValidRegions.end()) + continue; + + Region *ExpandedR = expandRegion(*CurrentRegion); + + if (!ExpandedR) + continue; + + R.addSubRegion(ExpandedR, true); + ValidRegions.insert(ExpandedR); + ValidRegions.erase(CurrentRegion); + + for (Region::iterator I = ExpandedR->begin(), E = ExpandedR->end(); I != E; + ++I) + ValidRegions.erase(*I); + } +} + +bool ScopDetection::allBlocksValid(DetectionContext &Context) const { + Region &R = Context.CurRegion; + + for (Region::block_iterator I = R.block_begin(), E = R.block_end(); I != E; + ++I) + if (!isValidBasicBlock(*(I->getNodeAs()), Context)) + return false; + + return true; +} + +bool ScopDetection::isValidExit(DetectionContext &Context) const { + Region &R = Context.CurRegion; + + // PHI nodes are not allowed in the exit basic block. + if (BasicBlock *Exit = R.getExit()) { + BasicBlock::iterator I = Exit->begin(); + if (I != Exit->end() && isa (*I)) + INVALID(Other, "PHI node in exit BB"); + } + + return true; +} + +bool ScopDetection::isValidRegion(DetectionContext &Context) const { + Region &R = Context.CurRegion; + + DEBUG(dbgs() << "Checking region: " << R.getNameStr() << "\n\t"); + + // The toplevel region is no valid region. + if (!R.getParent()) { + DEBUG(dbgs() << "Top level region is invalid"; + dbgs() << "\n"); + return false; + } + + // SCoP can not contains the entry block of the function, because we need + // to insert alloca instruction there when translate scalar to array. + if (R.getEntry() == &(R.getEntry()->getParent()->getEntryBlock())) + INVALID(Other, "Region containing entry block of function is invalid!"); + + // Only a simple region is allowed. + if (!R.isSimple()) + INVALID(SimpleRegion, "Region not simple: " << R.getNameStr()); + + if (!allBlocksValid(Context)) + return false; + + if (!isValidExit(Context)) + return false; + + DEBUG(dbgs() << "OK\n"); + return true; +} + +bool ScopDetection::isValidFunction(llvm::Function &F) { + return !InvalidFunctions.count(&F); +} + +bool ScopDetection::runOnFunction(llvm::Function &F) { + AA = &getAnalysis(); + SE = &getAnalysis(); + LI = &getAnalysis(); + RI = &getAnalysis(); + Region *TopRegion = RI->getTopLevelRegion(); + + releaseMemory(); + + if (OnlyFunction != "" && F.getName() != OnlyFunction) + return false; + + if(!isValidFunction(F)) + return false; + + findScops(*TopRegion); + return false; +} + + +void polly::ScopDetection::verifyRegion(const Region &R) const { + assert(isMaxRegionInScop(R) && "Expect R is a valid region."); + DetectionContext Context(const_cast(R), *AA, true /*verifying*/); + isValidRegion(Context); +} + +void polly::ScopDetection::verifyAnalysis() const { + for (RegionSet::const_iterator I = ValidRegions.begin(), + E = ValidRegions.end(); I != E; ++I) + verifyRegion(**I); +} + +void ScopDetection::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + // We also need AA and RegionInfo when we are verifying analysis. + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + AU.setPreservesAll(); +} + +void ScopDetection::print(raw_ostream &OS, const Module *) const { + for (RegionSet::const_iterator I = ValidRegions.begin(), + E = ValidRegions.end(); I != E; ++I) + OS << "Valid Region for Scop: " << (*I)->getNameStr() << '\n'; + + OS << "\n"; +} + +void ScopDetection::releaseMemory() { + ValidRegions.clear(); + InvalidRegions.clear(); + // Do not clear the invalid function set. +} + +char ScopDetection::ID = 0; + +INITIALIZE_PASS_BEGIN(ScopDetection, "polly-detect", + "Polly - Detect static control parts (SCoPs)", false, + false) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) +INITIALIZE_PASS_DEPENDENCY(RegionInfo) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) +INITIALIZE_PASS_END(ScopDetection, "polly-detect", + "Polly - Detect static control parts (SCoPs)", false, false) + +Pass *polly::createScopDetectionPass() { + return new ScopDetection(); +} diff --git a/tools/polly/lib/Analysis/ScopGraphPrinter.cpp b/tools/polly/lib/Analysis/ScopGraphPrinter.cpp new file mode 100644 index 00000000000..665e119a48f --- /dev/null +++ b/tools/polly/lib/Analysis/ScopGraphPrinter.cpp @@ -0,0 +1,216 @@ +//===- GraphPrinter.cpp - Create a DOT output describing the Scop. --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Create a DOT output describing the Scop. +// +// For each function a dot file is created that shows the control flow graph of +// the function and highlights the detected Scops. +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" +#include "polly/ScopDetection.h" + +#include "llvm/Analysis/DOTGraphTraitsPass.h" +#include "llvm/Analysis/RegionInfo.h" +#include "llvm/Analysis/RegionIterator.h" + +using namespace polly; +using namespace llvm; + +namespace llvm { + template <> struct GraphTraits + : public GraphTraits { + + static NodeType *getEntryNode(ScopDetection *SD) { + return GraphTraits::getEntryNode(SD->getRI()); + } + static nodes_iterator nodes_begin(ScopDetection *SD) { + return nodes_iterator::begin(getEntryNode(SD)); + } + static nodes_iterator nodes_end(ScopDetection *SD) { + return nodes_iterator::end(getEntryNode(SD)); + } + }; + +template<> +struct DOTGraphTraits : public DefaultDOTGraphTraits { + + DOTGraphTraits (bool isSimple=false) + : DefaultDOTGraphTraits(isSimple) {} + + std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) { + + if (!Node->isSubRegion()) { + BasicBlock *BB = Node->getNodeAs(); + + if (isSimple()) + return DOTGraphTraits + ::getSimpleNodeLabel(BB, BB->getParent()); + else + return DOTGraphTraits + ::getCompleteNodeLabel(BB, BB->getParent()); + } + + return "Not implemented"; + } +}; + +template<> +struct DOTGraphTraits : public DOTGraphTraits { + DOTGraphTraits (bool isSimple=false) + : DOTGraphTraits(isSimple) {} + static std::string getGraphName(ScopDetection *SD) { + return "Scop Graph"; + } + + std::string getEdgeAttributes(RegionNode *srcNode, + GraphTraits::ChildIteratorType CI, ScopDetection *SD) { + + RegionNode *destNode = *CI; + + if (srcNode->isSubRegion() || destNode->isSubRegion()) + return ""; + + // In case of a backedge, do not use it to define the layout of the nodes. + BasicBlock *srcBB = srcNode->getNodeAs(); + BasicBlock *destBB = destNode->getNodeAs(); + + RegionInfo *RI = SD->getRI(); + Region *R = RI->getRegionFor(destBB); + + while (R && R->getParent()) + if (R->getParent()->getEntry() == destBB) + R = R->getParent(); + else + break; + + if (R->getEntry() == destBB && R->contains(srcBB)) + return "constraint=false"; + + return ""; + } + + std::string getNodeLabel(RegionNode *Node, ScopDetection *SD) { + return DOTGraphTraits + ::getNodeLabel(Node, SD->getRI()->getTopLevelRegion()); + } + // Print the cluster of the subregions. This groups the single basic blocks + // and adds a different background color for each group. + static void printRegionCluster(const ScopDetection *SD, const Region *R, + raw_ostream &O, unsigned depth = 0) { + O.indent(2 * depth) << "subgraph cluster_" << static_cast(R) + << " {\n"; + std::string ErrorMessage = SD->regionIsInvalidBecause(R); + O.indent(2 * (depth + 1)) << "label = \"" << ErrorMessage << "\";\n"; + + if (SD->isMaxRegionInScop(*R)) { + O.indent(2 * (depth + 1)) << "style = filled;\n"; + + // Set color to green. + O.indent(2 * (depth + 1)) << "color = 3"; + } else { + O.indent(2 * (depth + 1)) << "style = solid;\n"; + + int color = (R->getDepth() * 2 % 12) + 1; + + // We do not want green again. + if (color == 3) + color = 6; + + O.indent(2 * (depth + 1)) << "color = " + << color << "\n"; + } + + for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI) + printRegionCluster(SD, *RI, O, depth + 1); + + RegionInfo *RI = R->getRegionInfo(); + + for (Region::const_block_iterator BI = R->block_begin(), + BE = R->block_end(); BI != BE; ++BI) { + BasicBlock *BB = (*BI)->getNodeAs(); + if (RI->getRegionFor(BB) == R) + O.indent(2 * (depth + 1)) << "Node" + << static_cast(RI->getTopLevelRegion()->getBBNode(BB)) + << ";\n"; + } + + O.indent(2 * depth) << "}\n"; + } + static void addCustomGraphFeatures(const ScopDetection *SD, + GraphWriter &GW) { + raw_ostream &O = GW.getOStream(); + O << "\tcolorscheme = \"paired12\"\n"; + printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4); + } +}; + +} //end namespace llvm + +struct ScopViewer + : public DOTGraphTraitsViewer { + static char ID; + ScopViewer() : DOTGraphTraitsViewer("scops", ID){} +}; +char ScopViewer::ID = 0; + +struct ScopOnlyViewer + : public DOTGraphTraitsViewer { + static char ID; + ScopOnlyViewer() + : DOTGraphTraitsViewer("scopsonly", ID){} +}; +char ScopOnlyViewer::ID = 0; + +struct ScopPrinter + : public DOTGraphTraitsPrinter { + static char ID; + ScopPrinter() : + DOTGraphTraitsPrinter("scops", ID) {} +}; +char ScopPrinter::ID = 0; + +struct ScopOnlyPrinter + : public DOTGraphTraitsPrinter { + static char ID; + ScopOnlyPrinter() : + DOTGraphTraitsPrinter("scopsonly", ID) {} +}; +char ScopOnlyPrinter::ID = 0; + +static RegisterPass +X("view-scops","Polly - View Scops of function"); + +static RegisterPass +Y("view-scops-only", + "Polly - View Scops of function (with no function bodies)"); + +static RegisterPass +M("dot-scops", "Polly - Print Scops of function"); + +static RegisterPass +N("dot-scops-only", + "Polly - Print Scops of function (with no function bodies)"); + +Pass *polly::createDOTViewerPass() { + return new ScopViewer(); +} + +Pass *polly::createDOTOnlyViewerPass() { + return new ScopOnlyViewer(); +} + +Pass *polly::createDOTPrinterPass() { + return new ScopPrinter(); +} + +Pass *polly::createDOTOnlyPrinterPass() { + return new ScopOnlyPrinter(); +} diff --git a/tools/polly/lib/Analysis/ScopInfo.cpp b/tools/polly/lib/Analysis/ScopInfo.cpp new file mode 100644 index 00000000000..30cfd5300ce --- /dev/null +++ b/tools/polly/lib/Analysis/ScopInfo.cpp @@ -0,0 +1,1047 @@ +//===--------- ScopInfo.cpp - Create Scops from LLVM IR ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Create a polyhedral description for a static control flow region. +// +// The pass creates a polyhedral description of the Scops detected by the Scop +// detection derived from their LLVM-IR code. +// +// This represantation is shared among several tools in the polyhedral +// community, which are e.g. Cloog, Pluto, Loopo, Graphite. +// +//===----------------------------------------------------------------------===// + +#include "polly/ScopInfo.h" + +#include "polly/TempScopInfo.h" +#include "polly/LinkAllPasses.h" +#include "polly/Support/GICHelper.h" +#include "polly/Support/ScopHelper.h" +#include "polly/Support/SCEVValidator.h" + +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/RegionIterator.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/Support/CommandLine.h" + +#define DEBUG_TYPE "polly-scops" +#include "llvm/Support/Debug.h" + +#include "isl/constraint.h" +#include "isl/set.h" +#include "isl/map.h" +#include "isl/aff.h" +#include "isl/printer.h" +#include "isl/local_space.h" +#include "isl/options.h" +#include +#include +#include + +using namespace llvm; +using namespace polly; + +STATISTIC(ScopFound, "Number of valid Scops"); +STATISTIC(RichScopFound, "Number of Scops containing a loop"); + +/// Convert an int into a string. +static std::string convertInt(int number) +{ + if (number == 0) + return "0"; + std::string temp = ""; + std::string returnvalue = ""; + while (number > 0) + { + temp += number % 10 + 48; + number /= 10; + } + for (unsigned i = 0; i < temp.length(); i++) + returnvalue+=temp[temp.length() - i - 1]; + return returnvalue; +} + +/// Translate a SCEVExpression into an isl_pw_aff object. +struct SCEVAffinator : public SCEVVisitor { +private: + isl_ctx *ctx; + int NbLoopSpaces; + const Scop *scop; + +public: + static isl_pw_aff *getPwAff(ScopStmt *stmt, const SCEV *scev) { + Scop *S = stmt->getParent(); + const Region *Reg = &S->getRegion(); + + S->addParams(getParamsInAffineExpr(Reg, scev, *S->getSE())); + + SCEVAffinator Affinator(stmt); + return Affinator.visit(scev); + } + + isl_pw_aff *visit(const SCEV *scev) { + // In case the scev is a valid parameter, we do not further analyze this + // expression, but create a new parameter in the isl_pw_aff. This allows us + // to treat subexpressions that we cannot translate into an piecewise affine + // expression, as constant parameters of the piecewise affine expression. + if (isl_id *Id = scop->getIdForParam(scev)) { + isl_space *Space = isl_space_set_alloc(ctx, 1, NbLoopSpaces); + Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id); + + isl_set *Domain = isl_set_universe(isl_space_copy(Space)); + isl_aff *Affine = isl_aff_zero_on_domain( + isl_local_space_from_space(Space)); + Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1); + + return isl_pw_aff_alloc(Domain, Affine); + } + + return SCEVVisitor::visit(scev); + } + + SCEVAffinator(const ScopStmt *stmt) : + ctx(stmt->getIslCtx()), + NbLoopSpaces(stmt->getNumIterators()), + scop(stmt->getParent()) {} + + __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Constant) { + ConstantInt *Value = Constant->getValue(); + isl_int v; + isl_int_init(v); + + // LLVM does not define if an integer value is interpreted as a signed or + // unsigned value. Hence, without further information, it is unknown how + // this value needs to be converted to GMP. At the moment, we only support + // signed operations. So we just interpret it as signed. Later, there are + // two options: + // + // 1. We always interpret any value as signed and convert the values on + // demand. + // 2. We pass down the signedness of the calculation and use it to interpret + // this constant correctly. + MPZ_from_APInt(v, Value->getValue(), /* isSigned */ true); + + isl_space *Space = isl_space_set_alloc(ctx, 0, NbLoopSpaces); + isl_local_space *ls = isl_local_space_from_space(isl_space_copy(Space)); + isl_aff *Affine = isl_aff_zero_on_domain(ls); + isl_set *Domain = isl_set_universe(Space); + + Affine = isl_aff_add_constant(Affine, v); + isl_int_clear(v); + + return isl_pw_aff_alloc(Domain, Affine); + } + + __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr) { + assert(0 && "Not yet supported"); + } + + __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { + assert(0 && "Not yet supported"); + } + + __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { + // Assuming the value is signed, a sign extension is basically a noop. + // TODO: Reconsider this as soon as we support unsigned values. + return visit(Expr->getOperand()); + } + + __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr) { + isl_pw_aff *Sum = visit(Expr->getOperand(0)); + + for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) { + isl_pw_aff *NextSummand = visit(Expr->getOperand(i)); + Sum = isl_pw_aff_add(Sum, NextSummand); + } + + // TODO: Check for NSW and NUW. + + return Sum; + } + + __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr) { + isl_pw_aff *Product = visit(Expr->getOperand(0)); + + for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) { + isl_pw_aff *NextOperand = visit(Expr->getOperand(i)); + + if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) { + isl_pw_aff_free(Product); + isl_pw_aff_free(NextOperand); + return NULL; + } + + Product = isl_pw_aff_mul(Product, NextOperand); + } + + // TODO: Check for NSW and NUW. + return Product; + } + + __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr) { + assert(0 && "Not yet supported"); + } + + int getLoopDepth(const Loop *L) { + Loop *outerLoop = + scop->getRegion().outermostLoopInRegion(const_cast(L)); + assert(outerLoop && "Scop does not contain this loop"); + return L->getLoopDepth() - outerLoop->getLoopDepth(); + } + + __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr) { + assert(Expr->isAffine() && "Only affine AddRecurrences allowed"); + assert(scop->getRegion().contains(Expr->getLoop()) + && "Scop does not contain the loop referenced in this AddRec"); + + isl_pw_aff *Start = visit(Expr->getStart()); + isl_pw_aff *Step = visit(Expr->getOperand(1)); + isl_space *Space = isl_space_set_alloc(ctx, 0, NbLoopSpaces); + isl_local_space *LocalSpace = isl_local_space_from_space(Space); + + int loopDimension = getLoopDepth(Expr->getLoop()); + + isl_aff *LAff = isl_aff_set_coefficient_si( + isl_aff_zero_on_domain (LocalSpace), isl_dim_in, loopDimension, 1); + isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff); + + // TODO: Do we need to check for NSW and NUW? + return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff)); + } + + __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr) { + isl_pw_aff *Max = visit(Expr->getOperand(0)); + + for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) { + isl_pw_aff *NextOperand = visit(Expr->getOperand(i)); + Max = isl_pw_aff_max(Max, NextOperand); + } + + return Max; + } + + __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr) { + assert(0 && "Not yet supported"); + } + + __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr) { + Value *Value = Expr->getValue(); + + isl_space *Space; + + std::string ValueName = Value->getName(); + isl_id *ID = isl_id_alloc(ctx, ValueName.c_str(), Value); + Space = isl_space_set_alloc(ctx, 1, NbLoopSpaces); + Space = isl_space_set_dim_id(Space, isl_dim_param, 0, ID); + + isl_set *Domain = isl_set_universe(isl_space_copy(Space)); + isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space)); + + Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1); + + return isl_pw_aff_alloc(Domain, Affine); + } +}; + +//===----------------------------------------------------------------------===// + +MemoryAccess::~MemoryAccess() { + isl_map_free(AccessRelation); + isl_map_free(newAccessRelation); +} + +static void replace(std::string& str, const std::string& find, + const std::string& replace) { + size_t pos = 0; + while((pos = str.find(find, pos)) != std::string::npos) + { + str.replace(pos, find.length(), replace); + pos += replace.length(); + } +} + +static void makeIslCompatible(std::string& str) { + str.erase(0, 1); + replace(str, ".", "_"); + replace(str, "\"", "_"); +} + +void MemoryAccess::setBaseName() { + raw_string_ostream OS(BaseName); + WriteAsOperand(OS, getBaseAddr(), false); + BaseName = OS.str(); + + makeIslCompatible(BaseName); + BaseName = "MemRef_" + BaseName; +} + +isl_map *MemoryAccess::getAccessRelation() const { + return isl_map_copy(AccessRelation); +} + +std::string MemoryAccess::getAccessRelationStr() const { + return stringFromIslObj(AccessRelation); +} + +isl_map *MemoryAccess::getNewAccessRelation() const { + return isl_map_copy(newAccessRelation); +} + +isl_basic_map *MemoryAccess::createBasicAccessMap(ScopStmt *Statement) { + isl_space *Space = isl_space_alloc(Statement->getIslCtx(), 0, + Statement->getNumIterators(), 1); + setBaseName(); + + Space = isl_space_set_tuple_name(Space, isl_dim_out, getBaseName().c_str()); + Space = isl_space_set_tuple_name(Space, isl_dim_in, Statement->getBaseName()); + + return isl_basic_map_universe(Space); +} + +MemoryAccess::MemoryAccess(const IRAccess &Access, ScopStmt *Statement) { + newAccessRelation = NULL; + Type = Access.isRead() ? Read : Write; + statement = Statement; + + BaseAddr = Access.getBase(); + + if (!Access.isAffine()) { + Type = (Type == Read) ? Read : MayWrite; + AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement)); + return; + } + + isl_pw_aff *Affine = SCEVAffinator::getPwAff(Statement, Access.getOffset()); + + setBaseName(); + + // Devide the access function by the size of the elements in the array. + // + // A stride one array access in C expressed as A[i] is expressed in LLVM-IR + // as something like A[i * elementsize]. This hides the fact that two + // subsequent values of 'i' index two values that are stored next to each + // other in memory. By this devision we make this characteristic obvious + // again. + isl_int v; + isl_int_init(v); + isl_int_set_si(v, Access.getElemSizeInBytes()); + Affine = isl_pw_aff_scale_down(Affine, v); + isl_int_clear(v); + + AccessRelation = isl_map_from_pw_aff(Affine); + AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_in, + Statement->getBaseName()); + AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_out, + getBaseName().c_str()); +} + +void MemoryAccess::realignParams() { + isl_space *ParamSpace = statement->getParent()->getParamSpace(); + AccessRelation = isl_map_align_params(AccessRelation, ParamSpace); +} + +MemoryAccess::MemoryAccess(const Value *BaseAddress, ScopStmt *Statement) { + newAccessRelation = NULL; + BaseAddr = BaseAddress; + Type = Read; + statement = Statement; + + isl_basic_map *BasicAccessMap = createBasicAccessMap(Statement); + AccessRelation = isl_map_from_basic_map(BasicAccessMap); + isl_space *ParamSpace = Statement->getParent()->getParamSpace(); + AccessRelation = isl_map_align_params(AccessRelation, ParamSpace); +} + +void MemoryAccess::print(raw_ostream &OS) const { + OS.indent(12) << (isRead() ? "Read" : "Write") << "Access := \n"; + OS.indent(16) << getAccessRelationStr() << ";\n"; +} + +void MemoryAccess::dump() const { + print(errs()); +} + +// Create a map in the size of the provided set domain, that maps from the +// one element of the provided set domain to another element of the provided +// set domain. +// The mapping is limited to all points that are equal in all but the last +// dimension and for which the last dimension of the input is strict smaller +// than the last dimension of the output. +// +// getEqualAndLarger(set[i0, i1, ..., iX]): +// +// set[i0, i1, ..., iX] -> set[o0, o1, ..., oX] +// : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX +// +static isl_map *getEqualAndLarger(isl_space *setDomain) { + isl_space *Space = isl_space_map_from_set(setDomain); + isl_map *Map = isl_map_universe(isl_space_copy(Space)); + isl_local_space *MapLocalSpace = isl_local_space_from_space(Space); + + // Set all but the last dimension to be equal for the input and output + // + // input[i0, i1, ..., iX] -> output[o0, o1, ..., oX] + // : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1) + for (unsigned i = 0; i < isl_map_dim(Map, isl_dim_in) - 1; ++i) + Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i); + + // Set the last dimension of the input to be strict smaller than the + // last dimension of the output. + // + // input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX + // + unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1; + isl_int v; + isl_int_init(v); + isl_constraint *c = isl_inequality_alloc(isl_local_space_copy(MapLocalSpace)); + isl_int_set_si(v, -1); + isl_constraint_set_coefficient(c, isl_dim_in, lastDimension, v); + isl_int_set_si(v, 1); + isl_constraint_set_coefficient(c, isl_dim_out, lastDimension, v); + isl_int_set_si(v, -1); + isl_constraint_set_constant(c, v); + isl_int_clear(v); + + Map = isl_map_add_constraint(Map, c); + + isl_local_space_free(MapLocalSpace); + return Map; +} + +isl_set *MemoryAccess::getStride(__isl_take const isl_set *domainSubset) const { + isl_map *accessRelation = getAccessRelation(); + isl_set *scatteringDomain = const_cast(domainSubset); + isl_map *scattering = getStatement()->getScattering(); + + scattering = isl_map_reverse(scattering); + int difference = isl_map_n_in(scattering) - isl_set_n_dim(scatteringDomain); + scattering = isl_map_project_out(scattering, isl_dim_in, + isl_set_n_dim(scatteringDomain), + difference); + + // Remove all names of the scattering dimensions, as the names may be lost + // anyways during the project. This leads to consistent results. + scattering = isl_map_set_tuple_name(scattering, isl_dim_in, ""); + scatteringDomain = isl_set_set_tuple_name(scatteringDomain, ""); + + isl_map *nextScatt = getEqualAndLarger(isl_set_get_space(scatteringDomain)); + nextScatt = isl_map_lexmin(nextScatt); + + scattering = isl_map_intersect_domain(scattering, scatteringDomain); + + nextScatt = isl_map_apply_range(nextScatt, isl_map_copy(scattering)); + nextScatt = isl_map_apply_range(nextScatt, isl_map_copy(accessRelation)); + nextScatt = isl_map_apply_domain(nextScatt, scattering); + nextScatt = isl_map_apply_domain(nextScatt, accessRelation); + + return isl_map_deltas(nextScatt); +} + +bool MemoryAccess::isStrideX(__isl_take const isl_set *DomainSubset, + int StrideWidth) const { + isl_set *Stride, *StrideX; + bool IsStrideX; + + Stride = getStride(DomainSubset); + StrideX = isl_set_universe(isl_set_get_space(Stride)); + StrideX = isl_set_fix_si(StrideX, isl_dim_set, 0, StrideWidth); + IsStrideX = isl_set_is_equal(Stride, StrideX); + + isl_set_free(StrideX); + isl_set_free(Stride); + + return IsStrideX; +} + +bool MemoryAccess::isStrideZero(const isl_set *DomainSubset) const { + return isStrideX(DomainSubset, 0); +} + +bool MemoryAccess::isStrideOne(const isl_set *DomainSubset) const { + return isStrideX(DomainSubset, 1); +} + +void MemoryAccess::setNewAccessRelation(isl_map *newAccess) { + isl_map_free(newAccessRelation); + newAccessRelation = newAccess; +} + +//===----------------------------------------------------------------------===// + +isl_map *ScopStmt::getScattering() const { + return isl_map_copy(Scattering); +} + +void ScopStmt::setScattering(isl_map *NewScattering) { + isl_map_free(Scattering); + Scattering = NewScattering; +} + +void ScopStmt::buildScattering(SmallVectorImpl &Scatter) { + unsigned NbIterators = getNumIterators(); + unsigned NbScatteringDims = Parent.getMaxLoopDepth() * 2 + 1; + + isl_space *Space = isl_space_alloc(getIslCtx(), 0, NbIterators, + NbScatteringDims); + Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering"); + Space = isl_space_set_tuple_name(Space, isl_dim_in, getBaseName()); + + Scattering = isl_map_universe(Space); + + // Loop dimensions. + for (unsigned i = 0; i < NbIterators; ++i) + Scattering = isl_map_equate(Scattering, isl_dim_out, 2 * i + 1, + isl_dim_in, i); + + // Constant dimensions + for (unsigned i = 0; i < NbIterators + 1; ++i) + Scattering = isl_map_fix_si(Scattering, isl_dim_out, 2 * i, Scatter[i]); + + // Fill scattering dimensions. + for (unsigned i = 2 * NbIterators + 1; i < NbScatteringDims; ++i) + Scattering = isl_map_fix_si(Scattering, isl_dim_out, i, 0); + + Scattering = isl_map_align_params(Scattering, Parent.getParamSpace()); +} + +void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) { + const AccFuncSetType *AccFuncs = tempScop.getAccessFunctions(BB); + + for (AccFuncSetType::const_iterator I = AccFuncs->begin(), + E = AccFuncs->end(); I != E; ++I) { + MemAccs.push_back(new MemoryAccess(I->first, this)); + InstructionToAccess[I->second] = MemAccs.back(); + } +} + +void ScopStmt::realignParams() { + for (memacc_iterator MI = memacc_begin(), ME = memacc_end(); MI != ME; ++MI) + (*MI)->realignParams(); + + Domain = isl_set_align_params(Domain, Parent.getParamSpace()); + Scattering = isl_map_align_params(Scattering, Parent.getParamSpace()); +} + +__isl_give isl_set *ScopStmt::buildConditionSet(const Comparison &Comp) { + isl_pw_aff *L = SCEVAffinator::getPwAff(this, Comp.getLHS()); + isl_pw_aff *R = SCEVAffinator::getPwAff(this, Comp.getRHS()); + + switch (Comp.getPred()) { + case ICmpInst::ICMP_EQ: + return isl_pw_aff_eq_set(L, R); + case ICmpInst::ICMP_NE: + return isl_pw_aff_ne_set(L, R); + case ICmpInst::ICMP_SLT: + return isl_pw_aff_lt_set(L, R); + case ICmpInst::ICMP_SLE: + return isl_pw_aff_le_set(L, R); + case ICmpInst::ICMP_SGT: + return isl_pw_aff_gt_set(L, R); + case ICmpInst::ICMP_SGE: + return isl_pw_aff_ge_set(L, R); + case ICmpInst::ICMP_ULT: + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_ULE: + case ICmpInst::ICMP_UGE: + llvm_unreachable("Unsigned comparisons not yet supported"); + default: + llvm_unreachable("Non integer predicate not supported"); + } +} + +__isl_give isl_set *ScopStmt::addLoopBoundsToDomain(__isl_take isl_set *Domain, + TempScop &tempScop) { + isl_space *Space; + isl_local_space *LocalSpace; + + Space = isl_set_get_space(Domain); + LocalSpace = isl_local_space_from_space(Space); + + for (int i = 0, e = getNumIterators(); i != e; ++i) { + isl_aff *Zero = isl_aff_zero_on_domain(isl_local_space_copy(LocalSpace)); + isl_pw_aff *IV = isl_pw_aff_from_aff( + isl_aff_set_coefficient_si(Zero, isl_dim_in, i, 1)); + + // 0 <= IV. + isl_set *LowerBound = isl_pw_aff_nonneg_set(isl_pw_aff_copy(IV)); + Domain = isl_set_intersect(Domain, LowerBound); + + // IV <= LatchExecutions. + const Loop *L = getLoopForDimension(i); + const SCEV *LatchExecutions = tempScop.getLoopBound(L); + isl_pw_aff *UpperBound = SCEVAffinator::getPwAff(this, LatchExecutions); + isl_set *UpperBoundSet = isl_pw_aff_le_set(IV, UpperBound); + Domain = isl_set_intersect(Domain, UpperBoundSet); + } + + isl_local_space_free(LocalSpace); + return Domain; +} + +__isl_give isl_set *ScopStmt::addConditionsToDomain(__isl_take isl_set *Domain, + TempScop &tempScop, + const Region &CurRegion) { + const Region *TopRegion = tempScop.getMaxRegion().getParent(), + *CurrentRegion = &CurRegion; + const BasicBlock *BranchingBB = BB; + + do { + if (BranchingBB != CurrentRegion->getEntry()) { + if (const BBCond *Condition = tempScop.getBBCond(BranchingBB)) + for (BBCond::const_iterator CI = Condition->begin(), + CE = Condition->end(); CI != CE; ++CI) { + isl_set *ConditionSet = buildConditionSet(*CI); + Domain = isl_set_intersect(Domain, ConditionSet); + } + } + BranchingBB = CurrentRegion->getEntry(); + CurrentRegion = CurrentRegion->getParent(); + } while (TopRegion != CurrentRegion); + + return Domain; +} + +__isl_give isl_set *ScopStmt::buildDomain(TempScop &tempScop, + const Region &CurRegion) { + isl_space *Space; + isl_set *Domain; + + Space = isl_space_set_alloc(getIslCtx(), 0, getNumIterators()); + + Domain = isl_set_universe(Space); + Domain = addLoopBoundsToDomain(Domain, tempScop); + Domain = addConditionsToDomain(Domain, tempScop, CurRegion); + Domain = isl_set_set_tuple_name(Domain, getBaseName()); + + return Domain; +} + +ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, + const Region &CurRegion, BasicBlock &bb, + SmallVectorImpl &NestLoops, + SmallVectorImpl &Scatter) + : Parent(parent), BB(&bb), IVS(NestLoops.size()) { + // Setup the induction variables. + for (unsigned i = 0, e = NestLoops.size(); i < e; ++i) { + PHINode *PN = NestLoops[i]->getCanonicalInductionVariable(); + assert(PN && "Non canonical IV in Scop!"); + IVS[i] = std::make_pair(PN, NestLoops[i]); + } + + raw_string_ostream OS(BaseName); + WriteAsOperand(OS, &bb, false); + BaseName = OS.str(); + + makeIslCompatible(BaseName); + BaseName = "Stmt_" + BaseName; + + Domain = buildDomain(tempScop, CurRegion); + buildScattering(Scatter); + buildAccesses(tempScop, CurRegion); +} + +ScopStmt::ScopStmt(Scop &parent, SmallVectorImpl &Scatter) + : Parent(parent), BB(NULL), IVS(0) { + + BaseName = "FinalRead"; + + // Build iteration domain. + std::string IterationDomainString = "{[i0] : i0 = 0}"; + Domain = isl_set_read_from_str(getIslCtx(), IterationDomainString.c_str()); + Domain = isl_set_set_tuple_name(Domain, getBaseName()); + + // Build scattering. + unsigned ScatSpace = Parent.getMaxLoopDepth() * 2 + 1; + isl_space *Space = isl_space_alloc(getIslCtx(), 0, 1, ScatSpace); + Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering"); + Space = isl_space_set_tuple_name(Space, isl_dim_in, getBaseName()); + Scattering = isl_map_universe(Space); + + // TODO: This is incorrect. We should not use a very large number to ensure + // that this statement is executed last. + Scattering = isl_map_fix_si(Scattering, isl_dim_out, 0, 200000000); + + // Build memory accesses, use SetVector to keep the order of memory accesses + // and prevent the same memory access inserted more than once. + SetVector BaseAddressSet; + + for (Scop::const_iterator SI = Parent.begin(), SE = Parent.end(); SI != SE; + ++SI) { + ScopStmt *Stmt = *SI; + + for (MemoryAccessVec::const_iterator I = Stmt->memacc_begin(), + E = Stmt->memacc_end(); I != E; ++I) + BaseAddressSet.insert((*I)->getBaseAddr()); + } + + for (SetVector::iterator BI = BaseAddressSet.begin(), + BE = BaseAddressSet.end(); BI != BE; ++BI) + MemAccs.push_back(new MemoryAccess(*BI, this)); +} + +std::string ScopStmt::getDomainStr() const { + return stringFromIslObj(Domain); +} + +std::string ScopStmt::getScatteringStr() const { + return stringFromIslObj(Scattering); +} + +unsigned ScopStmt::getNumParams() const { + return Parent.getNumParams(); +} + +unsigned ScopStmt::getNumIterators() const { + // The final read has one dimension with one element. + if (!BB) + return 1; + + return IVS.size(); +} + +unsigned ScopStmt::getNumScattering() const { + return isl_map_dim(Scattering, isl_dim_out); +} + +const char *ScopStmt::getBaseName() const { return BaseName.c_str(); } + +const PHINode *ScopStmt::getInductionVariableForDimension(unsigned Dimension) + const { + return IVS[Dimension].first; +} + +const Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const { + return IVS[Dimension].second; +} + +const SCEVAddRecExpr *ScopStmt::getSCEVForDimension(unsigned Dimension) + const { + PHINode *PN = + const_cast(getInductionVariableForDimension(Dimension)); + return cast(getParent()->getSE()->getSCEV(PN)); +} + +isl_ctx *ScopStmt::getIslCtx() const { + return Parent.getIslCtx(); +} + +isl_set *ScopStmt::getDomain() const { + return isl_set_copy(Domain); +} + +isl_space *ScopStmt::getDomainSpace() const { + return isl_set_get_space(Domain); +} + +ScopStmt::~ScopStmt() { + while (!MemAccs.empty()) { + delete MemAccs.back(); + MemAccs.pop_back(); + } + + isl_set_free(Domain); + isl_map_free(Scattering); +} + +void ScopStmt::print(raw_ostream &OS) const { + OS << "\t" << getBaseName() << "\n"; + + OS.indent(12) << "Domain :=\n"; + + if (Domain) { + OS.indent(16) << getDomainStr() << ";\n"; + } else + OS.indent(16) << "n/a\n"; + + OS.indent(12) << "Scattering :=\n"; + + if (Domain) { + OS.indent(16) << getScatteringStr() << ";\n"; + } else + OS.indent(16) << "n/a\n"; + + for (MemoryAccessVec::const_iterator I = MemAccs.begin(), E = MemAccs.end(); + I != E; ++I) + (*I)->print(OS); +} + +void ScopStmt::dump() const { print(dbgs()); } + +//===----------------------------------------------------------------------===// +/// Scop class implement + +void Scop::setContext(__isl_take isl_set *NewContext) { + NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context)); + isl_set_free(Context); + Context = NewContext; +} + +void Scop::addParams(std::vector NewParameters) { + for (std::vector::iterator PI = NewParameters.begin(), + PE = NewParameters.end(); PI != PE; ++PI) { + const SCEV *Parameter = *PI; + + if (ParameterIds.find(Parameter) != ParameterIds.end()) + continue; + + int dimension = Parameters.size(); + + Parameters.push_back(Parameter); + ParameterIds[Parameter] = dimension; + } +} + +__isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) const { + ParamIdType::const_iterator IdIter = ParameterIds.find(Parameter); + + if (IdIter == ParameterIds.end()) + return NULL; + + std::string ParameterName; + + if (const SCEVUnknown *ValueParameter = dyn_cast(Parameter)) { + Value *Val = ValueParameter->getValue(); + ParameterName = Val->getName(); + } + + if (ParameterName == "" || ParameterName.substr(0, 2) == "p_") + ParameterName = "p_" + convertInt(IdIter->second); + + return isl_id_alloc(getIslCtx(), ParameterName.c_str(), (void *) Parameter); +} + +void Scop::buildContext() { + isl_space *Space = isl_space_params_alloc(IslCtx, 0); + Context = isl_set_universe (Space); +} + +void Scop::realignParams() { + // Add all parameters into a common model. + isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size()); + + for (ParamIdType::iterator PI = ParameterIds.begin(), PE = ParameterIds.end(); + PI != PE; ++PI) { + const SCEV *Parameter = PI->first; + isl_id *id = getIdForParam(Parameter); + Space = isl_space_set_dim_id(Space, isl_dim_param, PI->second, id); + } + + // Align the parameters of all data structures to the model. + Context = isl_set_align_params(Context, Space); + + for (iterator I = begin(), E = end(); I != E; ++I) + (*I)->realignParams(); +} + +Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution, + isl_ctx *Context) + : SE(&ScalarEvolution), R(tempScop.getMaxRegion()), + MaxLoopDepth(tempScop.getMaxLoopDepth()) { + IslCtx = Context; + buildContext(); + + SmallVector NestLoops; + SmallVector Scatter; + + Scatter.assign(MaxLoopDepth + 1, 0); + + // Build the iteration domain, access functions and scattering functions + // traversing the region tree. + buildScop(tempScop, getRegion(), NestLoops, Scatter, LI); + Stmts.push_back(new ScopStmt(*this, Scatter)); + + realignParams(); + + assert(NestLoops.empty() && "NestLoops not empty at top level!"); +} + +Scop::~Scop() { + isl_set_free(Context); + + // Free the statements; + for (iterator I = begin(), E = end(); I != E; ++I) + delete *I; +} + +std::string Scop::getContextStr() const { + return stringFromIslObj(Context); +} + +std::string Scop::getNameStr() const { + std::string ExitName, EntryName; + raw_string_ostream ExitStr(ExitName); + raw_string_ostream EntryStr(EntryName); + + WriteAsOperand(EntryStr, R.getEntry(), false); + EntryStr.str(); + + if (R.getExit()) { + WriteAsOperand(ExitStr, R.getExit(), false); + ExitStr.str(); + } else + ExitName = "FunctionExit"; + + return EntryName + "---" + ExitName; +} + +__isl_give isl_set *Scop::getContext() const { + return isl_set_copy(Context); +} +__isl_give isl_space *Scop::getParamSpace() const { + return isl_set_get_space(this->Context); +} + +void Scop::printContext(raw_ostream &OS) const { + OS << "Context:\n"; + + if (!Context) { + OS.indent(4) << "n/a\n\n"; + return; + } + + OS.indent(4) << getContextStr() << "\n"; + + for (ParamVecType::const_iterator PI = Parameters.begin(), + PE = Parameters.end(); PI != PE; ++PI) { + const SCEV *Parameter = *PI; + int Dim = ParameterIds.find(Parameter)->second; + + OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n"; + } +} + +void Scop::printStatements(raw_ostream &OS) const { + OS << "Statements {\n"; + + for (const_iterator SI = begin(), SE = end();SI != SE; ++SI) + OS.indent(4) << (**SI); + + OS.indent(4) << "}\n"; +} + + +void Scop::print(raw_ostream &OS) const { + printContext(OS.indent(4)); + printStatements(OS.indent(4)); +} + +void Scop::dump() const { print(dbgs()); } + +isl_ctx *Scop::getIslCtx() const { return IslCtx; } + +ScalarEvolution *Scop::getSE() const { return SE; } + +bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) { + if (tempScop.getAccessFunctions(BB)) + return false; + + return true; +} + +void Scop::buildScop(TempScop &tempScop, + const Region &CurRegion, + SmallVectorImpl &NestLoops, + SmallVectorImpl &Scatter, + LoopInfo &LI) { + Loop *L = castToLoop(CurRegion, LI); + + if (L) + NestLoops.push_back(L); + + unsigned loopDepth = NestLoops.size(); + assert(Scatter.size() > loopDepth && "Scatter not big enough!"); + + for (Region::const_element_iterator I = CurRegion.element_begin(), + E = CurRegion.element_end(); I != E; ++I) + if (I->isSubRegion()) + buildScop(tempScop, *(I->getNodeAs()), NestLoops, Scatter, LI); + else { + BasicBlock *BB = I->getNodeAs(); + + if (isTrivialBB(BB, tempScop)) + continue; + + Stmts.push_back(new ScopStmt(*this, tempScop, CurRegion, *BB, NestLoops, + Scatter)); + + // Increasing the Scattering function is OK for the moment, because + // we are using a depth first iterator and the program is well structured. + ++Scatter[loopDepth]; + } + + if (!L) + return; + + // Exiting a loop region. + Scatter[loopDepth] = 0; + NestLoops.pop_back(); + ++Scatter[loopDepth-1]; +} + +//===----------------------------------------------------------------------===// +ScopInfo::ScopInfo() : RegionPass(ID), scop(0) { + ctx = isl_ctx_alloc(); + isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT); +} + +ScopInfo::~ScopInfo() { + clear(); + isl_ctx_free(ctx); +} + + + +void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.setPreservesAll(); +} + +bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) { + LoopInfo &LI = getAnalysis(); + ScalarEvolution &SE = getAnalysis(); + + TempScop *tempScop = getAnalysis().getTempScop(R); + + // This region is no Scop. + if (!tempScop) { + scop = 0; + return false; + } + + // Statistics. + ++ScopFound; + if (tempScop->getMaxLoopDepth() > 0) ++RichScopFound; + + scop = new Scop(*tempScop, LI, SE, ctx); + + return false; +} + +char ScopInfo::ID = 0; + +INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops", + "Polly - Create polyhedral description of Scops", false, + false) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(RegionInfo) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) +INITIALIZE_PASS_DEPENDENCY(TempScopInfo) +INITIALIZE_PASS_END(ScopInfo, "polly-scops", + "Polly - Create polyhedral description of Scops", false, + false) + +Pass *polly::createScopInfoPass() { + return new ScopInfo(); +} diff --git a/tools/polly/lib/Analysis/ScopPass.cpp b/tools/polly/lib/Analysis/ScopPass.cpp new file mode 100755 index 00000000000..c733ec94753 --- /dev/null +++ b/tools/polly/lib/Analysis/ScopPass.cpp @@ -0,0 +1,42 @@ +//===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the definitions of the ScopPass members. +// +//===----------------------------------------------------------------------===// + +#include "polly/ScopPass.h" +#include "polly/ScopInfo.h" + +using namespace llvm; +using namespace polly; + +bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) { + S = 0; + + if ((S = getAnalysis().getScop())) + return runOnScop(*S); + + return false; +} + +isl_ctx *ScopPass::getIslContext() { + assert(S && "Not in on a Scop!"); + return S->getIslCtx(); +} + +void ScopPass::print(raw_ostream &OS, const Module *M) const { + if (S) + printScop(OS); +} + +void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); +} diff --git a/tools/polly/lib/Analysis/TempScopInfo.cpp b/tools/polly/lib/Analysis/TempScopInfo.cpp new file mode 100644 index 00000000000..769ab4ecdd5 --- /dev/null +++ b/tools/polly/lib/Analysis/TempScopInfo.cpp @@ -0,0 +1,319 @@ +//===---------- TempScopInfo.cpp - Extract TempScops ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Collect information about the control flow regions detected by the Scop +// detection, such that this information can be translated info its polyhedral +// representation. +// +//===----------------------------------------------------------------------===// + +#include "polly/TempScopInfo.h" + +#include "polly/LinkAllPasses.h" +#include "polly/Support/GICHelper.h" +#include "polly/Support/ScopHelper.h" +#include "polly/Support/SCEVValidator.h" + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/RegionIterator.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/ADT/STLExtras.h" + +#define DEBUG_TYPE "polly-analyze-ir" +#include "llvm/Support/Debug.h" + +using namespace llvm; +using namespace polly; + +//===----------------------------------------------------------------------===// +/// Helper Class + +void Comparison::print(raw_ostream &OS) const { + // Not yet implemented. +} + +/// Helper function to print the condition +static void printBBCond(raw_ostream &OS, const BBCond &Cond) { + assert(!Cond.empty() && "Unexpected empty condition!"); + Cond[0].print(OS); + for (unsigned i = 1, e = Cond.size(); i != e; ++i) { + OS << " && "; + Cond[i].print(OS); + } +} + +inline raw_ostream &operator<<(raw_ostream &OS, const BBCond &Cond) { + printBBCond(OS, Cond); + return OS; +} + +//===----------------------------------------------------------------------===// +// TempScop implementation +TempScop::~TempScop() { + if (MayASInfo) delete MayASInfo; +} + +void TempScop::print(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI) const { + OS << "Scop: " << R.getNameStr() << ", Max Loop Depth: "<< MaxLoopDepth + << "\n"; + + printDetail(OS, SE, LI, &R, 0); +} + +void TempScop::printDetail(llvm::raw_ostream &OS, ScalarEvolution *SE, + LoopInfo *LI, const Region *CurR, + unsigned ind) const { +} + +void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB) { + AccFuncSetType Functions; + + for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) { + Instruction &Inst = *I; + if (isa(&Inst) || isa(&Inst)) { + unsigned Size; + enum IRAccess::TypeKind Type; + + if (LoadInst *Load = dyn_cast(&Inst)) { + Size = TD->getTypeStoreSize(Load->getType()); + Type = IRAccess::READ; + } else { + StoreInst *Store = cast(&Inst); + Size = TD->getTypeStoreSize(Store->getValueOperand()->getType()); + Type = IRAccess::WRITE; + } + + const SCEV *AccessFunction = SE->getSCEV(getPointerOperand(Inst)); + const SCEVUnknown *BasePointer = + dyn_cast(SE->getPointerBase(AccessFunction)); + + assert(BasePointer && "Could not find base pointer"); + AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer); + + bool IsAffine = isAffineExpr(&R, AccessFunction, *SE, + BasePointer->getValue()); + + Functions.push_back(std::make_pair(IRAccess(Type, + BasePointer->getValue(), + AccessFunction, Size, + IsAffine), + &Inst)); + } + } + + if (Functions.empty()) + return; + + AccFuncSetType &Accs = AccFuncMap[&BB]; + Accs.insert(Accs.end(), Functions.begin(), Functions.end()); +} + +void TempScopInfo::buildLoopBounds(TempScop &Scop) { + Region &R = Scop.getMaxRegion(); + unsigned MaxLoopDepth = 0; + + for (Region::block_iterator I = R.block_begin(), E = R.block_end(); + I != E; ++I) { + Loop *L = LI->getLoopFor(I->getNodeAs()); + + if (!L || !R.contains(L)) + continue; + + if (LoopBounds.find(L) != LoopBounds.end()) + continue; + + const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L); + LoopBounds[L] = BackedgeTakenCount; + + Loop *OL = R.outermostLoopInRegion(L); + unsigned LoopDepth = L->getLoopDepth() - OL->getLoopDepth() + 1; + + if (LoopDepth > MaxLoopDepth) + MaxLoopDepth = LoopDepth; + } + + Scop.MaxLoopDepth = MaxLoopDepth; +} + +void TempScopInfo::buildAffineCondition(Value &V, bool inverted, + Comparison **Comp, + TempScop &Scop) const { + if (ConstantInt *C = dyn_cast(&V)) { + // If this is always true condition, we will create 1 >= 0, + // otherwise we will create 1 == 0. + const SCEV *LHS = SE->getConstant(C->getType(), 0); + const SCEV *RHS = SE->getConstant(C->getType(), 1); + + if (C->isOne() == inverted) + *Comp = new Comparison(RHS, LHS, ICmpInst::ICMP_NE); + else + *Comp = new Comparison(LHS, LHS, ICmpInst::ICMP_EQ); + + return; + } + + ICmpInst *ICmp = dyn_cast(&V); + assert(ICmp && "Only ICmpInst of constant as condition supported!"); + + const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0)), + *RHS = SE->getSCEV(ICmp->getOperand(1)); + + ICmpInst::Predicate Pred = ICmp->getPredicate(); + + // Invert the predicate if needed. + if (inverted) + Pred = ICmpInst::getInversePredicate(Pred); + + switch (Pred) { + case ICmpInst::ICMP_UGT: + case ICmpInst::ICMP_UGE: + case ICmpInst::ICMP_ULT: + case ICmpInst::ICMP_ULE: + // TODO: At the moment we need to see everything as signed. This is an + // correctness issue that needs to be solved. + //AffLHS->setUnsigned(); + //AffRHS->setUnsigned(); + break; + default: + break; + } + + *Comp = new Comparison(LHS, RHS, Pred); +} + +void TempScopInfo::buildCondition(BasicBlock *BB, BasicBlock *RegionEntry, + TempScop &Scop) { + BBCond Cond; + + DomTreeNode *BBNode = DT->getNode(BB), *EntryNode = DT->getNode(RegionEntry); + assert(BBNode && EntryNode && "Get null node while building condition!"); + + // Walk up the dominance tree until reaching the entry node. Add all + // conditions on the path to BB except if BB postdominates the block + // containing the condition. + while (BBNode != EntryNode) { + BasicBlock *CurBB = BBNode->getBlock(); + BBNode = BBNode->getIDom(); + assert(BBNode && "BBNode should not reach the root node!"); + + if (PDT->dominates(CurBB, BBNode->getBlock())) + continue; + + BranchInst *Br = dyn_cast(BBNode->getBlock()->getTerminator()); + assert(Br && "A Valid Scop should only contain branch instruction"); + + if (Br->isUnconditional()) + continue; + + // Is BB on the ELSE side of the branch? + bool inverted = DT->dominates(Br->getSuccessor(1), BB); + + Comparison *Cmp; + buildAffineCondition(*(Br->getCondition()), inverted, &Cmp, Scop); + Cond.push_back(*Cmp); + } + + if (!Cond.empty()) + BBConds[BB] = Cond; +} + +TempScop *TempScopInfo::buildTempScop(Region &R) { + TempScop *TScop = new TempScop(R, LoopBounds, BBConds, AccFuncMap); + + for (Region::block_iterator I = R.block_begin(), E = R.block_end(); + I != E; ++I) { + BasicBlock *BB = I->getNodeAs(); + buildAccessFunctions(R, *BB); + buildCondition(BB, R.getEntry(), *TScop); + } + + buildLoopBounds(*TScop); + + // Build the MayAliasSets. + TScop->MayASInfo->buildMayAliasSets(*TScop, *AA); + return TScop; +} + +TempScop *TempScopInfo::getTempScop(const Region *R) const { + TempScopMapType::const_iterator at = TempScops.find(R); + return at == TempScops.end() ? 0 : at->second; +} + +void TempScopInfo::print(raw_ostream &OS, const Module *) const { + for (TempScopMapType::const_iterator I = TempScops.begin(), + E = TempScops.end(); I != E; ++I) + I->second->print(OS, SE, LI); +} + +bool TempScopInfo::runOnFunction(Function &F) { + DT = &getAnalysis(); + PDT = &getAnalysis(); + SE = &getAnalysis(); + LI = &getAnalysis(); + SD = &getAnalysis(); + AA = &getAnalysis(); + TD = &getAnalysis(); + + for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) { + Region *R = const_cast(*I); + TempScops.insert(std::make_pair(R, buildTempScop(*R))); + } + + return false; +} + +void TempScopInfo::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + AU.addRequiredTransitive(); + AU.addRequiredID(IndependentBlocksID); + AU.addRequired(); + AU.setPreservesAll(); +} + +TempScopInfo::~TempScopInfo() { + clear(); +} + +void TempScopInfo::clear() { + BBConds.clear(); + LoopBounds.clear(); + AccFuncMap.clear(); + DeleteContainerSeconds(TempScops); + TempScops.clear(); +} + +//===----------------------------------------------------------------------===// +// TempScop information extraction pass implement +char TempScopInfo::ID = 0; + +INITIALIZE_PASS_BEGIN(TempScopInfo, "polly-analyze-ir", + "Polly - Analyse the LLVM-IR in the detected regions", + false, false) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) +INITIALIZE_PASS_DEPENDENCY(RegionInfo) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) +INITIALIZE_PASS_DEPENDENCY(TargetData) +INITIALIZE_PASS_END(TempScopInfo, "polly-analyze-ir", + "Polly - Analyse the LLVM-IR in the detected regions", + false, false) + +Pass *polly::createTempScopInfoPass() { + return new TempScopInfo(); +} diff --git a/tools/polly/lib/CMakeLists.txt b/tools/polly/lib/CMakeLists.txt new file mode 100755 index 00000000000..05cfa0cbe77 --- /dev/null +++ b/tools/polly/lib/CMakeLists.txt @@ -0,0 +1,44 @@ +add_subdirectory(Analysis) +add_subdirectory(Exchange) +add_subdirectory(Support) +add_subdirectory(JSON) + +set(MODULE TRUE) +set(LLVM_NO_RTTI 1) + +if (SCOPLIB_FOUND) + set(POLLY_SCOPLIB_FILES Pocc.cpp) +endif (SCOPLIB_FOUND) + +set(LLVM_USED_LIBS + PollyAnalysis + PollyExchange + PollySupport + PollyJSON + ) + +add_polly_library(LLVMPolly + Cloog.cpp + CodePreparation.cpp + CodeGeneration.cpp + DeadCodeElimination.cpp + IndependentBlocks.cpp + MayAliasSet.cpp + Pocc.cpp + RegionSimplify.cpp + RegisterPasses.cpp + ScheduleOptimizer.cpp + ${POLLY_SCOPLIB_FILES} + ) + +add_dependencies(LLVMPolly + PollyAnalysis + PollyExchange + PollySupport + PollyJSON + ) + +set_target_properties(LLVMPolly + PROPERTIES + LINKER_LANGUAGE CXX + PREFIX "") diff --git a/tools/polly/lib/Cloog.cpp b/tools/polly/lib/Cloog.cpp new file mode 100644 index 00000000000..779bdf7e579 --- /dev/null +++ b/tools/polly/lib/Cloog.cpp @@ -0,0 +1,339 @@ +//===- Cloog.cpp - Cloog interface ----------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Cloog[1] interface. +// +// The Cloog interface takes a Scop and generates a Cloog AST (clast). This +// clast can either be returned directly or it can be pretty printed to stdout. +// +// A typical clast output looks like this: +// +// for (c2 = max(0, ceild(n + m, 2); c2 <= min(511, floord(5 * n, 3)); c2++) { +// bb2(c2); +// } +// +// [1] http://www.cloog.org/ - The Chunky Loop Generator +// +//===----------------------------------------------------------------------===// + +#include "polly/Cloog.h" +#include "polly/LinkAllPasses.h" +#include "polly/ScopInfo.h" + +#define DEBUG_TYPE "polly-cloog" +#include "llvm/Assembly/Writer.h" +#include "llvm/Module.h" +#include "llvm/Support/Debug.h" + +#include "cloog/isl/domain.h" +#include "cloog/isl/cloog.h" + +#include + +using namespace llvm; +using namespace polly; + +namespace polly { +class Cloog { + Scop *S; + CloogOptions *Options; + CloogState *State; + clast_stmt *ClastRoot; + + void buildCloogOptions(); + CloogUnionDomain *buildCloogUnionDomain(); + CloogInput *buildCloogInput(); + +public: + Cloog(Scop *Scop); + + ~Cloog(); + + /// Write a .cloog input file + void dump(FILE *F); + + /// Print a source code representation of the program. + void pprint(llvm::raw_ostream &OS); + + /// Create the Cloog AST from this program. + struct clast_root *getClast(); +}; + +Cloog::Cloog(Scop *Scop) : S(Scop) { + State = cloog_isl_state_malloc(Scop->getIslCtx()); + buildCloogOptions(); + ClastRoot = cloog_clast_create_from_input(buildCloogInput(), Options); +} + +Cloog::~Cloog() { + cloog_clast_free(ClastRoot); + cloog_options_free(Options); + cloog_state_free(State); +} + +// Create a FILE* write stream and get the output to it written +// to a std::string. +class FileToString { + int FD[2]; + FILE *input; + static const int BUFFERSIZE = 20; + + char buf[BUFFERSIZE + 1]; + + +public: + FileToString() { + pipe(FD); + input = fdopen(FD[1], "w"); + } + ~FileToString() { + close(FD[0]); + //close(FD[1]); + } + + FILE *getInputFile() { + return input; + } + + void closeInput() { + fclose(input); + close(FD[1]); + } + + std::string getOutput() { + std::string output; + int readSize; + + while (true) { + readSize = read(FD[0], &buf, BUFFERSIZE); + + if (readSize <= 0) + break; + + output += std::string(buf, readSize); + } + + + return output; + } + +}; + +/// Write .cloog input file. +void Cloog::dump(FILE *F) { + CloogInput *Input = buildCloogInput(); + cloog_input_dump_cloog(F, Input, Options); + cloog_input_free(Input); +} + +/// Print a source code representation of the program. +void Cloog::pprint(raw_ostream &OS) { + FileToString *Output = new FileToString(); + clast_pprint(Output->getInputFile(), ClastRoot, 0, Options); + Output->closeInput(); + OS << Output->getOutput(); + delete (Output); +} + +/// Create the Cloog AST from this program. +struct clast_root *Cloog::getClast() { + return (clast_root*)ClastRoot; +} + +void Cloog::buildCloogOptions() { + Options = cloog_options_malloc(State); + Options->quiet = 1; + Options->strides = 1; + Options->save_domains = 1; + Options->noscalars = 1; + + // The last loop depth to optimize should be the last scattering dimension. + // CLooG by default will continue to split the loops even after the last + // scattering dimension. This splitting is problematic for the schedules + // calculated by the PoCC/isl/Pluto optimizer. Such schedules contain may + // not be fully defined, but statements without dependences may be mapped + // to the same exeuction time. For such schedules, continuing to split + // may lead to a larger set of if-conditions in the innermost loop. + Options->l = 0; +} + +CloogUnionDomain *Cloog::buildCloogUnionDomain() { + CloogUnionDomain *DU = cloog_union_domain_alloc(S->getNumParams()); + + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (Stmt->isFinalRead()) + continue; + + CloogScattering *Scattering; + CloogDomain *Domain; + + Scattering = cloog_scattering_from_isl_map(Stmt->getScattering()); + Domain = cloog_domain_from_isl_set(Stmt->getDomain()); + + std::string entryName = Stmt->getBaseName(); + + DU = cloog_union_domain_add_domain(DU, entryName.c_str(), Domain, + Scattering, Stmt); + } + + return DU; +} + +CloogInput *Cloog::buildCloogInput() { + CloogDomain *Context = cloog_domain_from_isl_set(S->getContext()); + CloogUnionDomain *Statements = buildCloogUnionDomain(); + + isl_set *ScopContext = S->getContext(); + + for (unsigned i = 0; i < isl_set_dim(ScopContext, isl_dim_param); i++) { + isl_id *id = isl_set_get_dim_id(ScopContext, isl_dim_param, i); + Statements = cloog_union_domain_set_name(Statements, CLOOG_PARAM, i, + isl_id_get_name(id)); + isl_id_free(id); + } + + isl_set_free(ScopContext); + + CloogInput *Input = cloog_input_alloc(Context, Statements); + return Input; +} +} // End namespace polly. + +namespace { + +struct CloogExporter : public ScopPass { + static char ID; + Scop *S; + explicit CloogExporter() : ScopPass(ID) {} + + std::string getFileName(Region *R) const; + virtual bool runOnScop(Scop &S); + void getAnalysisUsage(AnalysisUsage &AU) const; +}; + +} +std::string CloogExporter::getFileName(Region *R) const { + std::string FunctionName = R->getEntry()->getParent()->getName(); + std::string ExitName, EntryName; + + raw_string_ostream ExitStr(ExitName); + raw_string_ostream EntryStr(EntryName); + + WriteAsOperand(EntryStr, R->getEntry(), false); + EntryStr.str(); + + if (R->getExit()) { + WriteAsOperand(ExitStr, R->getExit(), false); + ExitStr.str(); + } else + ExitName = "FunctionExit"; + + std::string RegionName = EntryName + "---" + ExitName; + std::string FileName = FunctionName + "___" + RegionName + ".cloog"; + + return FileName; +} + +char CloogExporter::ID = 0; +bool CloogExporter::runOnScop(Scop &S) { + Region &R = S.getRegion(); + CloogInfo &C = getAnalysis(); + + std::string FunctionName = R.getEntry()->getParent()->getName(); + std::string Filename = getFileName(&R); + + errs() << "Writing Scop '" << R.getNameStr() << "' in function '" + << FunctionName << "' to '" << Filename << "'...\n"; + + FILE *F = fopen(Filename.c_str(), "w"); + C.dump(F); + fclose(F); + + return false; +} + +void CloogExporter::getAnalysisUsage(AnalysisUsage &AU) const { + // Get the Common analysis usage of ScopPasses. + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); +} + +static RegisterPass A("polly-export-cloog", + "Polly - Export the Cloog input file" + " (Writes a .cloog file for each Scop)" + ); + +llvm::Pass *polly::createCloogExporterPass() { + return new CloogExporter(); +} + +/// Write a .cloog input file +void CloogInfo::dump(FILE *F) { + C->dump(F); +} + +/// Print a source code representation of the program. +void CloogInfo::pprint(llvm::raw_ostream &OS) { + C->pprint(OS); +} + +/// Create the Cloog AST from this program. +const struct clast_root *CloogInfo::getClast() { + return C->getClast(); +} + +void CloogInfo::releaseMemory() { + if (C) { + delete C; + C = 0; + } +} + +bool CloogInfo::runOnScop(Scop &S) { + if (C) + delete C; + + scop = &S; + + C = new Cloog(&S); + + Function *F = S.getRegion().getEntry()->getParent(); + + DEBUG(dbgs() << ":: " << F->getName()); + DEBUG(dbgs() << " : " << S.getRegion().getNameStr() << "\n");; + DEBUG(C->pprint(dbgs())); + + return false; +} + +void CloogInfo::printScop(raw_ostream &OS) const { + Function *function = scop->getRegion().getEntry()->getParent(); + + OS << function->getName() << "():\n"; + + C->pprint(OS); +} + +void CloogInfo::getAnalysisUsage(AnalysisUsage &AU) const { + // Get the Common analysis usage of ScopPasses. + ScopPass::getAnalysisUsage(AU); +} +char CloogInfo::ID = 0; + +INITIALIZE_PASS_BEGIN(CloogInfo, "polly-cloog", + "Execute Cloog code generation", false, false) +INITIALIZE_PASS_DEPENDENCY(ScopInfo) +INITIALIZE_PASS_END(CloogInfo, "polly-cloog", + "Execute Cloog code generation", false, false) + +Pass *polly::createCloogInfoPass() { + return new CloogInfo(); +} diff --git a/tools/polly/lib/CodeGeneration.cpp b/tools/polly/lib/CodeGeneration.cpp new file mode 100644 index 00000000000..9fdeb260d52 --- /dev/null +++ b/tools/polly/lib/CodeGeneration.cpp @@ -0,0 +1,1796 @@ +//===------ CodeGeneration.cpp - Code generate the Scops. -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The CodeGeneration pass takes a Scop created by ScopInfo and translates it +// back to LLVM-IR using Cloog. +// +// The Scop describes the high level memory behaviour of a control flow region. +// Transformation passes can update the schedule (execution order) of statements +// in the Scop. Cloog is used to generate an abstract syntax tree (clast) that +// reflects the updated execution order. This clast is used to create new +// LLVM-IR that is computational equivalent to the original control flow region, +// but executes its code in the new execution order defined by the changed +// scattering. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "polly-codegen" + +#include "polly/Cloog.h" +#include "polly/CodeGeneration.h" +#include "polly/Dependences.h" +#include "polly/LinkAllPasses.h" +#include "polly/ScopInfo.h" +#include "polly/TempScopInfo.h" +#include "polly/Support/GICHelper.h" + +#include "llvm/Module.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ScalarEvolutionExpander.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/IRBuilder.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +#define CLOOG_INT_GMP 1 +#include "cloog/cloog.h" +#include "cloog/isl/cloog.h" + +#include "isl/aff.h" + +#include +#include + +using namespace polly; +using namespace llvm; + +struct isl_set; + +namespace polly { + +bool EnablePollyVector; + +static cl::opt +Vector("enable-polly-vector", + cl::desc("Enable polly vector code generation"), cl::Hidden, + cl::location(EnablePollyVector), cl::init(false)); + +static cl::opt +OpenMP("enable-polly-openmp", + cl::desc("Generate OpenMP parallel code"), cl::Hidden, + cl::value_desc("OpenMP code generation enabled if true"), + cl::init(false)); + +static cl::opt +AtLeastOnce("enable-polly-atLeastOnce", + cl::desc("Give polly the hint, that every loop is executed at least" + "once"), cl::Hidden, + cl::value_desc("OpenMP code generation enabled if true"), + cl::init(false)); + +static cl::opt +Aligned("enable-polly-aligned", + cl::desc("Assumed aligned memory accesses."), cl::Hidden, + cl::value_desc("OpenMP code generation enabled if true"), + cl::init(false)); + +typedef DenseMap ValueMapT; +typedef DenseMap CharMapT; +typedef std::vector VectorValueMapT; +typedef struct { + Value *Result; + IRBuilder<> *Builder; +}IslPwAffUserInfo; + +// Create a new loop. +// +// @param Builder The builder used to create the loop. It also defines the +// place where to create the loop. +// @param UB The upper bound of the loop iv. +// @param Stride The number by which the loop iv is incremented after every +// iteration. +static Value *createLoop(IRBuilder<> *Builder, Value *LB, Value *UB, + APInt Stride, DominatorTree *DT, Pass *P, + BasicBlock **AfterBlock) { + Function *F = Builder->GetInsertBlock()->getParent(); + LLVMContext &Context = F->getContext(); + + BasicBlock *PreheaderBB = Builder->GetInsertBlock(); + BasicBlock *HeaderBB = BasicBlock::Create(Context, "polly.loop_header", F); + BasicBlock *BodyBB = BasicBlock::Create(Context, "polly.loop_body", F); + BasicBlock *AfterBB = SplitBlock(PreheaderBB, Builder->GetInsertPoint()++, P); + AfterBB->setName("polly.loop_after"); + + PreheaderBB->getTerminator()->setSuccessor(0, HeaderBB); + DT->addNewBlock(HeaderBB, PreheaderBB); + + Builder->SetInsertPoint(HeaderBB); + + // Use the type of upper and lower bound. + assert(LB->getType() == UB->getType() + && "Different types for upper and lower bound."); + + IntegerType *LoopIVType = dyn_cast(UB->getType()); + assert(LoopIVType && "UB is not integer?"); + + // IV + PHINode *IV = Builder->CreatePHI(LoopIVType, 2, "polly.loopiv"); + IV->addIncoming(LB, PreheaderBB); + + // IV increment. + Value *StrideValue = ConstantInt::get(LoopIVType, + Stride.zext(LoopIVType->getBitWidth())); + Value *IncrementedIV = Builder->CreateAdd(IV, StrideValue, + "polly.next_loopiv"); + + // Exit condition. + Value *CMP; + if (AtLeastOnce) { // At least on iteration. + UB = Builder->CreateAdd(UB, Builder->getInt64(1)); + CMP = Builder->CreateICmpNE(IV, UB); + } else { // Maybe not executed at all. + CMP = Builder->CreateICmpSLE(IV, UB); + } + + Builder->CreateCondBr(CMP, BodyBB, AfterBB); + DT->addNewBlock(BodyBB, HeaderBB); + + Builder->SetInsertPoint(BodyBB); + Builder->CreateBr(HeaderBB); + IV->addIncoming(IncrementedIV, BodyBB); + DT->changeImmediateDominator(AfterBB, HeaderBB); + + Builder->SetInsertPoint(BodyBB->begin()); + *AfterBlock = AfterBB; + + return IV; +} + +class BlockGenerator { + IRBuilder<> &Builder; + ValueMapT &VMap; + VectorValueMapT &ValueMaps; + Scop &S; + ScopStmt &Statement; + isl_set *ScatteringDomain; + +public: + BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, VectorValueMapT &vmaps, + ScopStmt &Stmt, __isl_keep isl_set *domain); + + const Region &getRegion(); + + Value *makeVectorOperand(Value *operand, int vectorWidth); + + Value *getOperand(const Value *oldOperand, ValueMapT &BBMap, + ValueMapT *VectorMap = 0); + + Type *getVectorPtrTy(const Value *V, int vectorWidth); + + /// @brief Load a vector from a set of adjacent scalars + /// + /// In case a set of scalars is known to be next to each other in memory, + /// create a vector load that loads those scalars + /// + /// %vector_ptr= bitcast double* %p to <4 x double>* + /// %vec_full = load <4 x double>* %vector_ptr + /// + Value *generateStrideOneLoad(const LoadInst *load, ValueMapT &BBMap, + int size); + + /// @brief Load a vector initialized from a single scalar in memory + /// + /// In case all elements of a vector are initialized to the same + /// scalar value, this value is loaded and shuffeled into all elements + /// of the vector. + /// + /// %splat_one = load <1 x double>* %p + /// %splat = shufflevector <1 x double> %splat_one, <1 x + /// double> %splat_one, <4 x i32> zeroinitializer + /// + Value *generateStrideZeroLoad(const LoadInst *load, ValueMapT &BBMap, + int size); + + /// @Load a vector from scalars distributed in memory + /// + /// In case some scalars a distributed randomly in memory. Create a vector + /// by loading each scalar and by inserting one after the other into the + /// vector. + /// + /// %scalar_1= load double* %p_1 + /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0 + /// %scalar 2 = load double* %p_2 + /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1 + /// + Value *generateUnknownStrideLoad(const LoadInst *load, + VectorValueMapT &scalarMaps, int size); + + static Value* islAffToValue(__isl_take isl_aff *Aff, + IslPwAffUserInfo *UserInfo); + + static int mergeIslAffValues(__isl_take isl_set *Set, + __isl_take isl_aff *Aff, void *User); + + Value* islPwAffToValue(__isl_take isl_pw_aff *PwAff); + + /// @brief Get the memory access offset to be added to the base address + std::vector getMemoryAccessIndex(__isl_keep isl_map *AccessRelation, + Value *BaseAddress); + + /// @brief Get the new operand address according to the changed access in + /// JSCOP file. + Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation, + Value *BaseAddress, const Value *OldOperand, + ValueMapT &BBMap); + + /// @brief Generate the operand address + Value *generateLocationAccessed(const Instruction *Inst, + const Value *Pointer, ValueMapT &BBMap ); + + Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap); + + /// @brief Load a value (or several values as a vector) from memory. + void generateLoad(const LoadInst *load, ValueMapT &vectorMap, + VectorValueMapT &scalarMaps, int vectorWidth); + + void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &BBMap, + ValueMapT &VectorMap, int VectorDimension, + int VectorWidth); + + void copyBinInst(const BinaryOperator *Inst, ValueMapT &BBMap, + ValueMapT &vectorMap, int vectorDimension, int vectorWidth); + + void copyVectorStore(const StoreInst *store, ValueMapT &BBMap, + ValueMapT &vectorMap, VectorValueMapT &scalarMaps, + int vectorDimension, int vectorWidth); + + void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap); + + bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap); + + int getVectorSize(); + + bool isVectorBlock(); + + void copyInstruction(const Instruction *Inst, ValueMapT &BBMap, + ValueMapT &vectorMap, VectorValueMapT &scalarMaps, + int vectorDimension, int vectorWidth); + + // Insert a copy of a basic block in the newly generated code. + // + // @param Builder The builder used to insert the code. It also specifies + // where to insert the code. + // @param BB The basic block to copy + // @param VMap A map returning for any old value its new equivalent. This + // is used to update the operands of the statements. + // For new statements a relation old->new is inserted in this + // map. + void copyBB(BasicBlock *BB, Pass *P); +}; + +BlockGenerator::BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, + VectorValueMapT &vmaps, ScopStmt &Stmt, + __isl_keep isl_set *domain) + : Builder(B), VMap(vmap), ValueMaps(vmaps), S(*Stmt.getParent()), + Statement(Stmt), ScatteringDomain(domain) {} + +const Region &BlockGenerator::getRegion() { + return S.getRegion(); +} + +Value *BlockGenerator::makeVectorOperand(Value *Operand, int VectorWidth) { + if (Operand->getType()->isVectorTy()) + return Operand; + + VectorType *VectorType = VectorType::get(Operand->getType(), VectorWidth); + Value *Vector = UndefValue::get(VectorType); + Vector = Builder.CreateInsertElement(Vector, Operand, Builder.getInt32(0)); + + std::vector Splat; + + for (int i = 0; i < VectorWidth; i++) + Splat.push_back (Builder.getInt32(0)); + + Constant *SplatVector = ConstantVector::get(Splat); + + return Builder.CreateShuffleVector(Vector, Vector, SplatVector); +} + +Value *BlockGenerator::getOperand(const Value *OldOperand, ValueMapT &BBMap, + ValueMapT *VectorMap) { + const Instruction *OpInst = dyn_cast(OldOperand); + + if (!OpInst) + return const_cast(OldOperand); + + if (VectorMap && VectorMap->count(OldOperand)) + return (*VectorMap)[OldOperand]; + + // IVS and Parameters. + if (VMap.count(OldOperand)) { + Value *NewOperand = VMap[OldOperand]; + + // Insert a cast if types are different + if (OldOperand->getType()->getScalarSizeInBits() + < NewOperand->getType()->getScalarSizeInBits()) + NewOperand = Builder.CreateTruncOrBitCast(NewOperand, + OldOperand->getType()); + + return NewOperand; + } + + // Instructions calculated in the current BB. + if (BBMap.count(OldOperand)) { + return BBMap[OldOperand]; + } + + // Ignore instructions that are referencing ops in the old BB. These + // instructions are unused. They where replace by new ones during + // createIndependentBlocks(). + if (getRegion().contains(OpInst->getParent())) + return NULL; + + return const_cast(OldOperand); +} + +Type *BlockGenerator::getVectorPtrTy(const Value *Val, int VectorWidth) { + PointerType *PointerTy = dyn_cast(Val->getType()); + assert(PointerTy && "PointerType expected"); + + Type *ScalarType = PointerTy->getElementType(); + VectorType *VectorType = VectorType::get(ScalarType, VectorWidth); + + return PointerType::getUnqual(VectorType); +} + +Value *BlockGenerator::generateStrideOneLoad(const LoadInst *Load, + ValueMapT &BBMap, int Size) { + const Value *Pointer = Load->getPointerOperand(); + Type *VectorPtrType = getVectorPtrTy(Pointer, Size); + Value *NewPointer = getOperand(Pointer, BBMap); + Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, + "vector_ptr"); + LoadInst *VecLoad = Builder.CreateLoad(VectorPtr, + Load->getName() + "_p_vec_full"); + if (!Aligned) + VecLoad->setAlignment(8); + + return VecLoad; +} + +Value *BlockGenerator::generateStrideZeroLoad(const LoadInst *Load, + ValueMapT &BBMap, int Size) { + const Value *Pointer = Load->getPointerOperand(); + Type *VectorPtrType = getVectorPtrTy(Pointer, 1); + Value *NewPointer = getOperand(Pointer, BBMap); + Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, + Load->getName() + "_p_vec_p"); + LoadInst *ScalarLoad= Builder.CreateLoad(VectorPtr, + Load->getName() + "_p_splat_one"); + + if (!Aligned) + ScalarLoad->setAlignment(8); + + Constant *SplatVector = + Constant::getNullValue(VectorType::get(Builder.getInt32Ty(), Size)); + + Value *VectorLoad = Builder.CreateShuffleVector(ScalarLoad, ScalarLoad, + SplatVector, + Load->getName() + + "_p_splat"); + return VectorLoad; +} + +Value *BlockGenerator::generateUnknownStrideLoad(const LoadInst *Load, + VectorValueMapT &ScalarMaps, + int Size) { + const Value *Pointer = Load->getPointerOperand(); + VectorType *VectorType = VectorType::get( + dyn_cast(Pointer->getType())->getElementType(), Size); + + Value *Vector = UndefValue::get(VectorType); + + for (int i = 0; i < Size; i++) { + Value *NewPointer = getOperand(Pointer, ScalarMaps[i]); + Value *ScalarLoad = Builder.CreateLoad(NewPointer, + Load->getName() + "_p_scalar_"); + Vector = Builder.CreateInsertElement(Vector, ScalarLoad, + Builder.getInt32(i), + Load->getName() + "_p_vec_"); + } + + return Vector; +} + +Value *BlockGenerator::islAffToValue(__isl_take isl_aff *Aff, + IslPwAffUserInfo *UserInfo) { + assert(isl_aff_is_cst(Aff) && "Only constant access functions supported"); + + IRBuilder<> *Builder = UserInfo->Builder; + + isl_int OffsetIsl; + mpz_t OffsetMPZ; + + isl_int_init(OffsetIsl); + mpz_init(OffsetMPZ); + isl_aff_get_constant(Aff, &OffsetIsl); + isl_int_get_gmp(OffsetIsl, OffsetMPZ); + + Value *OffsetValue = NULL; + APInt Offset = APInt_from_MPZ(OffsetMPZ); + OffsetValue = ConstantInt::get(Builder->getContext(), Offset); + + mpz_clear(OffsetMPZ); + isl_int_clear(OffsetIsl); + isl_aff_free(Aff); + + return OffsetValue; +} + +int BlockGenerator::mergeIslAffValues(__isl_take isl_set *Set, + __isl_take isl_aff *Aff, void *User) { + IslPwAffUserInfo *UserInfo = (IslPwAffUserInfo *)User; + + assert((UserInfo->Result == NULL) && "Result is already set." + "Currently only single isl_aff is supported"); + assert(isl_set_plain_is_universe(Set) + && "Code generation failed because the set is not universe"); + + UserInfo->Result = islAffToValue(Aff, UserInfo); + + isl_set_free(Set); + return 0; +} + +Value *BlockGenerator::islPwAffToValue(__isl_take isl_pw_aff *PwAff) { + IslPwAffUserInfo UserInfo; + UserInfo.Result = NULL; + UserInfo.Builder = &Builder; + isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &UserInfo); + assert(UserInfo.Result && "Code generation for isl_pw_aff failed"); + + isl_pw_aff_free(PwAff); + return UserInfo.Result; +} + +std::vector BlockGenerator::getMemoryAccessIndex( + __isl_keep isl_map *AccessRelation, Value *BaseAddress) { + assert((isl_map_dim(AccessRelation, isl_dim_out) == 1) + && "Only single dimensional access functions supported"); + + isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0); + Value *OffsetValue = islPwAffToValue(PwAff); + + PointerType *BaseAddressType = dyn_cast( + BaseAddress->getType()); + Type *ArrayTy = BaseAddressType->getElementType(); + Type *ArrayElementType = dyn_cast(ArrayTy)->getElementType(); + OffsetValue = Builder.CreateSExtOrBitCast(OffsetValue, ArrayElementType); + + std::vector IndexArray; + Value *NullValue = Constant::getNullValue(ArrayElementType); + IndexArray.push_back(NullValue); + IndexArray.push_back(OffsetValue); + return IndexArray; +} + +Value *BlockGenerator::getNewAccessOperand( + __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, const Value + *OldOperand, ValueMapT &BBMap) { + std::vector IndexArray = getMemoryAccessIndex(NewAccessRelation, + BaseAddress); + Value *NewOperand = Builder.CreateGEP(BaseAddress, IndexArray, + "p_newarrayidx_"); + return NewOperand; +} + +Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst, + const Value *Pointer, + ValueMapT &BBMap ) { + MemoryAccess &Access = Statement.getAccessFor(Inst); + isl_map *CurrentAccessRelation = Access.getAccessRelation(); + isl_map *NewAccessRelation = Access.getNewAccessRelation(); + + assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation) + && "Current and new access function use different spaces"); + + Value *NewPointer; + + if (!NewAccessRelation) { + NewPointer = getOperand(Pointer, BBMap); + } else { + Value *BaseAddress = const_cast(Access.getBaseAddr()); + NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, Pointer, + BBMap); + } + + isl_map_free(CurrentAccessRelation); + isl_map_free(NewAccessRelation); + return NewPointer; +} + +Value *BlockGenerator::generateScalarLoad(const LoadInst *Load, + ValueMapT &BBMap) { + const Value *Pointer = Load->getPointerOperand(); + const Instruction *Inst = dyn_cast(Load); + Value *NewPointer = generateLocationAccessed(Inst, Pointer, BBMap); + Value *ScalarLoad = Builder.CreateLoad(NewPointer, + Load->getName() + "_p_scalar_"); + return ScalarLoad; +} + +void BlockGenerator::generateLoad(const LoadInst *Load, ValueMapT &VectorMap, + VectorValueMapT &ScalarMaps, + int VectorWidth) { + if (ScalarMaps.size() == 1) { + ScalarMaps[0][Load] = generateScalarLoad(Load, ScalarMaps[0]); + return; + } + + Value *NewLoad; + + MemoryAccess &Access = Statement.getAccessFor(Load); + + assert(ScatteringDomain && "No scattering domain available"); + + if (Access.isStrideZero(isl_set_copy(ScatteringDomain))) + NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0], VectorWidth); + else if (Access.isStrideOne(isl_set_copy(ScatteringDomain))) + NewLoad = generateStrideOneLoad(Load, ScalarMaps[0], VectorWidth); + else + NewLoad = generateUnknownStrideLoad(Load, ScalarMaps, VectorWidth); + + VectorMap[Load] = NewLoad; +} + +void BlockGenerator::copyUnaryInst(const UnaryInstruction *Inst, + ValueMapT &BBMap, ValueMapT &VectorMap, + int VectorDimension, int VectorWidth) { + Value *NewOperand = getOperand(Inst->getOperand(0), BBMap, &VectorMap); + NewOperand = makeVectorOperand(NewOperand, VectorWidth); + + assert(isa(Inst) && "Can not generate vector code for instruction"); + + const CastInst *Cast = dyn_cast(Inst); + VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth); + VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType); +} + +void BlockGenerator::copyBinInst(const BinaryOperator *Inst, ValueMapT &BBMap, + ValueMapT &VectorMap, int VectorDimension, + int VectorWidth) { + Value *OpZero = Inst->getOperand(0); + Value *OpOne = Inst->getOperand(1); + + Value *NewOpZero, *NewOpOne; + NewOpZero = getOperand(OpZero, BBMap, &VectorMap); + NewOpOne = getOperand(OpOne, BBMap, &VectorMap); + + NewOpZero = makeVectorOperand(NewOpZero, VectorWidth); + NewOpOne = makeVectorOperand(NewOpOne, VectorWidth); + + Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero, + NewOpOne, + Inst->getName() + "p_vec"); + VectorMap[Inst] = NewInst; +} + +void BlockGenerator::copyVectorStore(const StoreInst *Store, ValueMapT &BBMap, + ValueMapT &VectorMap, + VectorValueMapT &ScalarMaps, + int VectorDimension, int VectorWidth) { + // In vector mode we only generate a store for the first dimension. + if (VectorDimension > 0) + return; + + MemoryAccess &Access = Statement.getAccessFor(Store); + + assert(ScatteringDomain && "No scattering domain available"); + + const Value *Pointer = Store->getPointerOperand(); + Value *Vector = getOperand(Store->getValueOperand(), BBMap, &VectorMap); + + if (Access.isStrideOne(isl_set_copy(ScatteringDomain))) { + Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth); + Value *NewPointer = getOperand(Pointer, BBMap, &VectorMap); + + Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType, + "vector_ptr"); + StoreInst *Store = Builder.CreateStore(Vector, VectorPtr); + + if (!Aligned) + Store->setAlignment(8); + } else { + for (unsigned i = 0; i < ScalarMaps.size(); i++) { + Value *Scalar = Builder.CreateExtractElement(Vector, + Builder.getInt32(i)); + Value *NewPointer = getOperand(Pointer, ScalarMaps[i]); + Builder.CreateStore(Scalar, NewPointer); + } + } +} + +void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap) { + Instruction *NewInst = Inst->clone(); + + // Replace old operands with the new ones. + for (Instruction::const_op_iterator OI = Inst->op_begin(), + OE = Inst->op_end(); OI != OE; ++OI) { + Value *OldOperand = *OI; + Value *NewOperand = getOperand(OldOperand, BBMap); + + if (!NewOperand) { + assert(!isa(NewInst) + && "Store instructions are always needed!"); + delete NewInst; + return; + } + + NewInst->replaceUsesOfWith(OldOperand, NewOperand); + } + + Builder.Insert(NewInst); + BBMap[Inst] = NewInst; + + if (!NewInst->getType()->isVoidTy()) + NewInst->setName("p_" + Inst->getName()); +} + +bool BlockGenerator::hasVectorOperands(const Instruction *Inst, + ValueMapT &VectorMap) { + for (Instruction::const_op_iterator OI = Inst->op_begin(), + OE = Inst->op_end(); OI != OE; ++OI) + if (VectorMap.count(*OI)) + return true; + return false; +} + +int BlockGenerator::getVectorSize() { + return ValueMaps.size(); +} + +bool BlockGenerator::isVectorBlock() { + return getVectorSize() > 1; +} + +void BlockGenerator::copyInstruction(const Instruction *Inst, ValueMapT &BBMap, + ValueMapT &VectorMap, + VectorValueMapT &ScalarMaps, + int VectorDimension, int VectorWidth) { + // Terminator instructions control the control flow. They are explicitally + // expressed in the clast and do not need to be copied. + if (Inst->isTerminator()) + return; + + if (isVectorBlock()) { + // If this instruction is already in the vectorMap, a vector instruction + // was already issued, that calculates the values of all dimensions. No + // need to create any more instructions. + if (VectorMap.count(Inst)) + return; + } + + if (const LoadInst *Load = dyn_cast(Inst)) { + generateLoad(Load, VectorMap, ScalarMaps, VectorWidth); + return; + } + + if (isVectorBlock() && hasVectorOperands(Inst, VectorMap)) { + if (const UnaryInstruction *UnaryInst = dyn_cast(Inst)) + copyUnaryInst(UnaryInst, BBMap, VectorMap, VectorDimension, VectorWidth); + else if + (const BinaryOperator *BinaryInst = dyn_cast(Inst)) + copyBinInst(BinaryInst, BBMap, VectorMap, VectorDimension, VectorWidth); + else if (const StoreInst *Store = dyn_cast(Inst)) + copyVectorStore(Store, BBMap, VectorMap, ScalarMaps, VectorDimension, + VectorWidth); + else + llvm_unreachable("Cannot issue vector code for this instruction"); + + return; + } + + copyInstScalar(Inst, BBMap); +} + +void BlockGenerator::copyBB(BasicBlock *BB, Pass *P) { + BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(), + Builder.GetInsertPoint(), P); + CopyBB->setName("polly." + BB->getName() + ".stmt"); + Builder.SetInsertPoint(CopyBB->begin()); + + // Create two maps that store the mapping from the original instructions of + // the old basic block to their copies in the new basic block. Those maps + // are basic block local. + // + // As vector code generation is supported there is one map for scalar values + // and one for vector values. + // + // In case we just do scalar code generation, the vectorMap is not used and + // the scalarMap has just one dimension, which contains the mapping. + // + // In case vector code generation is done, an instruction may either appear + // in the vector map once (as it is calculating >vectorwidth< values at a + // time. Or (if the values are calculated using scalar operations), it + // appears once in every dimension of the scalarMap. + VectorValueMapT ScalarBlockMap(getVectorSize()); + ValueMapT VectorBlockMap; + + for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); + II != IE; ++II) + for (int i = 0; i < getVectorSize(); i++) { + if (isVectorBlock()) + VMap = ValueMaps[i]; + + copyInstruction(II, ScalarBlockMap[i], VectorBlockMap, + ScalarBlockMap, i, getVectorSize()); + } +} + +/// Class to generate LLVM-IR that calculates the value of a clast_expr. +class ClastExpCodeGen { + IRBuilder<> &Builder; + const CharMapT *IVS; + + Value *codegen(const clast_name *e, Type *Ty); + Value *codegen(const clast_term *e, Type *Ty); + Value *codegen(const clast_binary *e, Type *Ty); + Value *codegen(const clast_reduction *r, Type *Ty); +public: + + // A generator for clast expressions. + // + // @param B The IRBuilder that defines where the code to calculate the + // clast expressions should be inserted. + // @param IVMAP A Map that translates strings describing the induction + // variables to the Values* that represent these variables + // on the LLVM side. + ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap); + + // Generates code to calculate a given clast expression. + // + // @param e The expression to calculate. + // @return The Value that holds the result. + Value *codegen(const clast_expr *e, Type *Ty); + + // @brief Reset the CharMap. + // + // This function is called to reset the CharMap to new one, while generating + // OpenMP code. + void setIVS(CharMapT *IVSNew); +}; + +Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) { + CharMapT::const_iterator I = IVS->find(e->name); + + assert(I != IVS->end() && "Clast name not found"); + + return Builder.CreateSExtOrBitCast(I->second, Ty); +} + +Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) { + APInt a = APInt_from_MPZ(e->val); + + Value *ConstOne = ConstantInt::get(Builder.getContext(), a); + ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty); + + if (!e->var) + return ConstOne; + + Value *var = codegen(e->var, Ty); + return Builder.CreateMul(ConstOne, var); +} + +Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) { + Value *LHS = codegen(e->LHS, Ty); + + APInt RHS_AP = APInt_from_MPZ(e->RHS); + + Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP); + RHS = Builder.CreateSExtOrBitCast(RHS, Ty); + + switch (e->type) { + case clast_bin_mod: + return Builder.CreateSRem(LHS, RHS); + case clast_bin_fdiv: + { + // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d + Value *One = ConstantInt::get(Builder.getInt1Ty(), 1); + Value *Zero = ConstantInt::get(Builder.getInt1Ty(), 0); + One = Builder.CreateZExtOrBitCast(One, Ty); + Zero = Builder.CreateZExtOrBitCast(Zero, Ty); + Value *Sum1 = Builder.CreateSub(LHS, RHS); + Value *Sum2 = Builder.CreateAdd(Sum1, One); + Value *isNegative = Builder.CreateICmpSLT(LHS, Zero); + Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS); + return Builder.CreateSDiv(Dividend, RHS); + } + case clast_bin_cdiv: + { + // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d + Value *One = ConstantInt::get(Builder.getInt1Ty(), 1); + Value *Zero = ConstantInt::get(Builder.getInt1Ty(), 0); + One = Builder.CreateZExtOrBitCast(One, Ty); + Zero = Builder.CreateZExtOrBitCast(Zero, Ty); + Value *Sum1 = Builder.CreateAdd(LHS, RHS); + Value *Sum2 = Builder.CreateSub(Sum1, One); + Value *isNegative = Builder.CreateICmpSLT(LHS, Zero); + Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2); + return Builder.CreateSDiv(Dividend, RHS); + } + case clast_bin_div: + return Builder.CreateSDiv(LHS, RHS); + }; + + llvm_unreachable("Unknown clast binary expression type"); +} + +Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) { + assert(( r->type == clast_red_min + || r->type == clast_red_max + || r->type == clast_red_sum) + && "Clast reduction type not supported"); + Value *old = codegen(r->elts[0], Ty); + + for (int i=1; i < r->n; ++i) { + Value *exprValue = codegen(r->elts[i], Ty); + + switch (r->type) { + case clast_red_min: + { + Value *cmp = Builder.CreateICmpSLT(old, exprValue); + old = Builder.CreateSelect(cmp, old, exprValue); + break; + } + case clast_red_max: + { + Value *cmp = Builder.CreateICmpSGT(old, exprValue); + old = Builder.CreateSelect(cmp, old, exprValue); + break; + } + case clast_red_sum: + old = Builder.CreateAdd(old, exprValue); + break; + } + } + + return old; +} + +ClastExpCodeGen::ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap) + : Builder(B), IVS(IVMap) {} + +Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) { + switch(e->type) { + case clast_expr_name: + return codegen((const clast_name *)e, Ty); + case clast_expr_term: + return codegen((const clast_term *)e, Ty); + case clast_expr_bin: + return codegen((const clast_binary *)e, Ty); + case clast_expr_red: + return codegen((const clast_reduction *)e, Ty); + } + + llvm_unreachable("Unknown clast expression!"); +} + +void ClastExpCodeGen::setIVS(CharMapT *IVSNew) { + IVS = IVSNew; +} + +class ClastStmtCodeGen { + // The Scop we code generate. + Scop *S; + ScalarEvolution &SE; + DominatorTree *DT; + ScopDetection *SD; + Dependences *DP; + TargetData *TD; + Pass *P; + + // The Builder specifies the current location to code generate at. + IRBuilder<> &Builder; + + // Map the Values from the old code to their counterparts in the new code. + ValueMapT ValueMap; + + // clastVars maps from the textual representation of a clast variable to its + // current *Value. clast variables are scheduling variables, original + // induction variables or parameters. They are used either in loop bounds or + // to define the statement instance that is executed. + // + // for (s = 0; s < n + 3; ++i) + // for (t = s; t < m; ++j) + // Stmt(i = s + 3 * m, j = t); + // + // {s,t,i,j,n,m} is the set of clast variables in this clast. + CharMapT *clastVars; + + // Codegenerator for clast expressions. + ClastExpCodeGen ExpGen; + + // Do we currently generate parallel code? + bool parallelCodeGeneration; + + std::vector parallelLoops; + +public: + + const std::vector &getParallelLoops(); + + protected: + void codegen(const clast_assignment *a); + + void codegen(const clast_assignment *a, ScopStmt *Statement, + unsigned Dimension, int vectorDim, + std::vector *VectorVMap = 0); + + void codegenSubstitutions(const clast_stmt *Assignment, + ScopStmt *Statement, int vectorDim = 0, + std::vector *VectorVMap = 0); + + void codegen(const clast_user_stmt *u, std::vector *IVS = NULL, + const char *iterator = NULL, isl_set *scatteringDomain = 0); + + void codegen(const clast_block *b); + + /// @brief Create a classical sequential loop. + void codegenForSequential(const clast_for *f, Value *LowerBound = 0, + Value *UpperBound = 0); + + /// @brief Add a new definition of an openmp subfunction. + Function *addOpenMPSubfunction(Module *M); + + /// @brief Add values to the OpenMP structure. + /// + /// Create the subfunction structure and add the values from the list. + Value *addValuesToOpenMPStruct(SetVector OMPDataVals, + Function *SubFunction); + + /// @brief Create OpenMP structure values. + /// + /// Create a list of values that has to be stored into the subfuncition + /// structure. + SetVector createOpenMPStructValues(); + + /// @brief Extract the values from the subfunction parameter. + /// + /// Extract the values from the subfunction parameter and update the clast + /// variables to point to the new values. + void extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP, + SetVector OMPDataVals, + Value *userContext); + + /// @brief Add body to the subfunction. + void addOpenMPSubfunctionBody(Function *FN, const clast_for *f, + Value *structData, + SetVector OMPDataVals); + + /// @brief Create an OpenMP parallel for loop. + /// + /// This loop reflects a loop as if it would have been created by an OpenMP + /// statement. + void codegenForOpenMP(const clast_for *f); + + bool isInnermostLoop(const clast_for *f); + + /// @brief Get the number of loop iterations for this loop. + /// @param f The clast for loop to check. + int getNumberOfIterations(const clast_for *f); + + /// @brief Create vector instructions for this loop. + void codegenForVector(const clast_for *f); + + void codegen(const clast_for *f); + + Value *codegen(const clast_equation *eq); + + void codegen(const clast_guard *g); + + void codegen(const clast_stmt *stmt); + + void addParameters(const CloogNames *names); + + public: + void codegen(const clast_root *r); + + ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, DominatorTree *dt, + ScopDetection *sd, Dependences *dp, TargetData *td, + IRBuilder<> &B, Pass *P); +}; +} + +const std::vector &ClastStmtCodeGen::getParallelLoops() { + return parallelLoops; +} + +void ClastStmtCodeGen::codegen(const clast_assignment *a) { + Value *V= ExpGen.codegen(a->RHS, TD->getIntPtrType(Builder.getContext())); + (*clastVars)[a->LHS] = V; +} + +void ClastStmtCodeGen::codegen(const clast_assignment *a, ScopStmt *Statement, + unsigned Dimension, int vectorDim, + std::vector *VectorVMap) { + Value *RHS = ExpGen.codegen(a->RHS, + TD->getIntPtrType(Builder.getContext())); + + assert(!a->LHS && "Statement assignments do not have left hand side"); + const PHINode *PN; + PN = Statement->getInductionVariableForDimension(Dimension); + const Value *V = PN; + + if (VectorVMap) + (*VectorVMap)[vectorDim][V] = RHS; + + ValueMap[V] = RHS; +} + +void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment, + ScopStmt *Statement, int vectorDim, + std::vector *VectorVMap) { + int Dimension = 0; + + while (Assignment) { + assert(CLAST_STMT_IS_A(Assignment, stmt_ass) + && "Substitions are expected to be assignments"); + codegen((const clast_assignment *)Assignment, Statement, Dimension, + vectorDim, VectorVMap); + Assignment = Assignment->next; + Dimension++; + } +} + +void ClastStmtCodeGen::codegen(const clast_user_stmt *u, + std::vector *IVS , const char *iterator, + isl_set *scatteringDomain) { + ScopStmt *Statement = (ScopStmt *)u->statement->usr; + BasicBlock *BB = Statement->getBasicBlock(); + + if (u->substitutions) + codegenSubstitutions(u->substitutions, Statement); + + int vectorDimensions = IVS ? IVS->size() : 1; + + VectorValueMapT VectorValueMap(vectorDimensions); + + if (IVS) { + assert (u->substitutions && "Substitutions expected!"); + int i = 0; + for (std::vector::iterator II = IVS->begin(), IE = IVS->end(); + II != IE; ++II) { + (*clastVars)[iterator] = *II; + codegenSubstitutions(u->substitutions, Statement, i, &VectorValueMap); + i++; + } + } + + BlockGenerator Generator(Builder, ValueMap, VectorValueMap, *Statement, + scatteringDomain); + Generator.copyBB(BB, P); +} + +void ClastStmtCodeGen::codegen(const clast_block *b) { + if (b->body) + codegen(b->body); +} + +void ClastStmtCodeGen::codegenForSequential(const clast_for *f, + Value *LowerBound, + Value *UpperBound) { + APInt Stride; + BasicBlock *AfterBB; + Type *IntPtrTy; + + Stride = APInt_from_MPZ(f->stride); + IntPtrTy = TD->getIntPtrType(Builder.getContext()); + + // The value of lowerbound and upperbound will be supplied, if this + // function is called while generating OpenMP code. Otherwise get + // the values. + assert(!!LowerBound == !!UpperBound && "Either give both bounds or none"); + + if (LowerBound == 0) { + LowerBound = ExpGen.codegen(f->LB, IntPtrTy); + UpperBound = ExpGen.codegen(f->UB, IntPtrTy); + } + + Value *IV = createLoop(&Builder, LowerBound, UpperBound, Stride, DT, P, + &AfterBB); + + // Add loop iv to symbols. + (*clastVars)[f->iterator] = IV; + + if (f->body) + codegen(f->body); + + // Loop is finished, so remove its iv from the live symbols. + clastVars->erase(f->iterator); + Builder.SetInsertPoint(AfterBB->begin()); +} + +Function *ClastStmtCodeGen::addOpenMPSubfunction(Module *M) { + Function *F = Builder.GetInsertBlock()->getParent(); + std::vector Arguments(1, Builder.getInt8PtrTy()); + FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false); + Function *FN = Function::Create(FT, Function::InternalLinkage, + F->getName() + ".omp_subfn", M); + // Do not run any polly pass on the new function. + SD->markFunctionAsInvalid(FN); + + Function::arg_iterator AI = FN->arg_begin(); + AI->setName("omp.userContext"); + + return FN; +} + +Value *ClastStmtCodeGen::addValuesToOpenMPStruct(SetVector OMPDataVals, + Function *SubFunction) { + std::vector structMembers; + + // Create the structure. + for (unsigned i = 0; i < OMPDataVals.size(); i++) + structMembers.push_back(OMPDataVals[i]->getType()); + + StructType *structTy = StructType::get(Builder.getContext(), + structMembers); + // Store the values into the structure. + Value *structData = Builder.CreateAlloca(structTy, 0, "omp.userContext"); + for (unsigned i = 0; i < OMPDataVals.size(); i++) { + Value *storeAddr = Builder.CreateStructGEP(structData, i); + Builder.CreateStore(OMPDataVals[i], storeAddr); + } + + return structData; +} + +SetVector ClastStmtCodeGen::createOpenMPStructValues() { + SetVector OMPDataVals; + + // Push the clast variables available in the clastVars. + for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end(); + I != E; I++) + OMPDataVals.insert(I->second); + + // Push the base addresses of memory references. + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + for (SmallVector::iterator I = Stmt->memacc_begin(), + E = Stmt->memacc_end(); I != E; ++I) { + Value *BaseAddr = const_cast((*I)->getBaseAddr()); + OMPDataVals.insert((BaseAddr)); + } + } + + return OMPDataVals; +} + +void ClastStmtCodeGen::extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP, + SetVector OMPDataVals, Value *userContext) { + // Extract the clast variables. + unsigned i = 0; + for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end(); + I != E; I++) { + Value *loadAddr = Builder.CreateStructGEP(userContext, i); + (*clastVarsOMP)[I->first] = Builder.CreateLoad(loadAddr); + i++; + } + + // Extract the base addresses of memory references. + for (unsigned j = i; j < OMPDataVals.size(); j++) { + Value *loadAddr = Builder.CreateStructGEP(userContext, j); + Value *baseAddr = OMPDataVals[j]; + ValueMap[baseAddr] = Builder.CreateLoad(loadAddr); + } +} + +void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN, + const clast_for *f, + Value *structData, + SetVector OMPDataVals) { + Module *M = Builder.GetInsertBlock()->getParent()->getParent(); + LLVMContext &Context = FN->getContext(); + IntegerType *intPtrTy = TD->getIntPtrType(Context); + + // Store the previous basic block. + BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint(); + BasicBlock *PrevBB = Builder.GetInsertBlock(); + + // Create basic blocks. + BasicBlock *HeaderBB = BasicBlock::Create(Context, "omp.setup", FN); + BasicBlock *ExitBB = BasicBlock::Create(Context, "omp.exit", FN); + BasicBlock *checkNextBB = BasicBlock::Create(Context, "omp.checkNext", FN); + BasicBlock *loadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds", + FN); + + DT->addNewBlock(HeaderBB, PrevBB); + DT->addNewBlock(ExitBB, HeaderBB); + DT->addNewBlock(checkNextBB, HeaderBB); + DT->addNewBlock(loadIVBoundsBB, HeaderBB); + + // Fill up basic block HeaderBB. + Builder.SetInsertPoint(HeaderBB); + Value *lowerBoundPtr = Builder.CreateAlloca(intPtrTy, 0, + "omp.lowerBoundPtr"); + Value *upperBoundPtr = Builder.CreateAlloca(intPtrTy, 0, + "omp.upperBoundPtr"); + Value *userContext = Builder.CreateBitCast(FN->arg_begin(), + structData->getType(), + "omp.userContext"); + + CharMapT clastVarsOMP; + extractValuesFromOpenMPStruct(&clastVarsOMP, OMPDataVals, userContext); + + Builder.CreateBr(checkNextBB); + + // Add code to check if another set of iterations will be executed. + Builder.SetInsertPoint(checkNextBB); + Function *runtimeNextFunction = M->getFunction("GOMP_loop_runtime_next"); + Value *ret1 = Builder.CreateCall2(runtimeNextFunction, + lowerBoundPtr, upperBoundPtr); + Value *hasNextSchedule = Builder.CreateTrunc(ret1, Builder.getInt1Ty(), + "omp.hasNextScheduleBlock"); + Builder.CreateCondBr(hasNextSchedule, loadIVBoundsBB, ExitBB); + + // Add code to to load the iv bounds for this set of iterations. + Builder.SetInsertPoint(loadIVBoundsBB); + Value *lowerBound = Builder.CreateLoad(lowerBoundPtr, "omp.lowerBound"); + Value *upperBound = Builder.CreateLoad(upperBoundPtr, "omp.upperBound"); + + // Subtract one as the upper bound provided by openmp is a < comparison + // whereas the codegenForSequential function creates a <= comparison. + upperBound = Builder.CreateSub(upperBound, ConstantInt::get(intPtrTy, 1), + "omp.upperBoundAdjusted"); + + // Use clastVarsOMP during code generation of the OpenMP subfunction. + CharMapT *oldClastVars = clastVars; + clastVars = &clastVarsOMP; + ExpGen.setIVS(&clastVarsOMP); + + Builder.CreateBr(checkNextBB); + Builder.SetInsertPoint(--Builder.GetInsertPoint()); + codegenForSequential(f, lowerBound, upperBound); + + // Restore the old clastVars. + clastVars = oldClastVars; + ExpGen.setIVS(oldClastVars); + + // Add code to terminate this openmp subfunction. + Builder.SetInsertPoint(ExitBB); + Function *endnowaitFunction = M->getFunction("GOMP_loop_end_nowait"); + Builder.CreateCall(endnowaitFunction); + Builder.CreateRetVoid(); + + // Restore the previous insert point. + Builder.SetInsertPoint(PrevInsertPoint); +} + +void ClastStmtCodeGen::codegenForOpenMP(const clast_for *f) { + Module *M = Builder.GetInsertBlock()->getParent()->getParent(); + IntegerType *intPtrTy = TD->getIntPtrType(Builder.getContext()); + + Function *SubFunction = addOpenMPSubfunction(M); + SetVector OMPDataVals = createOpenMPStructValues(); + Value *structData = addValuesToOpenMPStruct(OMPDataVals, SubFunction); + + addOpenMPSubfunctionBody(SubFunction, f, structData, OMPDataVals); + + // Create call for GOMP_parallel_loop_runtime_start. + Value *subfunctionParam = Builder.CreateBitCast(structData, + Builder.getInt8PtrTy(), + "omp_data"); + + Value *numberOfThreads = Builder.getInt32(0); + Value *lowerBound = ExpGen.codegen(f->LB, intPtrTy); + Value *upperBound = ExpGen.codegen(f->UB, intPtrTy); + + // Add one as the upper bound provided by openmp is a < comparison + // whereas the codegenForSequential function creates a <= comparison. + upperBound = Builder.CreateAdd(upperBound, ConstantInt::get(intPtrTy, 1)); + APInt APStride = APInt_from_MPZ(f->stride); + Value *stride = ConstantInt::get(intPtrTy, + APStride.zext(intPtrTy->getBitWidth())); + + SmallVector Arguments; + Arguments.push_back(SubFunction); + Arguments.push_back(subfunctionParam); + Arguments.push_back(numberOfThreads); + Arguments.push_back(lowerBound); + Arguments.push_back(upperBound); + Arguments.push_back(stride); + + Function *parallelStartFunction = + M->getFunction("GOMP_parallel_loop_runtime_start"); + Builder.CreateCall(parallelStartFunction, Arguments); + + // Create call to the subfunction. + Builder.CreateCall(SubFunction, subfunctionParam); + + // Create call for GOMP_parallel_end. + Function *FN = M->getFunction("GOMP_parallel_end"); + Builder.CreateCall(FN); +} + +bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) { + const clast_stmt *stmt = f->body; + + while (stmt) { + if (!CLAST_STMT_IS_A(stmt, stmt_user)) + return false; + + stmt = stmt->next; + } + + return true; +} + +int ClastStmtCodeGen::getNumberOfIterations(const clast_for *f) { + isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain)); + isl_set *tmp = isl_set_copy(loopDomain); + + // Calculate a map similar to the identity map, but with the last input + // and output dimension not related. + // [i0, i1, i2, i3] -> [i0, i1, i2, o0] + isl_space *Space = isl_set_get_space(loopDomain); + Space = isl_space_drop_outputs(Space, + isl_set_dim(loopDomain, isl_dim_set) - 2, 1); + Space = isl_space_map_from_set(Space); + isl_map *identity = isl_map_identity(Space); + identity = isl_map_add_dims(identity, isl_dim_in, 1); + identity = isl_map_add_dims(identity, isl_dim_out, 1); + + isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain); + map = isl_map_intersect(map, identity); + + isl_map *lexmax = isl_map_lexmax(isl_map_copy(map)); + isl_map *lexmin = isl_map_lexmin(map); + isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin)); + + isl_set *elements = isl_map_range(sub); + + if (!isl_set_is_singleton(elements)) { + isl_set_free(elements); + return -1; + } + + isl_point *p = isl_set_sample_point(elements); + + isl_int v; + isl_int_init(v); + isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v); + int numberIterations = isl_int_get_si(v); + isl_int_clear(v); + isl_point_free(p); + + return (numberIterations) / isl_int_get_si(f->stride) + 1; +} + +void ClastStmtCodeGen::codegenForVector(const clast_for *f) { + DEBUG(dbgs() << "Vectorizing loop '" << f->iterator << "'\n";); + int vectorWidth = getNumberOfIterations(f); + + Value *LB = ExpGen.codegen(f->LB, + TD->getIntPtrType(Builder.getContext())); + + APInt Stride = APInt_from_MPZ(f->stride); + IntegerType *LoopIVType = dyn_cast(LB->getType()); + Stride = Stride.zext(LoopIVType->getBitWidth()); + Value *StrideValue = ConstantInt::get(LoopIVType, Stride); + + std::vector IVS(vectorWidth); + IVS[0] = LB; + + for (int i = 1; i < vectorWidth; i++) + IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv"); + + isl_set *scatteringDomain = + isl_set_copy(isl_set_from_cloog_domain(f->domain)); + + // Add loop iv to symbols. + (*clastVars)[f->iterator] = LB; + + const clast_stmt *stmt = f->body; + + while (stmt) { + codegen((const clast_user_stmt *)stmt, &IVS, f->iterator, + scatteringDomain); + stmt = stmt->next; + } + + // Loop is finished, so remove its iv from the live symbols. + isl_set_free(scatteringDomain); + clastVars->erase(f->iterator); +} + +void ClastStmtCodeGen::codegen(const clast_for *f) { + if (Vector && isInnermostLoop(f) && DP->isParallelFor(f) + && (-1 != getNumberOfIterations(f)) + && (getNumberOfIterations(f) <= 16)) { + codegenForVector(f); + } else if (OpenMP && !parallelCodeGeneration && DP->isParallelFor(f)) { + parallelCodeGeneration = true; + parallelLoops.push_back(f->iterator); + codegenForOpenMP(f); + parallelCodeGeneration = false; + } else + codegenForSequential(f); +} + +Value *ClastStmtCodeGen::codegen(const clast_equation *eq) { + Value *LHS = ExpGen.codegen(eq->LHS, + TD->getIntPtrType(Builder.getContext())); + Value *RHS = ExpGen.codegen(eq->RHS, + TD->getIntPtrType(Builder.getContext())); + CmpInst::Predicate P; + + if (eq->sign == 0) + P = ICmpInst::ICMP_EQ; + else if (eq->sign > 0) + P = ICmpInst::ICMP_SGE; + else + P = ICmpInst::ICMP_SLE; + + return Builder.CreateICmp(P, LHS, RHS); +} + +void ClastStmtCodeGen::codegen(const clast_guard *g) { + Function *F = Builder.GetInsertBlock()->getParent(); + LLVMContext &Context = F->getContext(); + + BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(), + Builder.GetInsertPoint(), P); + CondBB->setName("polly.cond"); + BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P); + MergeBB->setName("polly.merge"); + BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F); + + DT->addNewBlock(ThenBB, CondBB); + DT->changeImmediateDominator(MergeBB, CondBB); + + CondBB->getTerminator()->eraseFromParent(); + + Builder.SetInsertPoint(CondBB); + + Value *Predicate = codegen(&(g->eq[0])); + + for (int i = 1; i < g->n; ++i) { + Value *TmpPredicate = codegen(&(g->eq[i])); + Predicate = Builder.CreateAnd(Predicate, TmpPredicate); + } + + Builder.CreateCondBr(Predicate, ThenBB, MergeBB); + Builder.SetInsertPoint(ThenBB); + Builder.CreateBr(MergeBB); + Builder.SetInsertPoint(ThenBB->begin()); + + codegen(g->then); +} + +void ClastStmtCodeGen::codegen(const clast_stmt *stmt) { + if (CLAST_STMT_IS_A(stmt, stmt_root)) + assert(false && "No second root statement expected"); + else if (CLAST_STMT_IS_A(stmt, stmt_ass)) + codegen((const clast_assignment *)stmt); + else if (CLAST_STMT_IS_A(stmt, stmt_user)) + codegen((const clast_user_stmt *)stmt); + else if (CLAST_STMT_IS_A(stmt, stmt_block)) + codegen((const clast_block *)stmt); + else if (CLAST_STMT_IS_A(stmt, stmt_for)) + codegen((const clast_for *)stmt); + else if (CLAST_STMT_IS_A(stmt, stmt_guard)) + codegen((const clast_guard *)stmt); + + if (stmt->next) + codegen(stmt->next); +} + +void ClastStmtCodeGen::addParameters(const CloogNames *names) { + SCEVExpander Rewriter(SE, "polly"); + + int i = 0; + for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end(); + PI != PE; ++PI) { + assert(i < names->nb_parameters && "Not enough parameter names"); + + const SCEV *Param = *PI; + Type *Ty = Param->getType(); + + Instruction *insertLocation = --(Builder.GetInsertBlock()->end()); + Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation); + (*clastVars)[names->parameters[i]] = V; + + ++i; + } +} + +void ClastStmtCodeGen::codegen(const clast_root *r) { + clastVars = new CharMapT(); + addParameters(r->names); + ExpGen.setIVS(clastVars); + + parallelCodeGeneration = false; + + const clast_stmt *stmt = (const clast_stmt*) r; + if (stmt->next) + codegen(stmt->next); + + delete clastVars; +} + +ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, + DominatorTree *dt, ScopDetection *sd, + Dependences *dp, TargetData *td, + IRBuilder<> &B, Pass *P) : + S(scop), SE(se), DT(dt), SD(sd), DP(dp), TD(td), P(P), Builder(B), + ExpGen(Builder, NULL) {} + +namespace { +class CodeGeneration : public ScopPass { + Region *region; + Scop *S; + DominatorTree *DT; + ScalarEvolution *SE; + ScopDetection *SD; + TargetData *TD; + RegionInfo *RI; + + std::vector parallelLoops; + + public: + static char ID; + + CodeGeneration() : ScopPass(ID) {} + + // Add the declarations needed by the OpenMP function calls that we insert in + // OpenMP mode. + void addOpenMPDeclarations(Module *M) + { + IRBuilder<> Builder(M->getContext()); + IntegerType *LongTy = TD->getIntPtrType(M->getContext()); + + llvm::GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; + + if (!M->getFunction("GOMP_parallel_end")) { + FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false); + Function::Create(Ty, Linkage, "GOMP_parallel_end", M); + } + + if (!M->getFunction("GOMP_parallel_loop_runtime_start")) { + Type *Params[] = { + PointerType::getUnqual(FunctionType::get(Builder.getVoidTy(), + Builder.getInt8PtrTy(), + false)), + Builder.getInt8PtrTy(), + Builder.getInt32Ty(), + LongTy, + LongTy, + LongTy, + }; + + FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false); + Function::Create(Ty, Linkage, "GOMP_parallel_loop_runtime_start", M); + } + + if (!M->getFunction("GOMP_loop_runtime_next")) { + PointerType *LongPtrTy = PointerType::getUnqual(LongTy); + Type *Params[] = { + LongPtrTy, + LongPtrTy, + }; + + FunctionType *Ty = FunctionType::get(Builder.getInt8Ty(), Params, false); + Function::Create(Ty, Linkage, "GOMP_loop_runtime_next", M); + } + + if (!M->getFunction("GOMP_loop_end_nowait")) { + FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false); + Function::Create(Ty, Linkage, "GOMP_loop_end_nowait", M); + } + } + + // Split the entry edge of the region and generate a new basic block on this + // edge. This function also updates ScopInfo and RegionInfo. + // + // @param region The region where the entry edge will be splitted. + BasicBlock *splitEdgeAdvanced(Region *region) { + BasicBlock *newBlock; + BasicBlock *splitBlock; + + newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this); + + if (DT->dominates(region->getEntry(), newBlock)) { + // Update ScopInfo. + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) + if ((*SI)->getBasicBlock() == newBlock) { + (*SI)->setBasicBlock(newBlock); + break; + } + + // Update RegionInfo. + splitBlock = region->getEntry(); + region->replaceEntry(newBlock); + RI->setRegionFor(newBlock, region); + } else { + RI->setRegionFor(newBlock, region->getParent()); + splitBlock = newBlock; + } + + return splitBlock; + } + + // Create a split block that branches either to the old code or to a new basic + // block where the new code can be inserted. + // + // @param Builder A builder that will be set to point to a basic block, where + // the new code can be generated. + // @return The split basic block. + BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) { + BasicBlock *StartBlock, *SplitBlock; + + SplitBlock = splitEdgeAdvanced(region); + SplitBlock->setName("polly.split_new_and_old"); + Function *F = SplitBlock->getParent(); + StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F); + SplitBlock->getTerminator()->eraseFromParent(); + Builder->SetInsertPoint(SplitBlock); + Builder->CreateCondBr(Builder->getTrue(), StartBlock, region->getEntry()); + DT->addNewBlock(StartBlock, SplitBlock); + Builder->SetInsertPoint(StartBlock); + return SplitBlock; + } + + // Merge the control flow of the newly generated code with the existing code. + // + // @param SplitBlock The basic block where the control flow was split between + // old and new version of the Scop. + // @param Builder An IRBuilder that points to the last instruction of the + // newly generated code. + void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) { + BasicBlock *MergeBlock; + Region *R = region; + + if (R->getExit()->getSinglePredecessor()) + // No splitEdge required. A block with a single predecessor cannot have + // PHI nodes that would complicate life. + MergeBlock = R->getExit(); + else { + MergeBlock = SplitEdge(R->getExitingBlock(), R->getExit(), this); + // SplitEdge will never split R->getExit(), as R->getExit() has more than + // one predecessor. Hence, mergeBlock is always a newly generated block. + R->replaceExit(MergeBlock); + } + + Builder->CreateBr(MergeBlock); + MergeBlock->setName("polly.merge_new_and_old"); + + if (DT->dominates(SplitBlock, MergeBlock)) + DT->changeImmediateDominator(MergeBlock, SplitBlock); + } + + bool runOnScop(Scop &scop) { + S = &scop; + region = &S->getRegion(); + DT = &getAnalysis(); + Dependences *DP = &getAnalysis(); + SE = &getAnalysis(); + SD = &getAnalysis(); + TD = &getAnalysis(); + RI = &getAnalysis(); + + parallelLoops.clear(); + + assert(region->isSimple() && "Only simple regions are supported"); + + Module *M = region->getEntry()->getParent()->getParent(); + + if (OpenMP) addOpenMPDeclarations(M); + + // In the CFG the optimized code of the SCoP is generated next to the + // original code. Both the new and the original version of the code remain + // in the CFG. A branch statement decides which version is executed. + // For now, we always execute the new version (the old one is dead code + // eliminated by the cleanup passes). In the future we may decide to execute + // the new version only if certain run time checks succeed. This will be + // useful to support constructs for which we cannot prove all assumptions at + // compile time. + // + // Before transformation: + // + // bb0 + // | + // orig_scop + // | + // bb1 + // + // After transformation: + // bb0 + // | + // polly.splitBlock + // / \. + // | startBlock + // | | + // orig_scop new_scop + // \ / + // \ / + // bb1 (joinBlock) + IRBuilder<> builder(region->getEntry()); + + // The builder will be set to startBlock. + BasicBlock *splitBlock = addSplitAndStartBlock(&builder); + BasicBlock *StartBlock = builder.GetInsertBlock(); + + mergeControlFlow(splitBlock, &builder); + builder.SetInsertPoint(StartBlock->begin()); + + ClastStmtCodeGen CodeGen(S, *SE, DT, SD, DP, TD, builder, this); + CloogInfo &C = getAnalysis(); + CodeGen.codegen(C.getClast()); + + parallelLoops.insert(parallelLoops.begin(), + CodeGen.getParallelLoops().begin(), + CodeGen.getParallelLoops().end()); + + return true; + } + + virtual void printScop(raw_ostream &OS) const { + for (std::vector::const_iterator PI = parallelLoops.begin(), + PE = parallelLoops.end(); PI != PE; ++PI) + OS << "Parallel loop with iterator '" << *PI << "' generated\n"; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + + AU.addPreserved(); + AU.addPreserved(); + + // FIXME: We do not create LoopInfo for the newly generated loops. + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + + // FIXME: We do not yet add regions for the newly generated code to the + // region tree. + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreservedID(IndependentBlocksID); + } +}; +} + +char CodeGeneration::ID = 1; + +INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen", + "Polly - Create LLVM-IR form SCoPs", false, false) +INITIALIZE_PASS_DEPENDENCY(CloogInfo) +INITIALIZE_PASS_DEPENDENCY(Dependences) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(RegionInfo) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) +INITIALIZE_PASS_DEPENDENCY(ScopDetection) +INITIALIZE_PASS_DEPENDENCY(TargetData) +INITIALIZE_PASS_END(CodeGeneration, "polly-codegen", + "Polly - Create LLVM-IR form SCoPs", false, false) + +Pass *polly::createCodeGenerationPass() { + return new CodeGeneration(); +} diff --git a/tools/polly/lib/CodePreparation.cpp b/tools/polly/lib/CodePreparation.cpp new file mode 100644 index 00000000000..5c7342e34a2 --- /dev/null +++ b/tools/polly/lib/CodePreparation.cpp @@ -0,0 +1,174 @@ +//===---- CodePreparation.cpp - Code preparation for Scop Detection -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implement the code preparation for Scop detect, which will: +// 1. Translate all PHINodes that not induction variable to memory access, +// this will easier parameter and scalar dependencies checking. +// +//===----------------------------------------------------------------------===// +#include "polly/LinkAllPasses.h" +#include "polly/Support/ScopHelper.h" + +#include "llvm/Instruction.h" +#include "llvm/Pass.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/RegionInfo.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/InstIterator.h" +#include "llvm/Transforms/Utils/Local.h" + +#define DEBUG_TYPE "polly-code-prep" +#include "llvm/Support/Debug.h" + + +using namespace llvm; +using namespace polly; + +namespace { +//===----------------------------------------------------------------------===// +/// @brief Scop Code Preparation - Perform some transforms to make scop detect +/// easier. +/// +class CodePreparation : public FunctionPass { + // DO NOT IMPLEMENT. + CodePreparation(const CodePreparation &); + // DO NOT IMPLEMENT. + const CodePreparation &operator=(const CodePreparation &); + + // LoopInfo to compute canonical induction variable. + LoopInfo *LI; + + // Clear the context. + void clear(); + + bool eliminatePHINodes(Function &F); + +public: + static char ID; + + explicit CodePreparation() : FunctionPass(ID) {} + ~CodePreparation(); + + /// @name FunctionPass interface. + //@{ + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + virtual void releaseMemory(); + virtual bool runOnFunction(Function &F); + virtual void print(raw_ostream &OS, const Module *) const; + //@} + +}; +} + +//===----------------------------------------------------------------------===// +/// CodePreparation implement. + +void CodePreparation::clear() { +} + +CodePreparation::~CodePreparation() { + clear(); +} + +bool CodePreparation::eliminatePHINodes(Function &F) { + // The PHINodes that will be deleted. + std::vector PNtoDel; + // The PHINodes that will be preserved. + std::vector PreservedPNs; + + // Scan the PHINodes in this function. + for (Function::iterator ibb = F.begin(), ibe = F.end(); + ibb != ibe; ++ibb) + for (BasicBlock::iterator iib = ibb->begin(), iie = ibb->getFirstNonPHI(); + iib != iie; ++iib) + if (PHINode *PN = cast(iib)) { + if (Loop *L = LI->getLoopFor(ibb)) { + // Induction variable will be preserved. + if (L->getCanonicalInductionVariable() == PN) { + PreservedPNs.push_back(PN); + continue; + } + } + + // As DemotePHIToStack does not support invoke edges, we preserve + // PHINodes that have invoke edges. + if (hasInvokeEdge(PN)) + PreservedPNs.push_back(PN); + else + PNtoDel.push_back(PN); + } + + if (PNtoDel.empty()) + return false; + + // Eliminate the PHINodes that not an Induction variable. + while (!PNtoDel.empty()) { + PHINode *PN = PNtoDel.back(); + PNtoDel.pop_back(); + + DemotePHIToStack(PN); + } + + // Move all preserved PHINodes to the beginning of the BasicBlock. + while (!PreservedPNs.empty()) { + PHINode *PN = PreservedPNs.back(); + PreservedPNs.pop_back(); + + BasicBlock *BB = PN->getParent(); + if (PN == BB->begin()) + continue; + + PN->moveBefore(BB->begin()); + } + + return true; +} + +void CodePreparation::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); +} + +bool CodePreparation::runOnFunction(Function &F) { + LI = &getAnalysis(); + + splitEntryBlockForAlloca(&F.getEntryBlock(), this); + + eliminatePHINodes(F); + + return false; +} + +void CodePreparation::releaseMemory() { + clear(); +} + +void CodePreparation::print(raw_ostream &OS, const Module *) const { +} + +char CodePreparation::ID = 0; +char &polly::CodePreparationID = CodePreparation::ID; + +INITIALIZE_PASS_BEGIN(CodePreparation, "polly-prepare", + "Polly - Prepare code for polly", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_END(CodePreparation, "polly-prepare", + "Polly - Prepare code for polly", false, false) + +Pass *polly::createCodePreparationPass() { + return new CodePreparation(); +} diff --git a/tools/polly/lib/DeadCodeElimination.cpp b/tools/polly/lib/DeadCodeElimination.cpp new file mode 100644 index 00000000000..734a0ce1b56 --- /dev/null +++ b/tools/polly/lib/DeadCodeElimination.cpp @@ -0,0 +1,75 @@ +//===- DeadCodeElimination.cpp - Eliminate dead iteration ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// If values calculated within an iteration are not used later on the iteration +// can be removed entirely. This pass removes such iterations. +//===----------------------------------------------------------------------===// + +#include "polly/Dependences.h" +#include "polly/LinkAllPasses.h" +#include "polly/ScopInfo.h" + +#include "isl/union_map.h" + +using namespace llvm; +using namespace polly; + +namespace { + + class DeadCodeElim : public ScopPass { + + public: + static char ID; + explicit DeadCodeElim() : ScopPass(ID) {} + + virtual bool runOnScop(Scop &S); + void printScop(llvm::raw_ostream &OS) const; + void getAnalysisUsage(AnalysisUsage &AU) const; + }; +} + +char DeadCodeElim::ID = 0; + +bool DeadCodeElim::runOnScop(Scop &S) { + Dependences *D = &getAnalysis(); + + int dependencyKinds = Dependences::TYPE_RAW + | Dependences::TYPE_WAR + | Dependences::TYPE_WAW; + + isl_union_map *dependences = D->getDependences(dependencyKinds); + + // The idea of this pass is to loop over all statments and remove statement + // iterations that do not calculate any value that is read later on. We need + // to make sure to forward RAR and WAR dependences. + // + // A case where this pass might be useful is + // http://llvm.org/bugs/show_bug.cgi?id=5117 + isl_union_map_free(dependences); + return false; +} + +void DeadCodeElim::printScop(raw_ostream &OS) const { +} + +void DeadCodeElim::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); +} + +INITIALIZE_PASS_BEGIN(DeadCodeElim, "polly-dce", + "Polly - Remove dead iterations", false, false) +INITIALIZE_PASS_DEPENDENCY(Dependences) +INITIALIZE_PASS_DEPENDENCY(ScopInfo) +INITIALIZE_PASS_END(DeadCodeElim, "polly-dce", + "Polly - Remove dead iterations", false, false) + +Pass* polly::createDeadCodeElimPass() { + return new DeadCodeElim(); +} diff --git a/tools/polly/lib/Exchange/CMakeLists.txt b/tools/polly/lib/Exchange/CMakeLists.txt new file mode 100644 index 00000000000..2268e099c22 --- /dev/null +++ b/tools/polly/lib/Exchange/CMakeLists.txt @@ -0,0 +1,18 @@ +if (OPENSCOP_FOUND) + set(POLLY_OPENSCOP_FILES + OpenScopImporter.cpp + OpenScopExporter.cpp) +endif (OPENSCOP_FOUND) + +if (SCOPLIB_FOUND) + set(POLLY_SCOPLIB_FILES + ScopLib.cpp + ScopLibExporter.cpp + ScopLibImporter.cpp) +endif (SCOPLIB_FOUND) + +add_polly_library(PollyExchange + JSONExporter.cpp + ${POLLY_OPENSCOP_FILES} + ${POLLY_SCOPLIB_FILES} +) diff --git a/tools/polly/lib/Exchange/JSONExporter.cpp b/tools/polly/lib/Exchange/JSONExporter.cpp new file mode 100755 index 00000000000..d9c569b45df --- /dev/null +++ b/tools/polly/lib/Exchange/JSONExporter.cpp @@ -0,0 +1,352 @@ +//===-- JSONExporter.cpp - Export Scops as JSON -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Export the Scops build by ScopInfo pass as a JSON file. +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" +#include "polly/Dependences.h" +#include "polly/ScopInfo.h" +#include "polly/ScopPass.h" + +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/system_error.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/ADT/Statistic.h" + +#define DEBUG_TYPE "polly-import-jscop" + +#include "json/reader.h" +#include "json/writer.h" + +#include "isl/set.h" +#include "isl/map.h" +#include "isl/constraint.h" +#include "isl/printer.h" + +#include + +using namespace llvm; +using namespace polly; + +STATISTIC(NewAccessMapFound, "Number of updated access functions"); + +namespace { +static cl::opt +ImportDir("polly-import-jscop-dir", + cl::desc("The directory to import the .jscop files from."), + cl::Hidden, cl::value_desc("Directory path"), cl::ValueRequired, + cl::init(".")); + +static cl::opt +ImportPostfix("polly-import-jscop-postfix", + cl::desc("Postfix to append to the import .jsop files."), + cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired, + cl::init("")); + +struct JSONExporter : public ScopPass { + static char ID; + Scop *S; + explicit JSONExporter() : ScopPass(ID) {} + + std::string getFileName(Scop *S) const; + Json::Value getJSON(Scop &scop) const; + virtual bool runOnScop(Scop &S); + void printScop(raw_ostream &OS) const; + void getAnalysisUsage(AnalysisUsage &AU) const; +}; + +struct JSONImporter : public ScopPass { + static char ID; + Scop *S; + std::vector newAccessStrings; + explicit JSONImporter() : ScopPass(ID) {} + + std::string getFileName(Scop *S) const; + virtual bool runOnScop(Scop &S); + void printScop(raw_ostream &OS) const; + void getAnalysisUsage(AnalysisUsage &AU) const; +}; + +} + +char JSONExporter::ID = 0; +std::string JSONExporter::getFileName(Scop *S) const { + std::string FunctionName = + S->getRegion().getEntry()->getParent()->getName(); + std::string FileName = FunctionName + "___" + S->getNameStr() + ".jscop"; + return FileName; +} + +void JSONExporter::printScop(raw_ostream &OS) const { + S->print(OS); +} + +Json::Value JSONExporter::getJSON(Scop &scop) const { + Json::Value root; + + root["name"] = S->getRegion().getNameStr(); + root["context"] = S->getContextStr(); + root["statements"]; + + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (Stmt->isFinalRead()) + continue; + + Json::Value statement; + + statement["name"] = Stmt->getBaseName(); + statement["domain"] = Stmt->getDomainStr(); + statement["schedule"] = Stmt->getScatteringStr(); + statement["accesses"]; + + for (ScopStmt::memacc_iterator MI = Stmt->memacc_begin(), + ME = Stmt->memacc_end(); MI != ME; ++MI) { + Json::Value access; + + access["kind"] = (*MI)->isRead() ? "read" : "write"; + access["relation"] = (*MI)->getAccessRelationStr(); + + statement["accesses"].append(access); + } + + root["statements"].append(statement); + } + + return root; +} + +bool JSONExporter::runOnScop(Scop &scop) { + S = &scop; + Region &R = S->getRegion(); + + std::string FileName = ImportDir + "/" + getFileName(S); + + Json::Value jscop = getJSON(scop); + Json::StyledWriter writer; + std::string fileContent = writer.write(jscop); + + // Write to file. + std::string ErrInfo; + tool_output_file F(FileName.c_str(), ErrInfo); + + std::string FunctionName = R.getEntry()->getParent()->getName(); + errs() << "Writing JScop '" << R.getNameStr() << "' in function '" + << FunctionName << "' to '" << FileName << "'.\n"; + + if (ErrInfo.empty()) { + F.os() << fileContent; + F.os().close(); + if (!F.os().has_error()) { + errs() << "\n"; + F.keep(); + return false; + } + } + + errs() << " error opening file for writing!\n"; + F.os().clear_error(); + + return false; +} + +void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); +} + +INITIALIZE_PASS_BEGIN(JSONExporter, "polly-export-jscop", + "Polly - Export Scops as JSON" + " (Writes a .jscop file for each Scop)", false, false) +INITIALIZE_PASS_DEPENDENCY(Dependences) +INITIALIZE_PASS_END(JSONExporter, "polly-export-jscop", + "Polly - Export Scops as JSON" + " (Writes a .jscop file for each Scop)", false, false) + +Pass *polly::createJSONExporterPass() { + return new JSONExporter(); +} + +char JSONImporter::ID = 0; +std::string JSONImporter::getFileName(Scop *S) const { + std::string FunctionName = + S->getRegion().getEntry()->getParent()->getName(); + std::string FileName = FunctionName + "___" + S->getNameStr() + ".jscop"; + + if (ImportPostfix != "") + FileName += "." + ImportPostfix; + + return FileName; +} + +void JSONImporter::printScop(raw_ostream &OS) const { + S->print(OS); + for (std::vector::const_iterator I = newAccessStrings.begin(), + E = newAccessStrings.end(); I != E; I++) + OS << "New access function '" << *I << "'detected in JSCOP file\n"; +} + +typedef Dependences::StatementToIslMapTy StatementToIslMapTy; + +bool JSONImporter::runOnScop(Scop &scop) { + S = &scop; + Region &R = S->getRegion(); + Dependences *D = &getAnalysis(); + + std::string FileName = ImportDir + "/" + getFileName(S); + + std::string FunctionName = R.getEntry()->getParent()->getName(); + errs() << "Reading JScop '" << R.getNameStr() << "' in function '" + << FunctionName << "' from '" << FileName << "'.\n"; + OwningPtr result; + error_code ec = MemoryBuffer::getFile(FileName, result); + + if (ec) { + errs() << "File could not be read: " << ec.message() << "\n"; + return false; + } + + Json::Reader reader; + Json::Value jscop; + + bool parsingSuccessful = reader.parse(result->getBufferStart(), jscop); + + if (!parsingSuccessful) { + errs() << "JSCoP file could not be parsed\n"; + return false; + } + + isl_set *OldContext = S->getContext(); + isl_set *NewContext = isl_set_read_from_str(S->getIslCtx(), + jscop["context"].asCString()); + + for (unsigned i = 0; i < isl_set_dim(OldContext, isl_dim_param); i++) { + isl_id *id = isl_set_get_dim_id(OldContext, isl_dim_param, i); + NewContext = isl_set_set_dim_id(NewContext, isl_dim_param, i, id); + + } + + isl_set_free(OldContext); + S->setContext(NewContext); + + StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy()); + + int index = 0; + + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (Stmt->isFinalRead()) + continue; + Json::Value schedule = jscop["statements"][index]["schedule"]; + + isl_map *m = isl_map_read_from_str(S->getIslCtx(), schedule.asCString()); + NewScattering[*SI] = m; + index++; + } + + if (!D->isValidScattering(&NewScattering)) { + errs() << "JScop file contains a scattering that changes the " + << "dependences. Use -disable-polly-legality to continue anyways\n"; + return false; + } + + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (NewScattering.find(Stmt) != NewScattering.end()) + Stmt->setScattering(NewScattering[Stmt]); + } + + int statementIdx = 0; + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (Stmt->isFinalRead()) + continue; + + int memoryAccessIdx = 0; + for (ScopStmt::memacc_iterator MI = Stmt->memacc_begin(), + ME = Stmt->memacc_end(); MI != ME; ++MI) { + Json::Value accesses = jscop["statements"][statementIdx] + ["accesses"][memoryAccessIdx]["relation"]; + isl_map *newAccessMap = isl_map_read_from_str(S->getIslCtx(), + accesses.asCString()); + isl_map *currentAccessMap = (*MI)->getAccessRelation(); + + if (isl_map_dim(newAccessMap, isl_dim_param) != + isl_map_dim(currentAccessMap, isl_dim_param)) { + errs() << "JScop file changes the number of parameter dimensions\n"; + isl_map_free(currentAccessMap); + isl_map_free(newAccessMap); + return false; + + } + + // We need to copy the isl_ids for the parameter dimensions to the new + // map. Without doing this the current map would have different + // ids then the new one, even though both are named identically. + for (unsigned i = 0; i < isl_map_dim(currentAccessMap, isl_dim_param); + i++) { + isl_id *id = isl_map_get_dim_id(currentAccessMap, isl_dim_param, i); + newAccessMap = isl_map_set_dim_id(newAccessMap, isl_dim_param, i, id); + } + + if (!isl_map_has_equal_space(currentAccessMap, newAccessMap)) { + errs() << "JScop file contains access function with incompatible " + << "dimensions\n"; + isl_map_free(currentAccessMap); + isl_map_free(newAccessMap); + return false; + } + if (isl_map_dim(newAccessMap, isl_dim_out) != 1) { + errs() << "New access map in JScop file should be single dimensional\n"; + isl_map_free(currentAccessMap); + isl_map_free(newAccessMap); + return false; + } + if (!isl_map_is_equal(newAccessMap, currentAccessMap)) { + // Statistics. + ++NewAccessMapFound; + newAccessStrings.push_back(accesses.asCString()); + (*MI)->setNewAccessRelation(newAccessMap); + } else { + isl_map_free(newAccessMap); + } + isl_map_free(currentAccessMap); + memoryAccessIdx++; + } + statementIdx++; + } + + return false; +} + +void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); +} + +INITIALIZE_PASS_BEGIN(JSONImporter, "polly-import-jscop", + "Polly - Import Scops from JSON" + " (Reads a .jscop file for each Scop)", false, false) +INITIALIZE_PASS_DEPENDENCY(Dependences) +INITIALIZE_PASS_END(JSONImporter, "polly-import-jscop", + "Polly - Import Scops from JSON" + " (Reads a .jscop file for each Scop)", false, false) + +Pass *polly::createJSONImporterPass() { + return new JSONImporter(); +} diff --git a/tools/polly/lib/Exchange/Makefile b/tools/polly/lib/Exchange/Makefile new file mode 100755 index 00000000000..61ad3ae10c5 --- /dev/null +++ b/tools/polly/lib/Exchange/Makefile @@ -0,0 +1,16 @@ +##===- polly/lib/Exchange/Makefile ----------------*- Makefile -*-===## + +# +# Indicate where we are relative to the top of the source tree. +# +LEVEL=../.. + +LIBRARYNAME=pollyexchange +BUILD_ARCHIVE = 1 + +CPP.Flags += $(POLLY_INC) + +# +# Include Makefile.common so we know what to do. +# +include $(LEVEL)/Makefile.common \ No newline at end of file diff --git a/tools/polly/lib/Exchange/OpenScopExporter.cpp b/tools/polly/lib/Exchange/OpenScopExporter.cpp new file mode 100755 index 00000000000..7f1af1d0861 --- /dev/null +++ b/tools/polly/lib/Exchange/OpenScopExporter.cpp @@ -0,0 +1,589 @@ +//===-- OpenScopExporter.cpp - Export Scops with openscop library --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Export the Scops build by ScopInfo pass to text file. +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" + +#ifdef OPENSCOP_FOUND + +#include "polly/ScopInfo.h" +#include "polly/ScopPass.h" + +#include "llvm/Support/CommandLine.h" +#include "llvm/Assembly/Writer.h" + +#define OPENSCOP_INT_T_IS_MP +#include "openscop/openscop.h" + +#include "stdio.h" +#include "isl/map.h" +#include "isl/set.h" +#include "isl/constraint.h" + +using namespace llvm; +using namespace polly; + +namespace { +static cl::opt +ExportDir("polly-export-dir", + cl::desc("The directory to export the .scop files to."), cl::Hidden, + cl::value_desc("Directory path"), cl::ValueRequired, cl::init(".")); + +struct ScopExporter : public ScopPass { + static char ID; + Scop *S; + explicit ScopExporter() : ScopPass(ID) {} + + std::string getFileName(Scop *S) const; + + virtual bool runOnScop(Scop &S); + void printScop(raw_ostream &OS) const; + void getAnalysisUsage(AnalysisUsage &AU) const; +}; + +} + +char ScopExporter::ID = 0; + +class OpenScop { + Scop *PollyScop; + openscop_scop_p openscop; + + std::map ArrayMap; + + void initializeArrays(); + void initializeParameters(); + void initializeScattering(); + void initializeStatements(); + openscop_statement_p initializeStatement(ScopStmt *stmt); + void freeStatement(openscop_statement_p stmt); + static int accessToMatrix_constraint(isl_constraint *c, void *user); + static int accessToMatrix_basic_map(isl_basic_map *bmap, void *user); + openscop_matrix_p createAccessMatrix(ScopStmt *S, bool isRead); + static int domainToMatrix_constraint(isl_constraint *c, void *user); + static int domainToMatrix_basic_set(isl_basic_set *bset, void *user); + openscop_matrix_p domainToMatrix(isl_set *PS); + static int scatteringToMatrix_constraint(isl_constraint *c, void *user); + static int scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user); + openscop_matrix_p scatteringToMatrix(isl_map *pmap); + +public: + OpenScop(Scop *S); + ~OpenScop(); + void print(FILE *F); + +}; + +OpenScop::OpenScop(Scop *S) : PollyScop(S) { + openscop = openscop_scop_malloc(); + + initializeArrays(); + initializeParameters(); + initializeScattering(); + initializeStatements(); +} + +void OpenScop::initializeParameters() { + openscop->nb_parameters = PollyScop->getNumParams(); + openscop->parameters = new char*[openscop->nb_parameters]; + + for (int i = 0; i < openscop->nb_parameters; ++i) { + openscop->parameters[i] = new char[20]; + sprintf(openscop->parameters[i], "p_%d", i); + } +} + +void OpenScop::initializeArrays() { + int nb_arrays = 0; + + for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE; + ++SI) + for (ScopStmt::memacc_iterator MI = (*SI)->memacc_begin(), + ME = (*SI)->memacc_end(); MI != ME; ++MI) { + const Value *BaseAddr = (*MI)->getBaseAddr(); + if (ArrayMap.find(BaseAddr) == ArrayMap.end()) { + ArrayMap.insert(std::make_pair(BaseAddr, nb_arrays)); + ++nb_arrays; + } + } + + openscop->nb_arrays = nb_arrays; + openscop->arrays = new char*[nb_arrays]; + + for (int i = 0; i < nb_arrays; ++i) + for (std::map::iterator VI = ArrayMap.begin(), + VE = ArrayMap.end(); VI != VE; ++VI) + if ((*VI).second == i) { + const Value *V = (*VI).first; + std::string name = V->getName(); + openscop->arrays[i] = new char[name.size() + 1]; + strcpy(openscop->arrays[i], name.c_str()); + } +} + +void OpenScop::initializeScattering() { + openscop->nb_scattdims = PollyScop->getScatterDim(); + openscop->scattdims = new char*[openscop->nb_scattdims]; + + for (int i = 0; i < openscop->nb_scattdims; ++i) { + openscop->scattdims[i] = new char[20]; + sprintf(openscop->scattdims[i], "s_%d", i); + } +} + +openscop_statement_p OpenScop::initializeStatement(ScopStmt *stmt) { + openscop_statement_p Stmt = openscop_statement_malloc(); + + // Domain & Schedule + isl_set *domain = stmt->getDomain(); + Stmt->domain = domainToMatrix(domain); + isl_map *Scattering = stmt->getScattering(); + Stmt->schedule = scatteringToMatrix(Scattering); + isl_set_free(domain); + isl_map_free(Scattering); + + + // Statement name + const char *entryName = stmt->getBaseName(); + Stmt->body = (char*)malloc(sizeof(char) * (strlen(entryName) + 1)); + strcpy(Stmt->body, entryName); + + // Iterator names + Stmt->nb_iterators = isl_set_n_dim(stmt->getDomain()); + Stmt->iterators = new char*[Stmt->nb_iterators]; + + for (int i = 0; i < Stmt->nb_iterators; ++i) { + Stmt->iterators[i] = new char[20]; + sprintf(Stmt->iterators[i], "i_%d", i); + } + + // Memory Accesses + Stmt->read = createAccessMatrix(stmt, true); + Stmt->write = createAccessMatrix(stmt, false); + + return Stmt; +} + +void OpenScop::initializeStatements() { + for (Scop::reverse_iterator SI = PollyScop->rbegin(), SE = PollyScop->rend(); + SI != SE; ++SI) { + if ((*SI)->isFinalRead()) + continue; + openscop_statement_p stmt = initializeStatement(*SI); + stmt->next = openscop->statement; + openscop->statement = stmt; + } +} + +void OpenScop::freeStatement(openscop_statement_p stmt) { + + if (stmt->read) + openscop_matrix_free(stmt->read); + stmt->read = NULL; + + if (stmt->write) + openscop_matrix_free(stmt->write); + stmt->write = NULL; + + if (stmt->domain) + openscop_matrix_free(stmt->domain); + stmt->domain = NULL; + + if (stmt->schedule) + openscop_matrix_free(stmt->schedule); + stmt->schedule = NULL; + + for (int i = 0; i < stmt->nb_iterators; ++i) + delete[](stmt->iterators[i]); + + delete[](stmt->iterators); + stmt->iterators = NULL; + stmt->nb_iterators = 0; + + delete[](stmt->body); + stmt->body = NULL; + + openscop_statement_free(stmt); +} + +void OpenScop::print(FILE *F) { + openscop_scop_print_dot_scop(F, openscop); +} + +/// Add an isl constraint to an OpenScop matrix. +/// +/// @param user The matrix +/// @param c The constraint +int OpenScop::domainToMatrix_constraint(isl_constraint *c, void *user) { + openscop_matrix_p m = (openscop_matrix_p) user; + + int nb_params = isl_constraint_dim(c, isl_space_param); + int nb_vars = isl_constraint_dim(c, isl_space_set); + int nb_div = isl_constraint_dim(c, isl_space_div); + + assert(!nb_div && "Existentially quantified variables not yet supported"); + + openscop_vector_p vec = openscop_vector_malloc(nb_params + nb_vars + 2); + + // Assign type + if (isl_constraint_is_equality(c)) + openscop_vector_tag_equality(vec); + else + openscop_vector_tag_inequality(vec); + + isl_int v; + isl_int_init(v); + + // Assign variables + for (int i = 0; i < nb_vars; ++i) { + isl_constraint_get_coefficient(c, isl_space_set, i, &v); + isl_int_set(vec->p[i + 1], v); + } + + // Assign parameters + for (int i = 0; i < nb_params; ++i) { + isl_constraint_get_coefficient(c, isl_space_param, i, &v); + isl_int_set(vec->p[nb_vars + i + 1], v); + } + + // Assign constant + isl_constraint_get_constant(c, &v); + isl_int_set(vec->p[nb_params + nb_vars + 1], v); + + openscop_matrix_insert_vector(m, vec, m->NbRows); + + return 0; +} + +/// Add an isl basic set to a OpenScop matrix_list +/// +/// @param bset The basic set to add +/// @param user The matrix list we should add the basic set to +/// +/// XXX: At the moment this function expects just a matrix, as support +/// for matrix lists is currently not available in OpenScop. So union of +/// polyhedron are not yet supported +int OpenScop::domainToMatrix_basic_set(isl_basic_set *bset, void *user) { + openscop_matrix_p m = (openscop_matrix_p) user; + assert(!m->NbRows && "Union of polyhedron not yet supported"); + + isl_basic_set_foreach_constraint(bset, &domainToMatrix_constraint, user); + return 0; +} + +/// Translate a isl_set to a OpenScop matrix. +/// +/// @param PS The set to be translated +/// @return A OpenScop Matrix +openscop_matrix_p OpenScop::domainToMatrix(isl_set *PS) { + + // Create a canonical copy of this set. + isl_set *set = isl_set_copy(PS); + set = isl_set_compute_divs (set); + set = isl_set_align_divs (set); + + // Initialize the matrix. + unsigned NbRows, NbColumns; + NbRows = 0; + NbColumns = isl_set_n_dim(PS) + isl_set_n_param(PS) + 2; + openscop_matrix_p matrix = openscop_matrix_malloc(NbRows, NbColumns); + + // Copy the content into the matrix. + isl_set_foreach_basic_set(set, &domainToMatrix_basic_set, matrix); + + isl_set_free(set); + + return matrix; +} + +/// Add an isl constraint to an OpenScop matrix. +/// +/// @param user The matrix +/// @param c The constraint +int OpenScop::scatteringToMatrix_constraint(isl_constraint *c, void *user) { + openscop_matrix_p m = (openscop_matrix_p) user; + + int nb_params = isl_constraint_dim(c, isl_space_param); + int nb_in = isl_constraint_dim(c, isl_space_in); + int nb_out = isl_constraint_dim(c, isl_space_out); + int nb_div = isl_constraint_dim(c, isl_space_div); + + assert(!nb_div && "Existentially quantified variables not yet supported"); + + openscop_vector_p vec = + openscop_vector_malloc(nb_params + nb_in + nb_out + 2); + + // Assign type + if (isl_constraint_is_equality(c)) + openscop_vector_tag_equality(vec); + else + openscop_vector_tag_inequality(vec); + + isl_int v; + isl_int_init(v); + + // Assign scattering + for (int i = 0; i < nb_out; ++i) { + isl_constraint_get_coefficient(c, isl_space_out, i, &v); + isl_int_set(vec->p[i + 1], v); + } + + // Assign variables + for (int i = 0; i < nb_in; ++i) { + isl_constraint_get_coefficient(c, isl_space_in, i, &v); + isl_int_set(vec->p[nb_out + i + 1], v); + } + + // Assign parameters + for (int i = 0; i < nb_params; ++i) { + isl_constraint_get_coefficient(c, isl_space_param, i, &v); + isl_int_set(vec->p[nb_out + nb_in + i + 1], v); + } + + // Assign constant + isl_constraint_get_constant(c, &v); + isl_int_set(vec->p[nb_out + nb_in + nb_params + 1], v); + + openscop_matrix_insert_vector(m, vec, m->NbRows); + + return 0; +} + +/// Add an isl basic map to a OpenScop matrix_list +/// +/// @param bmap The basic map to add +/// @param user The matrix list we should add the basic map to +/// +/// XXX: At the moment this function expects just a matrix, as support +/// for matrix lists is currently not available in OpenScop. So union of +/// polyhedron are not yet supported +int OpenScop::scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user) { + openscop_matrix_p m = (openscop_matrix_p) user; + assert(!m->NbRows && "Union of polyhedron not yet supported"); + + isl_basic_map_foreach_constraint(bmap, &scatteringToMatrix_constraint, user); + return 0; +} + +/// Translate a isl_map to a OpenScop matrix. +/// +/// @param map The map to be translated +/// @return A OpenScop Matrix +openscop_matrix_p OpenScop::scatteringToMatrix(isl_map *pmap) { + + // Create a canonical copy of this set. + isl_map *map = isl_map_copy(pmap); + map = isl_map_compute_divs (map); + map = isl_map_align_divs (map); + + // Initialize the matrix. + unsigned NbRows, NbColumns; + NbRows = 0; + NbColumns = isl_map_n_in(pmap) + isl_map_n_out(pmap) + isl_map_n_param(pmap) + + 2; + openscop_matrix_p matrix = openscop_matrix_malloc(NbRows, NbColumns); + + // Copy the content into the matrix. + isl_map_foreach_basic_map(map, &scatteringToMatrix_basic_map, matrix); + + isl_map_free(map); + + return matrix; +} + +/// Add an isl constraint to an OpenScop matrix. +/// +/// @param user The matrix +/// @param c The constraint +int OpenScop::accessToMatrix_constraint(isl_constraint *c, void *user) { + openscop_matrix_p m = (openscop_matrix_p) user; + + int nb_params = isl_constraint_dim(c, isl_space_param); + int nb_in = isl_constraint_dim(c, isl_space_in); + int nb_div = isl_constraint_dim(c, isl_space_div); + + assert(!nb_div && "Existentially quantified variables not yet supported"); + + openscop_vector_p vec = + openscop_vector_malloc(nb_params + nb_in + 2); + + isl_int v; + isl_int_init(v); + + // The access dimension has to be one. + isl_constraint_get_coefficient(c, isl_space_out, 0, &v); + assert(isl_int_is_one(v)); + bool inverse = true ; + + // Assign variables + for (int i = 0; i < nb_in; ++i) { + isl_constraint_get_coefficient(c, isl_space_in, i, &v); + + if (inverse) isl_int_neg(v,v); + + isl_int_set(vec->p[i + 1], v); + } + + // Assign parameters + for (int i = 0; i < nb_params; ++i) { + isl_constraint_get_coefficient(c, isl_space_param, i, &v); + + if (inverse) isl_int_neg(v,v); + + isl_int_set(vec->p[nb_in + i + 1], v); + } + + // Assign constant + isl_constraint_get_constant(c, &v); + + if (inverse) isl_int_neg(v,v); + + isl_int_set(vec->p[nb_in + nb_params + 1], v); + + openscop_matrix_insert_vector(m, vec, m->NbRows); + + return 0; +} + + +/// Add an isl basic map to a OpenScop matrix_list +/// +/// @param bmap The basic map to add +/// @param user The matrix list we should add the basic map to +/// +/// XXX: At the moment this function expects just a matrix, as support +/// for matrix lists is currently not available in OpenScop. So union of +/// polyhedron are not yet supported +int OpenScop::accessToMatrix_basic_map(isl_basic_map *bmap, void *user) { + isl_basic_map_foreach_constraint(bmap, &accessToMatrix_constraint, user); + return 0; +} + +/// Create the memory access matrix for openscop +/// +/// @param S The polly statement the access matrix is created for. +/// @param isRead Are we looking for read or write accesses? +/// @param ArrayMap A map translating from the memory references to the openscop +/// indeces +/// +/// @return The memory access matrix, as it is required by openscop. +openscop_matrix_p OpenScop::createAccessMatrix(ScopStmt *S, bool isRead) { + + unsigned NbColumns = S->getNumIterators() + S->getNumParams() + 2; + openscop_matrix_p m = openscop_matrix_malloc(0, NbColumns); + + for (ScopStmt::memacc_iterator MI = S->memacc_begin(), ME = S->memacc_end(); + MI != ME; ++MI) + if ((*MI)->isRead() == isRead) { + // Extract the access function. + isl_map_foreach_basic_map((*MI)->getAccessFunction(), + &accessToMatrix_basic_map, m); + + // Set the index of the memory access base element. + std::map::iterator BA = + ArrayMap.find((*MI)->getBaseAddr()); + isl_int_set_si(m->p[m->NbRows - 1][0], (*BA).second + 1); + } + + return m; +} + +OpenScop::~OpenScop() { + // Free array names. + for (int i = 0; i < openscop->nb_arrays; ++i) + delete[](openscop->arrays[i]); + + delete[](openscop->arrays); + openscop->arrays = NULL; + openscop->nb_arrays = 0; + + // Free scattering names. + for (int i = 0; i < openscop->nb_scattdims; ++i) + delete[](openscop->scattdims[i]); + + delete[](openscop->scattdims); + openscop->scattdims = NULL; + openscop->nb_scattdims = 0; + + // Free parameters + for (int i = 0; i < openscop->nb_parameters; ++i) + delete[](openscop->parameters[i]); + + delete[](openscop->parameters); + openscop->parameters = NULL; + openscop->nb_parameters = 0; + + openscop_statement_p stmt = openscop->statement; + + // Free Statements + while (stmt) { + openscop_statement_p TempStmt = stmt->next; + stmt->next = NULL; + freeStatement(stmt); + stmt = TempStmt; + } + + openscop->statement = NULL; + + openscop_scop_free(openscop); +} + +std::string ScopExporter::getFileName(Scop *S) const { + std::string FunctionName = + S->getRegion().getEntry()->getParent()->getName(); + std::string FileName = FunctionName + "___" + S->getNameStr() + ".scop"; + return FileName; +} + +void ScopExporter::printScop(raw_ostream &OS) const { + S->print(OS); +} + +bool ScopExporter::runOnScop(Scop &scop) { + S = &scop; + Region &R = S->getRegion(); + + std::string FileName = ExportDir + "/" + getFileName(S); + FILE *F = fopen(FileName.c_str(), "w"); + + if (!F) { + errs() << "Cannot open file: " << FileName << "\n"; + errs() << "Skipping export.\n"; + return false; + } + + OpenScop openscop(S); + openscop.print(F); + fclose(F); + + std::string FunctionName = R.getEntry()->getParent()->getName(); + errs() << "Writing Scop '" << R.getNameStr() << "' in function '" + << FunctionName << "' to '" << FileName << "'.\n"; + + return false; +} + +void ScopExporter::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); +} + +static RegisterPass A("polly-export", + "Polly - Export Scops with OpenScop library" + " (Writes a .scop file for each Scop)" + ); + +Pass *polly::createScopExporterPass() { + return new ScopExporter(); +} + +#endif + diff --git a/tools/polly/lib/Exchange/OpenScopImporter.cpp b/tools/polly/lib/Exchange/OpenScopImporter.cpp new file mode 100755 index 00000000000..db11a5608a9 --- /dev/null +++ b/tools/polly/lib/Exchange/OpenScopImporter.cpp @@ -0,0 +1,256 @@ +//===-- OpenScopImporter.cpp - Import Scops with openscop library --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Import modified .scop files into Polly. This allows to change the schedule of +// statements. +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" + +#include "polly/Dependences.h" +#include "polly/ScopInfo.h" +#include "polly/ScopPass.h" + +#include "llvm/Support/CommandLine.h" +#include "llvm/Assembly/Writer.h" + +#ifdef OPENSCOP_FOUND + +#define OPENSCOP_INT_T_IS_MP +#include "openscop/openscop.h" + +#include "isl/map.h" +#include "isl/set.h" +#include "isl/constraint.h" + +using namespace llvm; +using namespace polly; + +namespace { + static cl::opt + ImportDir("polly-import-dir", + cl::desc("The directory to import the .scop files from."), + cl::Hidden, cl::value_desc("Directory path"), cl::ValueRequired, + cl::init(".")); + static cl::opt + ImportPostfix("polly-import-postfix", + cl::desc("Postfix to append to the import .scop files."), + cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired, + cl::init("")); + + struct ScopImporter : public ScopPass { + static char ID; + Scop *S; + Dependences *D; + explicit ScopImporter() : ScopPass(ID) {} + bool updateScattering(Scop *S, openscop_scop_p OScop); + + std::string getFileName(Scop *S) const; + virtual bool runOnScop(Scop &S); + virtual void printScop(raw_ostream &OS) const; + void getAnalysisUsage(AnalysisUsage &AU) const; + }; +} + +char ScopImporter::ID = 0; + +/// @brief Create an isl constraint from a row of OpenScop integers. +/// +/// @param row An array of isl/OpenScop integers. +/// @param Space An isl space object, describing how to spilt the dimensions. +/// +/// @return An isl constraint representing this integer array. +isl_constraint *constraintFromMatrixRow(isl_int *row, isl_space *Space) { + isl_constraint *c; + + unsigned NbOut = isl_space_size(Space, isl_dim_out); + unsigned NbIn = isl_space_size(Space, isl_dim_in); + unsigned NbParam = isl_space_size(Space, isl_dim_param); + + if (isl_int_is_zero(row[0])) + c = isl_equality_alloc(isl_space_copy(Space)); + else + c = isl_inequality_alloc(isl_space_copy(Space)); + + unsigned current_column = 1; + + for (unsigned j = 0; j < NbOut; ++j) + isl_constraint_set_coefficient(c, isl_space_out, j, row[current_column++]); + + for (unsigned j = 0; j < NbIn; ++j) + isl_constraint_set_coefficient(c, isl_space_in, j, row[current_column++]); + + for (unsigned j = 0; j < NbParam; ++j) + isl_constraint_set_coefficient(c, isl_space_param, j, row[current_column++]); + + isl_constraint_set_constant(c, row[current_column]); + + return c; +} + +/// @brief Create an isl map from a OpenScop matrix. +/// +/// @param m The OpenScop matrix to translate. +/// @param Space The dimensions that are contained in the OpenScop matrix. +/// +/// @return An isl map representing m. +isl_map *mapFromMatrix(openscop_matrix_p m, isl_space *Space) { + isl_basic_map *bmap = isl_basic_map_universe(isl_space_copy(Space)); + + for (unsigned i = 0; i < m->NbRows; ++i) { + isl_constraint *c; + + c = constraintFromMatrixRow(m->p[i], Space); + bmap = isl_basic_map_add_constraint(bmap, c); + } + + return isl_map_from_basic_map(bmap); +} + +/// @brief Create a new scattering for PollyStmt. +/// +/// @param m The matrix describing the new scattering. +/// @param PollyStmt The statement to create the scattering for. +/// +/// @return An isl_map describing the scattering. +isl_map *scatteringForStmt(openscop_matrix_p m, ScopStmt *PollyStmt) { + + unsigned NbParam = PollyStmt->getNumParams(); + unsigned NbIterators = PollyStmt->getNumIterators(); + unsigned NbScattering = m->NbColumns - 2 - NbParam - NbIterators; + + isl_ctx *ctx = PollyStmt->getParent()->getCtx(); + isl_space *Space = isl_dim_alloc(ctx, NbParam, NbIterators, NbScattering); + Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering"); + Space = isl_space_set_tuple_name(Space, isl_dim_in, PollyStmt->getBaseName()); + isl_map *map = mapFromMatrix(m, Space); + isl_space_free(Space); + + return map; +} + +typedef Dependences::StatementToIslMapTy StatementToIslMapTy; + +/// @brief Read the new scattering from the OpenScop description. +/// +/// @S The Scop to update +/// @OScop The OpenScop data structure describing the new scattering. +/// @return A map that contains for each Statement the new scattering. +StatementToIslMapTy *readScattering(Scop *S, openscop_scop_p OScop) { + StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy()); + openscop_statement_p stmt = OScop->statement; + + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + + if ((*SI)->isFinalRead()) + continue; + + if (!stmt) { + errs() << "Not enough statements available in OpenScop file\n"; + delete &NewScattering; + return NULL; + } + + NewScattering[*SI] = scatteringForStmt(stmt->schedule, *SI); + stmt = stmt->next; + } + + if (stmt) { + errs() << "Too many statements in OpenScop file\n"; + delete &NewScattering; + return NULL; + } + + return &NewScattering; +} + +/// @brief Update the scattering in a Scop using the OpenScop description of +/// the scattering. +/// +/// @S The Scop to update +/// @OScop The OpenScop data structure describing the new scattering. +/// @return Returns false, if the update failed. +bool ScopImporter::updateScattering(Scop *S, openscop_scop_p OScop) { + StatementToIslMapTy *NewScattering = readScattering(S, OScop); + + if (!NewScattering) + return false; + + if (!D->isValidScattering(NewScattering)) { + errs() << "OpenScop file contains a scattering that changes the " + << "dependences. Use -disable-polly-legality to continue anyways\n"; + return false; + } + + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (NewScattering->find(Stmt) != NewScattering->end()) + Stmt->setScattering((*NewScattering)[Stmt]); + } + + return true; +} +std::string ScopImporter::getFileName(Scop *S) const { + std::string FunctionName = + S->getRegion().getEntry()->getParent()->getName(); + std::string FileName = FunctionName + "___" + S->getNameStr() + ".scop"; + return FileName; +} + +void ScopImporter::printScop(raw_ostream &OS) const { + S->print(OS); +} + +bool ScopImporter::runOnScop(Scop &scop) { + S = &scop; + Region &R = scop.getRegion(); + D = &getAnalysis(); + + std::string FileName = ImportDir + "/" + getFileName(S) + ImportPostfix; + FILE *F = fopen(FileName.c_str(), "r"); + + if (!F) { + errs() << "Cannot open file: " << FileName << "\n"; + errs() << "Skipping import.\n"; + return false; + } + + openscop_scop_p openscop = openscop_scop_read(F); + fclose(F); + + std::string FunctionName = R.getEntry()->getParent()->getName(); + errs() << "Reading Scop '" << R.getNameStr() << "' in function '" + << FunctionName << "' from '" << FileName << "'.\n"; + + bool UpdateSuccessfull = updateScattering(S, openscop); + + if (!UpdateSuccessfull) { + errs() << "Update failed" << "\n"; + } + + return false; +} + +void ScopImporter::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); +} + +static RegisterPass A("polly-import", + "Polly - Import Scops with OpenScop library" + " (Reads a .scop file for each Scop)" + ); + +Pass *polly::createScopImporterPass() { + return new ScopImporter(); +} + +#endif diff --git a/tools/polly/lib/Exchange/ScopLib.cpp b/tools/polly/lib/Exchange/ScopLib.cpp new file mode 100644 index 00000000000..dc183cf0655 --- /dev/null +++ b/tools/polly/lib/Exchange/ScopLib.cpp @@ -0,0 +1,764 @@ +//===- ScopLib.cpp - ScopLib interface ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// ScopLib Interface +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" + +#ifdef SCOPLIB_FOUND + +#include "polly/Dependences.h" +#include "polly/ScopLib.h" +#include "polly/ScopInfo.h" + +#include "llvm/Support/CommandLine.h" +#include "llvm/Assembly/Writer.h" + +#include "stdio.h" +#include "isl/set.h" +#include "isl/map.h" +#include "isl/constraint.h" + +using namespace llvm; + +namespace polly { + +ScopLib::ScopLib(Scop *S) : PollyScop(S) { + scoplib = scoplib_scop_malloc(); + + initializeArrays(); + initializeParameters(); + initializeScattering(); + initializeStatements(); +} + +ScopLib::ScopLib(Scop *S, FILE *F, Dependences *dep) : PollyScop(S), D(dep) { + scoplib = scoplib_scop_read(F); +} + +void ScopLib::initializeParameters() { + scoplib->nb_parameters = PollyScop->getNumParams(); + scoplib->parameters = (char**) malloc(sizeof(char*) * scoplib->nb_parameters); + + for (int i = 0; i < scoplib->nb_parameters; ++i) { + scoplib->parameters[i] = (char *) malloc(sizeof(char*) * 20); + sprintf(scoplib->parameters[i], "p_%d", i); + } +} + +void ScopLib::initializeArrays() { + int nb_arrays = 0; + + for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE; + ++SI) + for (ScopStmt::memacc_iterator MI = (*SI)->memacc_begin(), + ME = (*SI)->memacc_end(); MI != ME; ++MI) { + const Value *BaseAddr = (*MI)->getBaseAddr(); + if (ArrayMap.find(BaseAddr) == ArrayMap.end()) { + ArrayMap.insert(std::make_pair(BaseAddr, nb_arrays)); + ++nb_arrays; + } + } + + scoplib->nb_arrays = nb_arrays; + scoplib->arrays = (char**)malloc(sizeof(char*) * nb_arrays); + + for (int i = 0; i < nb_arrays; ++i) + for (std::map::iterator VI = ArrayMap.begin(), + VE = ArrayMap.end(); VI != VE; ++VI) + if ((*VI).second == i) { + const Value *V = (*VI).first; + std::string name = V->getName(); + scoplib->arrays[i] = (char*) malloc(sizeof(char*) * (name.size() + 1)); + strcpy(scoplib->arrays[i], name.c_str()); + } +} + +void ScopLib::initializeScattering() { +} + +scoplib_statement_p ScopLib::initializeStatement(ScopStmt *stmt) { + scoplib_statement_p Stmt = scoplib_statement_malloc(); + + // Domain & Schedule + Stmt->domain = scoplib_matrix_list_malloc(); + Stmt->domain->elt = domainToMatrix(stmt->getDomain()); + Stmt->schedule = scatteringToMatrix(stmt->getScattering()); + + // Statement name + std::string entryName; + raw_string_ostream OS(entryName); + WriteAsOperand(OS, stmt->getBasicBlock(), false); + entryName = OS.str(); + Stmt->body = (char*)malloc(sizeof(char) * (entryName.size() + 1)); + strcpy(Stmt->body, entryName.c_str()); + + // Iterator names + Stmt->nb_iterators = stmt->getNumIterators(); + Stmt->iterators = (char**) malloc(sizeof(char*) * Stmt->nb_iterators); + + for (int i = 0; i < Stmt->nb_iterators; ++i) { + Stmt->iterators[i] = (char*) malloc(sizeof(char*) * 20); + sprintf(Stmt->iterators[i], "i_%d", i); + } + + // Memory Accesses + Stmt->read = createAccessMatrix(stmt, true); + Stmt->write = createAccessMatrix(stmt, false); + + return Stmt; +} + +void ScopLib::initializeStatements() { + for (Scop::reverse_iterator SI = PollyScop->rbegin(), SE = PollyScop->rend(); + SI != SE; ++SI) { + + if ((*SI)->isFinalRead()) + continue; + + scoplib_statement_p stmt = initializeStatement(*SI); + stmt->next = scoplib->statement; + scoplib->statement = stmt; + } +} + +void ScopLib::freeStatement(scoplib_statement_p stmt) { + + if (stmt->read) + scoplib_matrix_free(stmt->read); + stmt->read = NULL; + + if (stmt->write) + scoplib_matrix_free(stmt->write); + stmt->write = NULL; + + scoplib_matrix_list_p current = stmt->domain; + while (current) { + scoplib_matrix_list_p next = current->next; + current->next = NULL; + scoplib_matrix_free(current->elt); + current->elt = NULL; + scoplib_matrix_list_free(current); + current = next; + } + stmt->domain = NULL; + + if (stmt->schedule) + scoplib_matrix_free(stmt->schedule); + stmt->schedule = NULL; + + for (int i = 0; i < stmt->nb_iterators; ++i) + free(stmt->iterators[i]); + + free(stmt->iterators); + stmt->iterators = NULL; + stmt->nb_iterators = 0; + + scoplib_statement_free(stmt); +} + +void ScopLib::print(FILE *F) { + scoplib_scop_print_dot_scop(F, scoplib); +} + +/// Add an isl constraint to an ScopLib matrix. +/// +/// @param user The matrix +/// @param c The constraint +int ScopLib::domainToMatrix_constraint(isl_constraint *c, void *user) { + scoplib_matrix_p m = (scoplib_matrix_p) user; + + int nb_params = isl_constraint_dim(c, isl_dim_param); + int nb_vars = isl_constraint_dim(c, isl_dim_set); + int nb_div = isl_constraint_dim(c, isl_dim_div); + + assert(!nb_div && "Existentially quantified variables not yet supported"); + + scoplib_vector_p vec = scoplib_vector_malloc(nb_params + nb_vars + 2); + + + // Assign type + if (isl_constraint_is_equality(c)) + scoplib_vector_tag_equality(vec); + else + scoplib_vector_tag_inequality(vec); + + isl_int v; + isl_int_init(v); + + // Assign variables + for (int i = 0; i < nb_vars; ++i) { + isl_constraint_get_coefficient(c, isl_dim_set, i, &v); + isl_int_set(vec->p[i + 1], v); + } + + // Assign parameters + for (int i = 0; i < nb_params; ++i) { + isl_constraint_get_coefficient(c, isl_dim_param, i, &v); + isl_int_set(vec->p[nb_vars + i + 1], v); + } + + // Assign constant + isl_constraint_get_constant(c, &v); + isl_int_set(vec->p[nb_params + nb_vars + 1], v); + + scoplib_matrix_insert_vector(m, vec, m->NbRows); + + scoplib_vector_free(vec); + isl_constraint_free(c); + isl_int_clear(v); + + return 0; +} + +/// Add an isl basic set to a ScopLib matrix_list +/// +/// @param bset The basic set to add +/// @param user The matrix list we should add the basic set to +/// +/// XXX: At the moment this function expects just a matrix, as support +/// for matrix lists is currently not available in ScopLib. So union of +/// polyhedron are not yet supported +int ScopLib::domainToMatrix_basic_set(isl_basic_set *bset, void *user) { + scoplib_matrix_p m = (scoplib_matrix_p) user; + assert(!m->NbRows && "Union of polyhedron not yet supported"); + + isl_basic_set_foreach_constraint(bset, &domainToMatrix_constraint, user); + isl_basic_set_free(bset); + return 0; +} + +/// Translate a isl_set to a ScopLib matrix. +/// +/// @param PS The set to be translated +/// @return A ScopLib Matrix +scoplib_matrix_p ScopLib::domainToMatrix(__isl_take isl_set *set) { + set = isl_set_compute_divs (set); + set = isl_set_align_divs (set); + + // Initialize the matrix. + unsigned NbRows, NbColumns; + NbRows = 0; + NbColumns = isl_set_n_dim(set) + isl_set_n_param(set) + 2; + scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns); + + // Copy the content into the matrix. + isl_set_foreach_basic_set(set, &domainToMatrix_basic_set, matrix); + + isl_set_free(set); + + return matrix; +} + +/// Add an isl constraint to an ScopLib matrix. +/// +/// @param user The matrix +/// @param c The constraint +int ScopLib::scatteringToMatrix_constraint(isl_constraint *c, void *user) { + scoplib_matrix_p m = (scoplib_matrix_p) user; + + int nb_params = isl_constraint_dim(c, isl_dim_param); + int nb_in = isl_constraint_dim(c, isl_dim_in); + int nb_div = isl_constraint_dim(c, isl_dim_div); + + assert(!nb_div && "Existentially quantified variables not yet supported"); + + scoplib_vector_p vec = + scoplib_vector_malloc(nb_params + nb_in + 2); + + // Assign type + if (isl_constraint_is_equality(c)) + scoplib_vector_tag_equality(vec); + else + scoplib_vector_tag_inequality(vec); + + isl_int v; + isl_int_init(v); + + // Assign variables + for (int i = 0; i < nb_in; ++i) { + isl_constraint_get_coefficient(c, isl_dim_in, i, &v); + isl_int_set(vec->p[i + 1], v); + } + + // Assign parameters + for (int i = 0; i < nb_params; ++i) { + isl_constraint_get_coefficient(c, isl_dim_param, i, &v); + isl_int_set(vec->p[nb_in + i + 1], v); + } + + // Assign constant + isl_constraint_get_constant(c, &v); + isl_int_set(vec->p[nb_in + nb_params + 1], v); + + scoplib_vector_p null = + scoplib_vector_malloc(nb_params + nb_in + 2); + + vec = scoplib_vector_sub(null, vec); + scoplib_matrix_insert_vector(m, vec, 0); + + isl_constraint_free(c); + isl_int_clear(v); + + return 0; +} + +/// Add an isl basic map to a ScopLib matrix_list +/// +/// @param bmap The basic map to add +/// @param user The matrix list we should add the basic map to +/// +/// XXX: At the moment this function expects just a matrix, as support +/// for matrix lists is currently not available in ScopLib. So union of +/// polyhedron are not yet supported +int ScopLib::scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user) { + scoplib_matrix_p m = (scoplib_matrix_p) user; + assert(!m->NbRows && "Union of polyhedron not yet supported"); + + isl_basic_map_foreach_constraint(bmap, &scatteringToMatrix_constraint, user); + isl_basic_map_free(bmap); + return 0; +} + +/// Translate a isl_map to a ScopLib matrix. +/// +/// @param map The map to be translated +/// @return A ScopLib Matrix +scoplib_matrix_p ScopLib::scatteringToMatrix(__isl_take isl_map *map) { + map = isl_map_compute_divs (map); + map = isl_map_align_divs (map); + + // Initialize the matrix. + unsigned NbRows, NbColumns; + NbRows = 0; + NbColumns = isl_map_n_in(map) + isl_map_n_param(map) + 2; + scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns); + + // Copy the content into the matrix. + isl_map_foreach_basic_map(map, &scatteringToMatrix_basic_map, matrix); + + // Only keep the relevant rows. + scoplib_matrix_p reduced = scoplib_matrix_ncopy(matrix, + isl_map_n_in(map) * 2 + 1); + + scoplib_matrix_free (matrix); + isl_map_free(map); + + return reduced; +} + +/// Add an isl constraint to an ScopLib matrix. +/// +/// @param user The matrix +/// @param c The constraint +int ScopLib::accessToMatrix_constraint(isl_constraint *c, void *user) { + scoplib_matrix_p m = (scoplib_matrix_p) user; + + int nb_params = isl_constraint_dim(c, isl_dim_param); + int nb_in = isl_constraint_dim(c, isl_dim_in); + int nb_div = isl_constraint_dim(c, isl_dim_div); + + assert(!nb_div && "Existentially quantified variables not yet supported"); + + scoplib_vector_p vec = + scoplib_vector_malloc(nb_params + nb_in + 2); + + isl_int v; + isl_int_init(v); + + // The access dimension has to be one. + isl_constraint_get_coefficient(c, isl_dim_out, 0, &v); + assert(isl_int_is_one(v)); + bool inverse = true ; + + // Assign variables + for (int i = 0; i < nb_in; ++i) { + isl_constraint_get_coefficient(c, isl_dim_in, i, &v); + + if (inverse) isl_int_neg(v,v); + + isl_int_set(vec->p[i + 1], v); + } + + // Assign parameters + for (int i = 0; i < nb_params; ++i) { + isl_constraint_get_coefficient(c, isl_dim_param, i, &v); + + if (inverse) isl_int_neg(v,v); + + isl_int_set(vec->p[nb_in + i + 1], v); + } + + // Assign constant + isl_constraint_get_constant(c, &v); + + if (inverse) isl_int_neg(v,v); + + isl_int_set(vec->p[nb_in + nb_params + 1], v); + + scoplib_matrix_insert_vector(m, vec, m->NbRows); + + isl_constraint_free(c); + isl_int_clear(v); + + return 0; +} + + +/// Add an isl basic map to a ScopLib matrix_list +/// +/// @param bmap The basic map to add +/// @param user The matrix list we should add the basic map to +/// +/// XXX: At the moment this function expects just a matrix, as support +/// for matrix lists is currently not available in ScopLib. So union of +/// polyhedron are not yet supported +int ScopLib::accessToMatrix_basic_map(isl_basic_map *bmap, void *user) { + isl_basic_map_foreach_constraint(bmap, &accessToMatrix_constraint, user); + isl_basic_map_free(bmap); + return 0; +} + +/// Create the memory access matrix for scoplib +/// +/// @param S The polly statement the access matrix is created for. +/// @param isRead Are we looking for read or write accesses? +/// @param ArrayMap A map translating from the memory references to the scoplib +/// indeces +/// +/// @return The memory access matrix, as it is required by scoplib. +scoplib_matrix_p ScopLib::createAccessMatrix(ScopStmt *S, bool isRead) { + + unsigned NbColumns = S->getNumIterators() + S->getNumParams() + 2; + scoplib_matrix_p m = scoplib_matrix_malloc(0, NbColumns); + + for (ScopStmt::memacc_iterator MI = S->memacc_begin(), ME = S->memacc_end(); + MI != ME; ++MI) + if ((*MI)->isRead() == isRead) { + // Extract the access function. + isl_map *AccessRelation = (*MI)->getAccessRelation(); + isl_map_foreach_basic_map(AccessRelation, + &accessToMatrix_basic_map, m); + isl_map_free(AccessRelation); + + // Set the index of the memory access base element. + std::map::iterator BA = + ArrayMap.find((*MI)->getBaseAddr()); + isl_int_set_si(m->p[m->NbRows - 1][0], (*BA).second + 1); + } + + return m; +} + +ScopLib::~ScopLib() { + if (!scoplib) + return; + + // Free array names. + for (int i = 0; i < scoplib->nb_arrays; ++i) + free(scoplib->arrays[i]); + + free(scoplib->arrays); + scoplib->arrays = NULL; + scoplib->nb_arrays = 0; + + // Free parameters + for (int i = 0; i < scoplib->nb_parameters; ++i) + free(scoplib->parameters[i]); + + free(scoplib->parameters); + scoplib->parameters = NULL; + scoplib->nb_parameters = 0; + + scoplib_statement_p stmt = scoplib->statement; + + // Free Statements + while (stmt) { + scoplib_statement_p TempStmt = stmt->next; + stmt->next = NULL; + freeStatement(stmt); + stmt = TempStmt; + } + + scoplib->statement = NULL; + + scoplib_scop_free(scoplib); +} +/// @brief Create an isl constraint from a row of OpenScop integers. +/// +/// @param row An array of isl/OpenScop integers. +/// @param Space An isl space object, describing how to spilt the dimensions. +/// +/// @return An isl constraint representing this integer array. +isl_constraint *constraintFromMatrixRow(isl_int *row, + __isl_take isl_space *Space) { + isl_constraint *c; + + unsigned NbIn = isl_space_dim(Space, isl_dim_in); + unsigned NbParam = isl_space_dim(Space, isl_dim_param); + + if (isl_int_is_zero(row[0])) + c = isl_equality_alloc(isl_local_space_from_space(Space)); + else + c = isl_inequality_alloc(isl_local_space_from_space(Space)); + + unsigned current_column = 1; + + for (unsigned j = 0; j < NbIn; ++j) + isl_constraint_set_coefficient(c, isl_dim_in, j, row[current_column++]); + + for (unsigned j = 0; j < NbParam; ++j) + isl_constraint_set_coefficient(c, isl_dim_param, j, row[current_column++]); + + isl_constraint_set_constant(c, row[current_column]); + + return c; +} + +/// @brief Create an isl map from a OpenScop matrix. +/// +/// @param m The OpenScop matrix to translate. +/// @param Space The dimensions that are contained in the OpenScop matrix. +/// +/// @return An isl map representing m. +isl_map *mapFromMatrix(scoplib_matrix_p m, __isl_take isl_space *Space, + unsigned scatteringDims) { + isl_basic_map *bmap = isl_basic_map_universe(isl_space_copy(Space)); + + for (unsigned i = 0; i < m->NbRows; ++i) { + isl_constraint *c; + + c = constraintFromMatrixRow(m->p[i], isl_space_copy(Space)); + + mpz_t minusOne; + mpz_init(minusOne); + mpz_set_si(minusOne, -1); + isl_constraint_set_coefficient(c, isl_dim_out, i, minusOne); + + bmap = isl_basic_map_add_constraint(bmap, c); + } + + for (unsigned i = m->NbRows; i < scatteringDims; i++) { + isl_constraint *c; + + c = isl_equality_alloc(isl_local_space_from_space(isl_space_copy(Space))); + + mpz_t One; + mpz_init(One); + mpz_set_si(One, 1); + isl_constraint_set_coefficient(c, isl_dim_out, i, One); + + bmap = isl_basic_map_add_constraint(bmap, c); + } + + isl_space_free(Space); + + return isl_map_from_basic_map(bmap); +} +/// @brief Create an isl constraint from a row of OpenScop integers. +/// +/// @param row An array of isl/OpenScop integers. +/// @param Space An isl space object, describing how to spilt the dimensions. +/// +/// @return An isl constraint representing this integer array. +isl_constraint *constraintFromMatrixRowFull(isl_int *row, + __isl_take isl_space *Space) { + isl_constraint *c; + + unsigned NbOut = isl_space_dim(Space, isl_dim_out); + unsigned NbIn = isl_space_dim(Space, isl_dim_in); + unsigned NbParam = isl_space_dim(Space, isl_dim_param); + + isl_local_space *LSpace = isl_local_space_from_space(Space); + + if (isl_int_is_zero(row[0])) + c = isl_equality_alloc(LSpace); + else + c = isl_inequality_alloc(LSpace); + + unsigned current_column = 1; + + for (unsigned j = 0; j < NbOut; ++j) + isl_constraint_set_coefficient(c, isl_dim_out, j, row[current_column++]); + + for (unsigned j = 0; j < NbIn; ++j) + isl_constraint_set_coefficient(c, isl_dim_in, j, row[current_column++]); + + for (unsigned j = 0; j < NbParam; ++j) + isl_constraint_set_coefficient(c, isl_dim_param, j, row[current_column++]); + + isl_constraint_set_constant(c, row[current_column]); + + return c; +} + +/// @brief Create an isl map from a OpenScop matrix. +/// +/// @param m The OpenScop matrix to translate. +/// @param Space The dimensions that are contained in the OpenScop matrix. +/// +/// @return An isl map representing m. +isl_map *mapFromMatrix(scoplib_matrix_p m, __isl_take isl_space *Space) { + isl_basic_map *bmap = isl_basic_map_universe(isl_space_copy(Space)); + + for (unsigned i = 0; i < m->NbRows; ++i) { + isl_constraint *c; + + c = constraintFromMatrixRowFull(m->p[i], isl_space_copy(Space)); + bmap = isl_basic_map_add_constraint(bmap, c); + } + + isl_space_free(Space); + + return isl_map_from_basic_map(bmap); +} + +/// @brief Create a new scattering for PollyStmt. +/// +/// @param m The matrix describing the new scattering. +/// @param PollyStmt The statement to create the scattering for. +/// +/// @return An isl_map describing the scattering. +isl_map *scatteringForStmt(scoplib_matrix_p m, ScopStmt *PollyStmt, + int scatteringDims) { + + unsigned NbParam = PollyStmt->getNumParams(); + unsigned NbIterators = PollyStmt->getNumIterators(); + unsigned NbScattering; + + if (scatteringDims == -1) + NbScattering = m->NbColumns - 2 - NbParam - NbIterators; + else + NbScattering = scatteringDims; + + isl_ctx *ctx = PollyStmt->getParent()->getIslCtx(); + isl_space *Space = isl_dim_alloc(ctx, NbParam, NbIterators, NbScattering); + + isl_space *ParamSpace = PollyStmt->getParent()->getParamSpace(); + + // We need to copy the isl_ids for the parameter dimensions to the new + // map. Without doing this the current map would have different + // ids then the new one, even though both are named identically. + for (unsigned i = 0; i < isl_space_dim(Space, isl_dim_param); + i++) { + isl_id *id = isl_space_get_dim_id(ParamSpace, isl_dim_param, i); + Space = isl_space_set_dim_id(Space, isl_dim_param, i, id); + } + + isl_space_free(ParamSpace); + + Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering"); + Space = isl_space_set_tuple_name(Space, isl_dim_in, PollyStmt->getBaseName()); + + if (scatteringDims == -1) + return mapFromMatrix(m, Space); + + return mapFromMatrix(m, Space, scatteringDims); +} + +unsigned maxScattering(scoplib_statement_p stmt) { + unsigned max = 0; + + while (stmt) { + max = std::max(max, stmt->schedule->NbRows); + stmt = stmt->next; + } + + return max; +} + +typedef Dependences::StatementToIslMapTy StatementToIslMapTy; + +void freeStmtToIslMap(StatementToIslMapTy *Map) { + for (StatementToIslMapTy::iterator MI = Map->begin(), ME = Map->end(); + MI != ME; ++MI) + isl_map_free(MI->second); + + delete (Map); +} + +/// @brief Read the new scattering from the scoplib description. +/// +/// @S The Scop to update +/// @OScop The ScopLib data structure describing the new scattering. +/// @return A map that contains for each Statement the new scattering. +StatementToIslMapTy *readScattering(Scop *S, scoplib_scop_p OScop) { + StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy()); + + scoplib_statement_p stmt = OScop->statement; + + // Check if we have dimensions for each scattering or if each row + // represents a scattering dimension. + int numScatteringDims = -1; + ScopStmt *pollyStmt = *S->begin(); + + if (stmt->schedule->NbColumns + == 2 + pollyStmt->getNumParams() + pollyStmt->getNumIterators()) { + numScatteringDims = maxScattering(stmt); + } + + for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) { + + if ((*SI)->isFinalRead()) + continue; + + if (!stmt) { + errs() << "Not enough statements available in OpenScop file\n"; + freeStmtToIslMap(&NewScattering); + return NULL; + } + + NewScattering[*SI] = scatteringForStmt(stmt->schedule, *SI, + numScatteringDims); + stmt = stmt->next; + } + + if (stmt) { + errs() << "Too many statements in OpenScop file\n"; + freeStmtToIslMap(&NewScattering); + return NULL; + } + + return &NewScattering; +} + +/// @brief Update the scattering in a Scop using the scoplib description of +/// the scattering. +bool ScopLib::updateScattering() { + if (!scoplib) + return false; + + StatementToIslMapTy *NewScattering = readScattering(PollyScop, scoplib); + + if (!NewScattering) + return false; + + if (!D->isValidScattering(NewScattering)) { + freeStmtToIslMap(NewScattering); + errs() << "OpenScop file contains a scattering that changes the " + << "dependences. Use -disable-polly-legality to continue anyways\n"; + return false; + } + + for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE; + ++SI) { + ScopStmt *Stmt = *SI; + + if (NewScattering->find(Stmt) != NewScattering->end()) + Stmt->setScattering(isl_map_copy((*NewScattering)[Stmt])); + } + + freeStmtToIslMap(NewScattering); + return true; +} +} + +#endif diff --git a/tools/polly/lib/Exchange/ScopLibExporter.cpp b/tools/polly/lib/Exchange/ScopLibExporter.cpp new file mode 100755 index 00000000000..583240d51cb --- /dev/null +++ b/tools/polly/lib/Exchange/ScopLibExporter.cpp @@ -0,0 +1,99 @@ +//===-- ScopLibExporter.cpp - Export Scops with scoplib ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Export the Scops build by ScopInfo pass to text file. +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" + +#ifdef SCOPLIB_FOUND + +#include "polly/ScopInfo.h" +#include "polly/ScopPass.h" +#include "polly/ScopLib.h" + +#include "llvm/Support/CommandLine.h" +#include "llvm/Assembly/Writer.h" + +#include "stdio.h" +#include "isl/set.h" +#include "isl/constraint.h" + +using namespace llvm; +using namespace polly; + +namespace { + static cl::opt + ExportDir("polly-export-scoplib-dir", + cl::desc("The directory to export the .scoplib files to."), + cl::Hidden, cl::value_desc("Directory path"), cl::ValueRequired, + cl::init(".")); + + class ScopLibExporter : public ScopPass { + Scop *S; + + std::string getFileName(Scop *S) const; + public: + static char ID; + explicit ScopLibExporter() : ScopPass(ID) {} + + virtual bool runOnScop(Scop &scop); + void getAnalysisUsage(AnalysisUsage &AU) const; + }; + +} + +char ScopLibExporter::ID = 0; + +std::string ScopLibExporter::getFileName(Scop *S) const { + std::string FunctionName = + S->getRegion().getEntry()->getParent()->getName(); + std::string FileName = FunctionName + "___" + S->getNameStr() + ".scoplib"; + return FileName; +} + +bool ScopLibExporter::runOnScop(Scop &scop) { + S = &scop; + Region *R = &S->getRegion(); + + std::string FileName = ExportDir + "/" + getFileName(S); + FILE *F = fopen(FileName.c_str(), "w"); + + if (!F) { + errs() << "Cannot open file: " << FileName << "\n"; + errs() << "Skipping export.\n"; + return false; + } + + ScopLib scoplib(S); + scoplib.print(F); + fclose(F); + + std::string FunctionName = R->getEntry()->getParent()->getName(); + errs() << "Writing Scop '" << R->getNameStr() << "' in function '" + << FunctionName << "' to '" << FileName << "'.\n"; + + return false; +} + +void ScopLibExporter::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); +} + +static RegisterPass A("polly-export-scoplib", + "Polly - Export Scops with ScopLib library" + " (Writes a .scoplib file for each Scop)" + ); + +Pass *polly::createScopLibExporterPass() { + return new ScopLibExporter(); +} + +#endif diff --git a/tools/polly/lib/Exchange/ScopLibImporter.cpp b/tools/polly/lib/Exchange/ScopLibImporter.cpp new file mode 100755 index 00000000000..bf90857f893 --- /dev/null +++ b/tools/polly/lib/Exchange/ScopLibImporter.cpp @@ -0,0 +1,120 @@ +//===-- ScopLibImporter.cpp - Import Scops with scoplib. -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Import modified .scop files into Polly. This allows to change the schedule of +// statements. +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" + +#ifdef SCOPLIB_FOUND + +#include "polly/ScopInfo.h" +#include "polly/ScopLib.h" +#include "polly/Dependences.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Assembly/Writer.h" + +#define SCOPLIB_INT_T_IS_MP +#include "scoplib/scop.h" + +#include "isl/set.h" +#include "isl/constraint.h" + +using namespace llvm; +using namespace polly; + +namespace { + static cl::opt + ImportDir("polly-import-scoplib-dir", + cl::desc("The directory to import the .scoplib files from."), + cl::Hidden, cl::value_desc("Directory path"), cl::ValueRequired, + cl::init(".")); + static cl::opt + ImportPostfix("polly-import-scoplib-postfix", + cl::desc("Postfix to append to the import .scoplib files."), + cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired, + cl::init("")); + + struct ScopLibImporter : public RegionPass { + static char ID; + Scop *S; + Dependences *D; + explicit ScopLibImporter() : RegionPass(ID) {} + + bool updateScattering(Scop *S, scoplib_scop_p OScop); + std::string getFileName(Scop *S) const; + virtual bool runOnRegion(Region *R, RGPassManager &RGM); + virtual void print(raw_ostream &OS, const Module *) const; + void getAnalysisUsage(AnalysisUsage &AU) const; + }; +} + +char ScopLibImporter::ID = 0; + +namespace { +std::string ScopLibImporter::getFileName(Scop *S) const { + std::string FunctionName = + S->getRegion().getEntry()->getParent()->getName(); + std::string FileName = FunctionName + "___" + S->getNameStr() + ".scoplib"; + return FileName; +} + +void ScopLibImporter::print(raw_ostream &OS, const Module *) const {} + +bool ScopLibImporter::runOnRegion(Region *R, RGPassManager &RGM) { + S = getAnalysis().getScop(); + D = &getAnalysis(); + + if (!S) + return false; + + std::string FileName = ImportDir + "/" + getFileName(S) + ImportPostfix; + FILE *F = fopen(FileName.c_str(), "r"); + + if (!F) { + errs() << "Cannot open file: " << FileName << "\n"; + errs() << "Skipping import.\n"; + return false; + } + + std::string FunctionName = R->getEntry()->getParent()->getName(); + errs() << "Reading Scop '" << R->getNameStr() << "' in function '" + << FunctionName << "' from '" << FileName << "'.\n"; + + ScopLib scoplib(S, F, D); + bool UpdateSuccessfull = scoplib.updateScattering(); + fclose(F); + + if (!UpdateSuccessfull) { + errs() << "Update failed" << "\n"; + } + + return false; +} + +void ScopLibImporter::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired(); + AU.addRequired(); +} + +} + +static RegisterPass A("polly-import-scoplib", + "Polly - Import Scops with ScopLib library" + " (Reads a .scoplib file for each Scop)" + ); + +Pass *polly::createScopLibImporterPass() { + return new ScopLibImporter(); +} + +#endif diff --git a/tools/polly/lib/IndependentBlocks.cpp b/tools/polly/lib/IndependentBlocks.cpp new file mode 100644 index 00000000000..7ab01abc02c --- /dev/null +++ b/tools/polly/lib/IndependentBlocks.cpp @@ -0,0 +1,556 @@ +//===------ IndependentBlocks.cpp - Create Independent Blocks in Regions --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Create independent blocks in the regions detected by ScopDetection. +// +//===----------------------------------------------------------------------===// +// +#include "polly/LinkAllPasses.h" +#include "polly/ScopDetection.h" +#include "polly/Support/ScopHelper.h" +#include "polly/Cloog.h" + +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/RegionInfo.h" +#include "llvm/Analysis/RegionPass.h" +#include "llvm/Analysis/RegionIterator.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ValueTracking.h" +#include "llvm/Transforms/Utils/Local.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Assembly/Writer.h" + +#define DEBUG_TYPE "polly-independent" +#include "llvm/Support/Debug.h" + +#include + +using namespace polly; +using namespace llvm; + +namespace { +struct IndependentBlocks : public FunctionPass { + RegionInfo *RI; + ScalarEvolution *SE; + ScopDetection *SD; + LoopInfo *LI; + + BasicBlock *AllocaBlock; + + static char ID; + + IndependentBlocks() : FunctionPass(ID) {} + + // Create new code for every instruction operator that can be expressed by a + // SCEV. Like this there are just two types of instructions left: + // + // 1. Instructions that only reference loop ivs or parameters outside the + // region. + // + // 2. Instructions that are not used for any memory modification. (These + // will be ignored later on.) + // + // Blocks containing only these kind of instructions are called independent + // blocks as they can be scheduled arbitrarily. + bool createIndependentBlocks(BasicBlock *BB, const Region *R); + bool createIndependentBlocks(const Region *R); + + // Elimination on the Scop to eliminate the scalar dependences come with + // trivially dead instructions. + bool eliminateDeadCode(const Region *R); + + //===--------------------------------------------------------------------===// + /// Non trivial scalar dependences checking functions. + /// Non trivial scalar dependences occur when the def and use are located in + /// different BBs and we can not move them into the same one. This will + /// prevent use from schedule BBs arbitrarily. + /// + /// @brief This function checks if a scalar value that is part of the + /// Scop is used outside of the Scop. + /// + /// @param Use The use of the instruction. + /// @param R The maximum region in the Scop. + /// + /// @return Return true if the Use of an instruction and the instruction + /// itself form a non trivial scalar dependence. + static bool isEscapeUse(const Value *Use, const Region *R); + + /// @brief This function just checks if a Value is either defined in the same + /// basic block or outside the region, such that there are no scalar + /// dependences between basic blocks that are both part of the same + /// region. + /// + /// @param Operand The operand of the instruction. + /// @param CurBB The BasicBlock that contains the instruction. + /// @param R The maximum region in the Scop. + /// + /// @return Return true if the Operand of an instruction and the instruction + /// itself form a non trivial scalar (true) dependence. + bool isEscapeOperand(const Value *Operand, const BasicBlock *CurBB, + const Region *R) const; + + //===--------------------------------------------------------------------===// + /// Operand tree moving functions. + /// Trivial scalar dependences can eliminate by move the def to the same BB + /// that containing use. + /// + /// @brief Check if the instruction can be moved to another place safely. + /// + /// @param Inst The instruction. + /// + /// @return Return true if the instruction can be moved safely, false + /// otherwise. + static bool isSafeToMove(Instruction *Inst); + + typedef std::map ReplacedMapType; + + /// @brief Move all safe to move instructions in the Operand Tree (DAG) to + /// eliminate trivial scalar dependences. + /// + /// @param Inst The root of the operand Tree. + /// @param R The maximum region in the Scop. + /// @param ReplacedMap The map that mapping original instruction to the moved + /// instruction. + /// @param InsertPos The insert position of the moved instructions. + void moveOperandTree(Instruction *Inst, const Region *R, + ReplacedMapType &ReplacedMap, + Instruction *InsertPos); + + bool isIndependentBlock(const Region *R, BasicBlock *BB) const; + bool areAllBlocksIndependent(const Region *R) const; + + // Split the exit block to hold load instructions. + bool splitExitBlock(Region *R); + + bool translateScalarToArray(BasicBlock *BB, const Region *R); + bool translateScalarToArray(Instruction *Inst, const Region *R); + bool translateScalarToArray(const Region *R); + + bool runOnFunction(Function &F); + void verifyAnalysis() const; + void verifyScop(const Region *R) const; + void getAnalysisUsage(AnalysisUsage &AU) const; +}; +} + +bool IndependentBlocks::isSafeToMove(Instruction *Inst) { + if (Inst->mayReadFromMemory() || + Inst->mayWriteToMemory()) + return false; + + return isSafeToSpeculativelyExecute(Inst); +} + +void IndependentBlocks::moveOperandTree(Instruction *Inst, const Region *R, + ReplacedMapType &ReplacedMap, + Instruction *InsertPos) { + BasicBlock *CurBB = Inst->getParent(); + + // Depth first traverse the operand tree (or operand dag, because we will + // stop at PHINodes, so there are no cycle). + typedef Instruction::op_iterator ChildIt; + std::vector > WorkStack; + + WorkStack.push_back(std::make_pair(Inst, Inst->op_begin())); + + while (!WorkStack.empty()) { + Instruction *CurInst = WorkStack.back().first; + ChildIt It = WorkStack.back().second; + DEBUG(dbgs() << "Checking Operand of Node:\n" << *CurInst << "\n------>\n"); + if (It == CurInst->op_end()) { + // Insert the new instructions in topological order. + if (!CurInst->getParent()) + CurInst->insertBefore(InsertPos); + + WorkStack.pop_back(); + } else { + // for each node N, + Instruction *Operand = dyn_cast(*It); + ++WorkStack.back().second; + + // Can not move no instruction value. + if (Operand == 0) continue; + + DEBUG(dbgs() << "For Operand:\n" << *Operand << "\n--->"); + + // If the Scop Region does not contain N, skip it and all its operand and + // continue. because we reach a "parameter". + // FIXME: we must keep the predicate instruction inside the Scop, otherwise + // it will be translated to a load instruction, and we can not handle load + // as affine predicate at this moment. + if (!R->contains(Operand) && !isa(CurInst)) { + DEBUG(dbgs() << "Out of region.\n"); + continue; + } + + // No need to move induction variable. + if (isIndVar(Operand, LI)) { + DEBUG(dbgs() << "is IV.\n"); + continue; + } + + // We can not move the operand, a non trivial scalar dependence found! + if (!isSafeToMove(Operand)) { + DEBUG(dbgs() << "Can not move!\n"); + continue; + } + + // Do not need to move instruction if it contained in the same BB with + // the root instruction. + // FIXME: Remember this in visited Map. + if (Operand->getParent() == CurBB) { + DEBUG(dbgs() << "No need to move.\n"); + // Try to move its operand. + WorkStack.push_back(std::make_pair(Operand, Operand->op_begin())); + continue; + } + + // Now we need to move Operand to CurBB. + // Check if we already moved it. + ReplacedMapType::iterator At = ReplacedMap.find(Operand); + if (At != ReplacedMap.end()) { + DEBUG(dbgs() << "Moved.\n"); + Instruction *MovedOp = At->second; + It->set(MovedOp); + // Skip all its children as we already processed them. + continue; + } else { + // Note that NewOp is not inserted in any BB now, we will insert it when + // it popped form the work stack, so it will be inserted in topological + // order. + Instruction *NewOp = Operand->clone(); + NewOp->setName(Operand->getName() + ".moved.to." + CurBB->getName()); + DEBUG(dbgs() << "Move to " << *NewOp << "\n"); + It->set(NewOp); + ReplacedMap.insert(std::make_pair(Operand, NewOp)); + // Process its operands. + WorkStack.push_back(std::make_pair(NewOp, NewOp->op_begin())); + } + } + } + + SE->forgetValue(Inst); +} + +bool IndependentBlocks::createIndependentBlocks(BasicBlock *BB, + const Region *R) { + std::vector WorkList; + for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II) + if (!isSafeToMove(II) && !isIndVar(II, LI)) + WorkList.push_back(II); + + ReplacedMapType ReplacedMap; + Instruction *InsertPos = BB->getFirstNonPHIOrDbg(); + + for (std::vector::iterator I = WorkList.begin(), + E = WorkList.end(); I != E; ++I) + moveOperandTree(*I, R, ReplacedMap, InsertPos); + + // The BB was changed if we replaced any operand. + return !ReplacedMap.empty(); +} + +bool IndependentBlocks::createIndependentBlocks(const Region *R) { + bool Changed = false; + + for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end(); + SI != SE; ++SI) + Changed |= createIndependentBlocks((*SI)->getNodeAs(), R); + + return Changed; +} + +bool IndependentBlocks::eliminateDeadCode(const Region *R) { + std::vector WorkList; + + // Find all trivially dead instructions. + for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end(); + SI != SE; ++SI) { + BasicBlock *BB = (*SI)->getNodeAs(); + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + if (isInstructionTriviallyDead(I)) + WorkList.push_back(I); + } + + if (WorkList.empty()) return false; + + // Delete them so the cross BB scalar dependences come with them will + // also be eliminated. + while (!WorkList.empty()) { + RecursivelyDeleteTriviallyDeadInstructions(WorkList.back()); + WorkList.pop_back(); + } + + return true; +} + +bool IndependentBlocks::isEscapeUse(const Value *Use, const Region *R) { + // Non-instruction user will never escape. + if (!isa(Use)) return false; + + return !R->contains(cast(Use)); +} + +bool IndependentBlocks::isEscapeOperand(const Value *Operand, + const BasicBlock *CurBB, + const Region *R) const { + const Instruction *OpInst = dyn_cast(Operand); + + // Non-instruction operand will never escape. + if (OpInst == 0) return false; + + // Induction variables are valid operands. + if (isIndVar(OpInst, LI)) return false; + + // A value from a different BB is used in the same region. + return R->contains(OpInst) && (OpInst->getParent() != CurBB); +} + +bool IndependentBlocks::splitExitBlock(Region *R) { + // Split the exit BB to place the load instruction of escaped users. + BasicBlock *ExitBB = R->getExit(); + Region *ExitRegion = RI->getRegionFor(ExitBB); + + if (ExitBB != ExitRegion->getEntry()) + return false; + + BasicBlock *NewExit = createSingleExitEdge(R, this); + + std::vector toUpdate; + toUpdate.push_back(R); + + while (!toUpdate.empty()) { + Region *Reg = toUpdate.back(); + toUpdate.pop_back(); + + for (Region::iterator I = Reg->begin(), E = Reg->end(); I != E; ++I) { + Region *SubR = *I; + + if (SubR->getExit() == ExitBB) + toUpdate.push_back(SubR); + } + + Reg->replaceExit(NewExit); + } + + RI->setRegionFor(NewExit, R->getParent()); + return true; +} + +bool IndependentBlocks::translateScalarToArray(const Region *R) { + bool Changed = false; + + for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end(); + SI != SE; ++SI) + Changed |= translateScalarToArray((*SI)->getNodeAs(), R); + + return Changed; +} + +bool IndependentBlocks::translateScalarToArray(Instruction *Inst, + const Region *R) { + if (isIndVar(Inst, LI)) + return false; + + SmallVector LoadInside, LoadOutside; + for (Instruction::use_iterator UI = Inst->use_begin(), + UE = Inst->use_end(); UI != UE; ++UI) + // Inst is referenced outside or referenced as an escaped operand. + if (Instruction *U = dyn_cast(*UI)) { + BasicBlock *UParent = U->getParent(); + + if (isEscapeUse(U, R)) + LoadOutside.push_back(U); + + if (isIndVar(U, LI)) + continue; + + if (R->contains(UParent) && isEscapeOperand(Inst, UParent, R)) + LoadInside.push_back(U); + } + + if (LoadOutside.empty() && LoadInside.empty()) + return false; + + // Create the alloca. + AllocaInst *Slot = new AllocaInst(Inst->getType(), 0, + Inst->getName() + ".s2a", + AllocaBlock->begin()); + assert(!isa(Inst) && "Unexpect Invoke in Scop!"); + // Store right after Inst. + BasicBlock::iterator StorePos = Inst; + (void) new StoreInst(Inst, Slot, ++StorePos); + + if (!LoadOutside.empty()) { + LoadInst *ExitLoad = new LoadInst(Slot, Inst->getName()+".loadoutside", + false, R->getExit()->getFirstNonPHI()); + + while (!LoadOutside.empty()) { + Instruction *U = LoadOutside.pop_back_val(); + assert(!isa(U) && "Can not handle PHI node outside!"); + SE->forgetValue(U); + U->replaceUsesOfWith(Inst, ExitLoad); + } + } + + while (!LoadInside.empty()) { + Instruction *U = LoadInside.pop_back_val(); + assert(!isa(U) && "Can not handle PHI node outside!"); + SE->forgetValue(U); + LoadInst *L = new LoadInst(Slot, Inst->getName()+".loadarray", + false, U); + U->replaceUsesOfWith(Inst, L); + } + + return true; +} + +bool IndependentBlocks::translateScalarToArray(BasicBlock *BB, + const Region *R) { + bool changed = false; + + SmallVector Insts; + for (BasicBlock::iterator II = BB->begin(), IE = --BB->end(); + II != IE; ++II) + Insts.push_back(II); + + while (!Insts.empty()) { + Instruction *Inst = Insts.pop_back_val(); + changed |= translateScalarToArray(Inst, R); + } + + return changed; +} + +bool IndependentBlocks::isIndependentBlock(const Region *R, + BasicBlock *BB) const { + for (BasicBlock::iterator II = BB->begin(), IE = --BB->end(); + II != IE; ++II) { + Instruction *Inst = &*II; + + if (isIndVar(Inst, LI)) + continue; + + // A value inside the Scop is referenced outside. + for (Instruction::use_iterator UI = Inst->use_begin(), + UE = Inst->use_end(); UI != UE; ++UI) { + if (isEscapeUse(*UI, R)) { + DEBUG(dbgs() << "Instruction not independent:\n"); + DEBUG(dbgs() << "Instruction used outside the Scop!\n"); + DEBUG(Inst->print(dbgs())); + DEBUG(dbgs() << "\n"); + return false; + } + } + + for (Instruction::op_iterator OI = Inst->op_begin(), + OE = Inst->op_end(); OI != OE; ++OI) { + if (isEscapeOperand(*OI, BB, R)) { + DEBUG(dbgs() << "Instruction in function '"; + WriteAsOperand(dbgs(), BB->getParent(), false); + dbgs() << "' not independent:\n"); + DEBUG(dbgs() << "Uses invalid operator\n"); + DEBUG(Inst->print(dbgs())); + DEBUG(dbgs() << "\n"); + DEBUG(dbgs() << "Invalid operator is: "; + WriteAsOperand(dbgs(), *OI, false); + dbgs() << "\n"); + return false; + } + } + } + + return true; +} + +bool IndependentBlocks::areAllBlocksIndependent(const Region *R) const { + for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end(); + SI != SE; ++SI) + if (!isIndependentBlock(R, (*SI)->getNodeAs())) + return false; + + return true; +} + +void IndependentBlocks::getAnalysisUsage(AnalysisUsage &AU) const { + // FIXME: If we set preserves cfg, the cfg only passes do not need to + // be "addPreserved"? + AU.addPreserved(); + AU.addPreserved(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addRequired(); + AU.addPreserved(); + AU.addPreserved(); +} + +bool IndependentBlocks::runOnFunction(llvm::Function &F) { + bool Changed = false; + + RI = &getAnalysis(); + LI = &getAnalysis(); + SD = &getAnalysis(); + SE = &getAnalysis(); + + AllocaBlock = &F.getEntryBlock(); + + DEBUG(dbgs() << "Run IndepBlock on " << F.getName() << '\n'); + + for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) { + const Region *R = *I; + Changed |= createIndependentBlocks(R); + Changed |= eliminateDeadCode(R); + // This may change the RegionTree. + Changed |= splitExitBlock(const_cast(R)); + } + + DEBUG(dbgs() << "Before Scalar to Array------->\n"); + DEBUG(F.dump()); + + for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) + Changed |= translateScalarToArray(*I); + + DEBUG(dbgs() << "After Independent Blocks------------->\n"); + DEBUG(F.dump()); + + verifyAnalysis(); + + return Changed; +} + +void IndependentBlocks::verifyAnalysis() const { + for (ScopDetection::const_iterator I = SD->begin(), E = SD->end();I != E;++I) + verifyScop(*I); +} + +void IndependentBlocks::verifyScop(const Region *R) const { + assert (areAllBlocksIndependent(R) && "Cannot generate independent blocks"); +} + +char IndependentBlocks::ID = 0; +char &polly::IndependentBlocksID = IndependentBlocks::ID; + +INITIALIZE_PASS_BEGIN(IndependentBlocks, "polly-independent", + "Polly - Create independent blocks", false, false) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_DEPENDENCY(RegionInfo) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) +INITIALIZE_PASS_DEPENDENCY(ScopDetection) +INITIALIZE_PASS_END(IndependentBlocks, "polly-independent", + "Polly - Create independent blocks", false, false) + +Pass *polly::createIndependentBlocksPass() { + return new IndependentBlocks(); +} diff --git a/tools/polly/lib/JSON/CMakeLists.txt b/tools/polly/lib/JSON/CMakeLists.txt new file mode 100755 index 00000000000..68bc1a1932d --- /dev/null +++ b/tools/polly/lib/JSON/CMakeLists.txt @@ -0,0 +1,6 @@ +add_polly_library(PollyJSON + json_reader.cpp + json_value.cpp + json_writer.cpp +) + diff --git a/tools/polly/lib/JSON/LICENSE.txt b/tools/polly/lib/JSON/LICENSE.txt new file mode 100644 index 00000000000..1c37b118103 --- /dev/null +++ b/tools/polly/lib/JSON/LICENSE.txt @@ -0,0 +1 @@ +The json-cpp library and this documentation are in Public Domain. diff --git a/tools/polly/lib/JSON/Makefile b/tools/polly/lib/JSON/Makefile new file mode 100755 index 00000000000..9f1d2df826e --- /dev/null +++ b/tools/polly/lib/JSON/Makefile @@ -0,0 +1,16 @@ +##===- polly/lib/Support/Makefile ----------------*- Makefile -*-===## + +# +# Indicate where we are relative to the top of the source tree. +# +LEVEL=../.. + +LIBRARYNAME=pollyjson +BUILD_ARCHIVE = 1 + +CPP.Flags += $(POLLY_INC) + +# +# Include Makefile.common so we know what to do. +# +include $(LEVEL)/Makefile.common diff --git a/tools/polly/lib/JSON/include/json/autolink.h b/tools/polly/lib/JSON/include/json/autolink.h new file mode 100644 index 00000000000..37c9258ed51 --- /dev/null +++ b/tools/polly/lib/JSON/include/json/autolink.h @@ -0,0 +1,19 @@ +#ifndef JSON_AUTOLINK_H_INCLUDED +# define JSON_AUTOLINK_H_INCLUDED + +# include "config.h" + +# ifdef JSON_IN_CPPTL +# include +# endif + +# if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && !defined(JSON_IN_CPPTL) +# define CPPTL_AUTOLINK_NAME "json" +# undef CPPTL_AUTOLINK_DLL +# ifdef JSON_DLL +# define CPPTL_AUTOLINK_DLL +# endif +# include "autolink.h" +# endif + +#endif // JSON_AUTOLINK_H_INCLUDED diff --git a/tools/polly/lib/JSON/include/json/config.h b/tools/polly/lib/JSON/include/json/config.h new file mode 100644 index 00000000000..b6dde91635b --- /dev/null +++ b/tools/polly/lib/JSON/include/json/config.h @@ -0,0 +1,43 @@ +#ifndef JSON_CONFIG_H_INCLUDED +# define JSON_CONFIG_H_INCLUDED + +/// If defined, indicates that json library is embedded in CppTL library. +//# define JSON_IN_CPPTL 1 + +/// If defined, indicates that json may leverage CppTL library +//# define JSON_USE_CPPTL 1 +/// If defined, indicates that cpptl vector based map should be used instead of std::map +/// as Value container. +//# define JSON_USE_CPPTL_SMALLMAP 1 +/// If defined, indicates that Json specific container should be used +/// (hash table & simple deque container with customizable allocator). +/// THIS FEATURE IS STILL EXPERIMENTAL! +//# define JSON_VALUE_USE_INTERNAL_MAP 1 +/// Force usage of standard new/malloc based allocator instead of memory pool based allocator. +/// The memory pools allocator used optimization (initializing Value and ValueInternalLink +/// as if it was a POD) that may cause some validation tool to report errors. +/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined. +//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1 + +/// If defined, indicates that Json use exception to report invalid type manipulation +/// instead of C assert macro. +# define JSON_USE_EXCEPTION 0 + +# ifdef JSON_IN_CPPTL +# include +# ifndef JSON_USE_CPPTL +# define JSON_USE_CPPTL 1 +# endif +# endif + +# ifdef JSON_IN_CPPTL +# define JSON_API CPPTL_API +# elif defined(JSON_DLL_BUILD) +# define JSON_API __declspec(dllexport) +# elif defined(JSON_DLL) +# define JSON_API __declspec(dllimport) +# else +# define JSON_API +# endif + +#endif // JSON_CONFIG_H_INCLUDED diff --git a/tools/polly/lib/JSON/include/json/features.h b/tools/polly/lib/JSON/include/json/features.h new file mode 100644 index 00000000000..5a9adec1186 --- /dev/null +++ b/tools/polly/lib/JSON/include/json/features.h @@ -0,0 +1,42 @@ +#ifndef CPPTL_JSON_FEATURES_H_INCLUDED +# define CPPTL_JSON_FEATURES_H_INCLUDED + +# include "forwards.h" + +namespace Json { + + /** \brief Configuration passed to reader and writer. + * This configuration object can be used to force the Reader or Writer + * to behave in a standard conforming way. + */ + class JSON_API Features + { + public: + /** \brief A configuration that allows all features and assumes all strings are UTF-8. + * - C & C++ comments are allowed + * - Root object can be any JSON value + * - Assumes Value strings are encoded in UTF-8 + */ + static Features all(); + + /** \brief A configuration that is strictly compatible with the JSON specification. + * - Comments are forbidden. + * - Root object must be either an array or an object value. + * - Assumes Value strings are encoded in UTF-8 + */ + static Features strictMode(); + + /** \brief Initialize the configuration like JsonConfig::allFeatures; + */ + Features(); + + /// \c true if comments are allowed. Default: \c true. + bool allowComments_; + + /// \c true if root must be either an array or an object value. Default: \c false. + bool strictRoot_; + }; + +} // namespace Json + +#endif // CPPTL_JSON_FEATURES_H_INCLUDED diff --git a/tools/polly/lib/JSON/include/json/forwards.h b/tools/polly/lib/JSON/include/json/forwards.h new file mode 100644 index 00000000000..d0ce8300cea --- /dev/null +++ b/tools/polly/lib/JSON/include/json/forwards.h @@ -0,0 +1,39 @@ +#ifndef JSON_FORWARDS_H_INCLUDED +# define JSON_FORWARDS_H_INCLUDED + +# include "config.h" + +namespace Json { + + // writer.h + class FastWriter; + class StyledWriter; + + // reader.h + class Reader; + + // features.h + class Features; + + // value.h + typedef int Int; + typedef unsigned int UInt; + class StaticString; + class Path; + class PathArgument; + class Value; + class ValueIteratorBase; + class ValueIterator; + class ValueConstIterator; +#ifdef JSON_VALUE_USE_INTERNAL_MAP + class ValueAllocator; + class ValueMapAllocator; + class ValueInternalLink; + class ValueInternalArray; + class ValueInternalMap; +#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP + +} // namespace Json + + +#endif // JSON_FORWARDS_H_INCLUDED diff --git a/tools/polly/lib/JSON/include/json/json.h b/tools/polly/lib/JSON/include/json/json.h new file mode 100644 index 00000000000..c71ed65abff --- /dev/null +++ b/tools/polly/lib/JSON/include/json/json.h @@ -0,0 +1,10 @@ +#ifndef JSON_JSON_H_INCLUDED +# define JSON_JSON_H_INCLUDED + +# include "autolink.h" +# include "value.h" +# include "reader.h" +# include "writer.h" +# include "features.h" + +#endif // JSON_JSON_H_INCLUDED diff --git a/tools/polly/lib/JSON/include/json/reader.h b/tools/polly/lib/JSON/include/json/reader.h new file mode 100644 index 00000000000..ee1d6a2444a --- /dev/null +++ b/tools/polly/lib/JSON/include/json/reader.h @@ -0,0 +1,196 @@ +#ifndef CPPTL_JSON_READER_H_INCLUDED +# define CPPTL_JSON_READER_H_INCLUDED + +# include "features.h" +# include "value.h" +# include +# include +# include +# include + +namespace Json { + + /** \brief Unserialize a JSON document into a Value. + * + */ + class JSON_API Reader + { + public: + typedef char Char; + typedef const Char *Location; + + /** \brief Constructs a Reader allowing all features + * for parsing. + */ + Reader(); + + /** \brief Constructs a Reader allowing the specified feature set + * for parsing. + */ + Reader( const Features &features ); + + /** \brief Read a Value from a JSON document. + * \param document UTF-8 encoded string containing the document to read. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them back during + * serialization, \c false to discard comments. + * This parameter is ignored if Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an error occurred. + */ + bool parse( const std::string &document, + Value &root, + bool collectComments = true ); + + /** \brief Read a Value from a JSON document. + * \param document UTF-8 encoded string containing the document to read. + * \param root [out] Contains the root value of the document if it was + * successfully parsed. + * \param collectComments \c true to collect comment and allow writing them back during + * serialization, \c false to discard comments. + * This parameter is ignored if Features::allowComments_ + * is \c false. + * \return \c true if the document was successfully parsed, \c false if an error occurred. + */ + bool parse( const char *beginDoc, const char *endDoc, + Value &root, + bool collectComments = true ); + + /// \brief Parse from input stream. + /// \see Json::operator>>(std::istream&, Json::Value&). + bool parse( std::istream &is, + Value &root, + bool collectComments = true ); + + /** \brief Returns a user friendly string that list errors in the parsed document. + * \return Formatted error message with the list of errors with their location in + * the parsed document. An empty string is returned if no error occurred + * during parsing. + */ + std::string getFormatedErrorMessages() const; + + private: + enum TokenType + { + tokenEndOfStream = 0, + tokenObjectBegin, + tokenObjectEnd, + tokenArrayBegin, + tokenArrayEnd, + tokenString, + tokenNumber, + tokenTrue, + tokenFalse, + tokenNull, + tokenArraySeparator, + tokenMemberSeparator, + tokenComment, + tokenError + }; + + class Token + { + public: + TokenType type_; + Location start_; + Location end_; + }; + + class ErrorInfo + { + public: + Token token_; + std::string message_; + Location extra_; + }; + + typedef std::deque Errors; + + bool expectToken( TokenType type, Token &token, const char *message ); + bool readToken( Token &token ); + void skipSpaces(); + bool match( Location pattern, + int patternLength ); + bool readComment(); + bool readCStyleComment(); + bool readCppStyleComment(); + bool readString(); + void readNumber(); + bool readValue(); + bool readObject( Token &token ); + bool readArray( Token &token ); + bool decodeNumber( Token &token ); + bool decodeString( Token &token ); + bool decodeString( Token &token, std::string &decoded ); + bool decodeDouble( Token &token ); + bool decodeUnicodeCodePoint( Token &token, + Location ¤t, + Location end, + unsigned int &unicode ); + bool decodeUnicodeEscapeSequence( Token &token, + Location ¤t, + Location end, + unsigned int &unicode ); + bool addError( const std::string &message, + Token &token, + Location extra = 0 ); + bool recoverFromError( TokenType skipUntilToken ); + bool addErrorAndRecover( const std::string &message, + Token &token, + TokenType skipUntilToken ); + void skipUntilSpace(); + Value ¤tValue(); + Char getNextChar(); + void getLocationLineAndColumn( Location location, + int &line, + int &column ) const; + std::string getLocationLineAndColumn( Location location ) const; + void addComment( Location begin, + Location end, + CommentPlacement placement ); + void skipCommentTokens( Token &token ); + + typedef std::stack Nodes; + Nodes nodes_; + Errors errors_; + std::string document_; + Location begin_; + Location end_; + Location current_; + Location lastValueEnd_; + Value *lastValue_; + std::string commentsBefore_; + Features features_; + bool collectComments_; + }; + + /** \brief Read from 'sin' into 'root'. + + Always keep comments from the input JSON. + + This can be used to read a file into a particular sub-object. + For example: + \code + Json::Value root; + cin >> root["dir"]["file"]; + cout << root; + \endcode + Result: + \verbatim + { + "dir": { + "file": { + // The input stream JSON would be nested here. + } + } + } + \endverbatim + \throw std::exception on parse error. + \see Json::operator<<() + */ + std::istream& operator>>( std::istream&, Value& ); + +} // namespace Json + +#endif // CPPTL_JSON_READER_H_INCLUDED diff --git a/tools/polly/lib/JSON/include/json/value.h b/tools/polly/lib/JSON/include/json/value.h new file mode 100644 index 00000000000..58bfd88e7a1 --- /dev/null +++ b/tools/polly/lib/JSON/include/json/value.h @@ -0,0 +1,1069 @@ +#ifndef CPPTL_JSON_H_INCLUDED +# define CPPTL_JSON_H_INCLUDED + +# include "forwards.h" +# include +# include + +# ifndef JSON_USE_CPPTL_SMALLMAP +# include +# else +# include +# endif +# ifdef JSON_USE_CPPTL +# include +# endif + +/** \brief JSON (JavaScript Object Notation). + */ +namespace Json { + + /** \brief Type of the value held by a Value object. + */ + enum ValueType + { + nullValue = 0, ///< 'null' value + intValue, ///< signed integer value + uintValue, ///< unsigned integer value + realValue, ///< double value + stringValue, ///< UTF-8 string value + booleanValue, ///< bool value + arrayValue, ///< array value (ordered list) + objectValue ///< object value (collection of name/value pairs). + }; + + enum CommentPlacement + { + commentBefore = 0, ///< a comment placed on the line before a value + commentAfterOnSameLine, ///< a comment just after a value on the same line + commentAfter, ///< a comment on the line after a value (only make sense for root value) + numberOfCommentPlacement + }; + +//# ifdef JSON_USE_CPPTL +// typedef CppTL::AnyEnumerator EnumMemberNames; +// typedef CppTL::AnyEnumerator EnumValues; +//# endif + + /** \brief Lightweight wrapper to tag static string. + * + * Value constructor and objectValue member assignement takes advantage of the + * StaticString and avoid the cost of string duplication when storing the + * string or the member name. + * + * Example of usage: + * \code + * Json::Value aValue( StaticString("some text") ); + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ + class JSON_API StaticString + { + public: + explicit StaticString( const char *czstring ) + : str_( czstring ) + { + } + + operator const char *() const + { + return str_; + } + + const char *c_str() const + { + return str_; + } + + private: + const char *str_; + }; + + /** \brief Represents a JSON value. + * + * This class is a discriminated union wrapper that can represents a: + * - signed integer [range: Value::minInt - Value::maxInt] + * - unsigned integer (range: 0 - Value::maxUInt) + * - double + * - UTF-8 string + * - boolean + * - 'null' + * - an ordered list of Value + * - collection of name/value pairs (javascript object) + * + * The type of the held value is represented by a #ValueType and + * can be obtained using type(). + * + * values of an #objectValue or #arrayValue can be accessed using operator[]() methods. + * Non const methods will automatically create the a #nullValue element + * if it does not exist. + * The sequence of an #arrayValue will be automatically resize and initialized + * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. + * + * The get() methods can be used to obtanis default value in the case the required element + * does not exist. + * + * It is possible to iterate over the list of a #objectValue values using + * the getMemberNames() method. + */ + class JSON_API Value + { + friend class ValueIteratorBase; +# ifdef JSON_VALUE_USE_INTERNAL_MAP + friend class ValueInternalLink; + friend class ValueInternalMap; +# endif + public: + typedef std::vector Members; + typedef ValueIterator iterator; + typedef ValueConstIterator const_iterator; + typedef Json::UInt UInt; + typedef Json::Int Int; + typedef UInt ArrayIndex; + + static const Value null; + static const Int minInt; + static const Int maxInt; + static const UInt maxUInt; + + private: +#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION +# ifndef JSON_VALUE_USE_INTERNAL_MAP + class CZString + { + public: + enum DuplicationPolicy + { + noDuplication = 0, + duplicate, + duplicateOnCopy + }; + CZString( int index ); + CZString( const char *cstr, DuplicationPolicy allocate ); + CZString( const CZString &other ); + ~CZString(); + CZString &operator =( const CZString &other ); + bool operator<( const CZString &other ) const; + bool operator==( const CZString &other ) const; + int index() const; + const char *c_str() const; + bool isStaticString() const; + private: + void swap( CZString &other ); + const char *cstr_; + int index_; + }; + + public: +# ifndef JSON_USE_CPPTL_SMALLMAP + typedef std::map ObjectValues; +# else + typedef CppTL::SmallMap ObjectValues; +# endif // ifndef JSON_USE_CPPTL_SMALLMAP +# endif // ifndef JSON_VALUE_USE_INTERNAL_MAP +#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + + public: + /** \brief Create a default Value of the given type. + + This is a very useful constructor. + To create an empty array, pass arrayValue. + To create an empty object, pass objectValue. + Another Value can then be set to this one by assignment. + This is useful since clear() and resize() will not alter types. + + Examples: + \code + Json::Value null_value; // null + Json::Value arr_value(Json::arrayValue); // [] + Json::Value obj_value(Json::objectValue); // {} + \endcode + */ + Value( ValueType type = nullValue ); + Value( Int value ); + Value( UInt value ); + Value( double value ); + Value( const char *value ); + Value( const char *beginValue, const char *endValue ); + /** \brief Constructs a value from a static string. + + * Like other value string constructor but do not duplicate the string for + * internal storage. The given string must remain alive after the call to this + * constructor. + * Example of usage: + * \code + * Json::Value aValue( StaticString("some text") ); + * \endcode + */ + Value( const StaticString &value ); + Value( const std::string &value ); +# ifdef JSON_USE_CPPTL + Value( const CppTL::ConstString &value ); +# endif + Value( bool value ); + Value( const Value &other ); + ~Value(); + + Value &operator=( const Value &other ); + /// Swap values. + /// \note Currently, comments are intentionally not swapped, for + /// both logic and efficiency. + void swap( Value &other ); + + ValueType type() const; + + bool operator <( const Value &other ) const; + bool operator <=( const Value &other ) const; + bool operator >=( const Value &other ) const; + bool operator >( const Value &other ) const; + + bool operator ==( const Value &other ) const; + bool operator !=( const Value &other ) const; + + int compare( const Value &other ); + + const char *asCString() const; + std::string asString() const; +# ifdef JSON_USE_CPPTL + CppTL::ConstString asConstString() const; +# endif + Int asInt() const; + UInt asUInt() const; + double asDouble() const; + bool asBool() const; + + bool isNull() const; + bool isBool() const; + bool isInt() const; + bool isUInt() const; + bool isIntegral() const; + bool isDouble() const; + bool isNumeric() const; + bool isString() const; + bool isArray() const; + bool isObject() const; + + bool isConvertibleTo( ValueType other ) const; + + /// Number of values in array or object + UInt size() const; + + /// \brief Return true if empty array, empty object, or null; + /// otherwise, false. + bool empty() const; + + /// Return isNull() + bool operator!() const; + + /// Remove all object members and array elements. + /// \pre type() is arrayValue, objectValue, or nullValue + /// \post type() is unchanged + void clear(); + + /// Resize the array to size elements. + /// New elements are initialized to null. + /// May only be called on nullValue or arrayValue. + /// \pre type() is arrayValue or nullValue + /// \post type() is arrayValue + void resize( UInt size ); + + /// Access an array element (zero based index ). + /// If the array contains less than index element, then null value are inserted + /// in the array so that its size is index+1. + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + Value &operator[]( UInt index ); + /// Access an array element (zero based index ) + /// (You may need to say 'value[0u]' to get your compiler to distinguish + /// this from the operator[] which takes a string.) + const Value &operator[]( UInt index ) const; + /// If the array contains at least index+1 elements, returns the element value, + /// otherwise returns defaultValue. + Value get( UInt index, + const Value &defaultValue ) const; + /// Return true if index < size(). + bool isValidIndex( UInt index ) const; + /// \brief Append value to array at the end. + /// + /// Equivalent to jsonvalue[jsonvalue.size()] = value; + Value &append( const Value &value ); + + /// Access an object value by name, create a null member if it does not exist. + Value &operator[]( const char *key ); + /// Access an object value by name, returns null if there is no member with that name. + const Value &operator[]( const char *key ) const; + /// Access an object value by name, create a null member if it does not exist. + Value &operator[]( const std::string &key ); + /// Access an object value by name, returns null if there is no member with that name. + const Value &operator[]( const std::string &key ) const; + /** \brief Access an object value by name, create a null member if it does not exist. + + * If the object as no entry for that name, then the member name used to store + * the new entry is not duplicated. + * Example of use: + * \code + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode + */ + Value &operator[]( const StaticString &key ); +# ifdef JSON_USE_CPPTL + /// Access an object value by name, create a null member if it does not exist. + Value &operator[]( const CppTL::ConstString &key ); + /// Access an object value by name, returns null if there is no member with that name. + const Value &operator[]( const CppTL::ConstString &key ) const; +# endif + /// Return the member named key if it exist, defaultValue otherwise. + Value get( const char *key, + const Value &defaultValue ) const; + /// Return the member named key if it exist, defaultValue otherwise. + Value get( const std::string &key, + const Value &defaultValue ) const; +# ifdef JSON_USE_CPPTL + /// Return the member named key if it exist, defaultValue otherwise. + Value get( const CppTL::ConstString &key, + const Value &defaultValue ) const; +# endif + /// \brief Remove and return the named member. + /// + /// Do nothing if it did not exist. + /// \return the removed Value, or null. + /// \pre type() is objectValue or nullValue + /// \post type() is unchanged + Value removeMember( const char* key ); + /// Same as removeMember(const char*) + Value removeMember( const std::string &key ); + + /// Return true if the object has a member named key. + bool isMember( const char *key ) const; + /// Return true if the object has a member named key. + bool isMember( const std::string &key ) const; +# ifdef JSON_USE_CPPTL + /// Return true if the object has a member named key. + bool isMember( const CppTL::ConstString &key ) const; +# endif + + /// \brief Return a list of the member names. + /// + /// If null, return an empty list. + /// \pre type() is objectValue or nullValue + /// \post if type() was nullValue, it remains nullValue + Members getMemberNames() const; + +//# ifdef JSON_USE_CPPTL +// EnumMemberNames enumMemberNames() const; +// EnumValues enumValues() const; +//# endif + + /// Comments must be //... or /* ... */ + void setComment( const char *comment, + CommentPlacement placement ); + /// Comments must be //... or /* ... */ + void setComment( const std::string &comment, + CommentPlacement placement ); + bool hasComment( CommentPlacement placement ) const; + /// Include delimiters and embedded newlines. + std::string getComment( CommentPlacement placement ) const; + + std::string toStyledString() const; + + const_iterator begin() const; + const_iterator end() const; + + iterator begin(); + iterator end(); + + private: + Value &resolveReference( const char *key, + bool isStatic ); + +# ifdef JSON_VALUE_USE_INTERNAL_MAP + inline bool isItemAvailable() const + { + return itemIsUsed_ == 0; + } + + inline void setItemUsed( bool isUsed = true ) + { + itemIsUsed_ = isUsed ? 1 : 0; + } + + inline bool isMemberNameStatic() const + { + return memberNameIsStatic_ == 0; + } + + inline void setMemberNameIsStatic( bool isStatic ) + { + memberNameIsStatic_ = isStatic ? 1 : 0; + } +# endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP + + private: + struct CommentInfo + { + CommentInfo(); + ~CommentInfo(); + + void setComment( const char *text ); + + char *comment_; + }; + + //struct MemberNamesTransform + //{ + // typedef const char *result_type; + // const char *operator()( const CZString &name ) const + // { + // return name.c_str(); + // } + //}; + + union ValueHolder + { + Int int_; + UInt uint_; + double real_; + bool bool_; + char *string_; +# ifdef JSON_VALUE_USE_INTERNAL_MAP + ValueInternalArray *array_; + ValueInternalMap *map_; +#else + ObjectValues *map_; +# endif + } value_; + ValueType type_ : 8; + int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. +# ifdef JSON_VALUE_USE_INTERNAL_MAP + unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container. + int memberNameIsStatic_ : 1; // used by the ValueInternalMap container. +# endif + CommentInfo *comments_; + }; + + + /** \brief Experimental and untested: represents an element of the "path" to access a node. + */ + class PathArgument + { + public: + friend class Path; + + PathArgument(); + PathArgument( UInt index ); + PathArgument( const char *key ); + PathArgument( const std::string &key ); + + private: + enum Kind + { + kindNone = 0, + kindIndex, + kindKey + }; + std::string key_; + UInt index_; + Kind kind_; + }; + + /** \brief Experimental and untested: represents a "path" to access a node. + * + * Syntax: + * - "." => root node + * - ".[n]" => elements at index 'n' of root node (an array value) + * - ".name" => member named 'name' of root node (an object value) + * - ".name1.name2.name3" + * - ".[0][1][2].name1[3]" + * - ".%" => member name is provided as parameter + * - ".[%]" => index is provied as parameter + */ + class Path + { + public: + Path( const std::string &path, + const PathArgument &a1 = PathArgument(), + const PathArgument &a2 = PathArgument(), + const PathArgument &a3 = PathArgument(), + const PathArgument &a4 = PathArgument(), + const PathArgument &a5 = PathArgument() ); + + const Value &resolve( const Value &root ) const; + Value resolve( const Value &root, + const Value &defaultValue ) const; + /// Creates the "path" to access the specified node and returns a reference on the node. + Value &make( Value &root ) const; + + private: + typedef std::vector InArgs; + typedef std::vector Args; + + void makePath( const std::string &path, + const InArgs &in ); + void addPathInArg( const std::string &path, + const InArgs &in, + InArgs::const_iterator &itInArg, + PathArgument::Kind kind ); + void invalidPath( const std::string &path, + int location ); + + Args args_; + }; + + /** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value. + * + * - makeMemberName() and releaseMemberName() are called to respectively duplicate and + * free an Json::objectValue member name. + * - duplicateStringValue() and releaseStringValue() are called similarly to + * duplicate and free a Json::stringValue value. + */ + class ValueAllocator + { + public: + enum { unknown = (unsigned)-1 }; + + virtual ~ValueAllocator(); + + virtual char *makeMemberName( const char *memberName ) = 0; + virtual void releaseMemberName( char *memberName ) = 0; + virtual char *duplicateStringValue( const char *value, + unsigned int length = unknown ) = 0; + virtual void releaseStringValue( char *value ) = 0; + }; + +#ifdef JSON_VALUE_USE_INTERNAL_MAP + /** \brief Allocator to customize Value internal map. + * Below is an example of a simple implementation (default implementation actually + * use memory pool for speed). + * \code + class DefaultValueMapAllocator : public ValueMapAllocator + { + public: // overridden from ValueMapAllocator + virtual ValueInternalMap *newMap() + { + return new ValueInternalMap(); + } + + virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) + { + return new ValueInternalMap( other ); + } + + virtual void destructMap( ValueInternalMap *map ) + { + delete map; + } + + virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) + { + return new ValueInternalLink[size]; + } + + virtual void releaseMapBuckets( ValueInternalLink *links ) + { + delete [] links; + } + + virtual ValueInternalLink *allocateMapLink() + { + return new ValueInternalLink(); + } + + virtual void releaseMapLink( ValueInternalLink *link ) + { + delete link; + } + }; + * \endcode + */ + class JSON_API ValueMapAllocator + { + public: + virtual ~ValueMapAllocator(); + virtual ValueInternalMap *newMap() = 0; + virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0; + virtual void destructMap( ValueInternalMap *map ) = 0; + virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0; + virtual void releaseMapBuckets( ValueInternalLink *links ) = 0; + virtual ValueInternalLink *allocateMapLink() = 0; + virtual void releaseMapLink( ValueInternalLink *link ) = 0; + }; + + /** \brief ValueInternalMap hash-map bucket chain link (for internal use only). + * \internal previous_ & next_ allows for bidirectional traversal. + */ + class JSON_API ValueInternalLink + { + public: + enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture. + enum InternalFlags { + flagAvailable = 0, + flagUsed = 1 + }; + + ValueInternalLink(); + + ~ValueInternalLink(); + + Value items_[itemPerLink]; + char *keys_[itemPerLink]; + ValueInternalLink *previous_; + ValueInternalLink *next_; + }; + + + /** \brief A linked page based hash-table implementation used internally by Value. + * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked + * list in each bucket to handle collision. There is an addional twist in that + * each node of the collision linked list is a page containing a fixed amount of + * value. This provides a better compromise between memory usage and speed. + * + * Each bucket is made up of a chained list of ValueInternalLink. The last + * link of a given bucket can be found in the 'previous_' field of the following bucket. + * The last link of the last bucket is stored in tailLink_ as it has no following bucket. + * Only the last link of a bucket may contains 'available' item. The last link always + * contains at least one element unless is it the bucket one very first link. + */ + class JSON_API ValueInternalMap + { + friend class ValueIteratorBase; + friend class Value; + public: + typedef unsigned int HashKey; + typedef unsigned int BucketIndex; + +# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + struct IteratorState + { + IteratorState() + : map_(0) + , link_(0) + , itemIndex_(0) + , bucketIndex_(0) + { + } + ValueInternalMap *map_; + ValueInternalLink *link_; + BucketIndex itemIndex_; + BucketIndex bucketIndex_; + }; +# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + + ValueInternalMap(); + ValueInternalMap( const ValueInternalMap &other ); + ValueInternalMap &operator =( const ValueInternalMap &other ); + ~ValueInternalMap(); + + void swap( ValueInternalMap &other ); + + BucketIndex size() const; + + void clear(); + + bool reserveDelta( BucketIndex growth ); + + bool reserve( BucketIndex newItemCount ); + + const Value *find( const char *key ) const; + + Value *find( const char *key ); + + Value &resolveReference( const char *key, + bool isStatic ); + + void remove( const char *key ); + + void doActualRemove( ValueInternalLink *link, + BucketIndex index, + BucketIndex bucketIndex ); + + ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex ); + + Value &setNewItem( const char *key, + bool isStatic, + ValueInternalLink *link, + BucketIndex index ); + + Value &unsafeAdd( const char *key, + bool isStatic, + HashKey hashedKey ); + + HashKey hash( const char *key ) const; + + int compare( const ValueInternalMap &other ) const; + + private: + void makeBeginIterator( IteratorState &it ) const; + void makeEndIterator( IteratorState &it ) const; + static bool equals( const IteratorState &x, const IteratorState &other ); + static void increment( IteratorState &iterator ); + static void incrementBucket( IteratorState &iterator ); + static void decrement( IteratorState &iterator ); + static const char *key( const IteratorState &iterator ); + static const char *key( const IteratorState &iterator, bool &isStatic ); + static Value &value( const IteratorState &iterator ); + static int distance( const IteratorState &x, const IteratorState &y ); + + private: + ValueInternalLink *buckets_; + ValueInternalLink *tailLink_; + BucketIndex bucketsSize_; + BucketIndex itemCount_; + }; + + /** \brief A simplified deque implementation used internally by Value. + * \internal + * It is based on a list of fixed "page", each page contains a fixed number of items. + * Instead of using a linked-list, a array of pointer is used for fast item look-up. + * Look-up for an element is as follow: + * - compute page index: pageIndex = itemIndex / itemsPerPage + * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage] + * + * Insertion is amortized constant time (only the array containing the index of pointers + * need to be reallocated when items are appended). + */ + class JSON_API ValueInternalArray + { + friend class Value; + friend class ValueIteratorBase; + public: + enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo. + typedef Value::ArrayIndex ArrayIndex; + typedef unsigned int PageIndex; + +# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + struct IteratorState // Must be a POD + { + IteratorState() + : array_(0) + , currentPageIndex_(0) + , currentItemIndex_(0) + { + } + ValueInternalArray *array_; + Value **currentPageIndex_; + unsigned int currentItemIndex_; + }; +# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + + ValueInternalArray(); + ValueInternalArray( const ValueInternalArray &other ); + ValueInternalArray &operator =( const ValueInternalArray &other ); + ~ValueInternalArray(); + void swap( ValueInternalArray &other ); + + void clear(); + void resize( ArrayIndex newSize ); + + Value &resolveReference( ArrayIndex index ); + + Value *find( ArrayIndex index ) const; + + ArrayIndex size() const; + + int compare( const ValueInternalArray &other ) const; + + private: + static bool equals( const IteratorState &x, const IteratorState &other ); + static void increment( IteratorState &iterator ); + static void decrement( IteratorState &iterator ); + static Value &dereference( const IteratorState &iterator ); + static Value &unsafeDereference( const IteratorState &iterator ); + static int distance( const IteratorState &x, const IteratorState &y ); + static ArrayIndex indexOf( const IteratorState &iterator ); + void makeBeginIterator( IteratorState &it ) const; + void makeEndIterator( IteratorState &it ) const; + void makeIterator( IteratorState &it, ArrayIndex index ) const; + + void makeIndexValid( ArrayIndex index ); + + Value **pages_; + ArrayIndex size_; + PageIndex pageCount_; + }; + + /** \brief Experimental: do not use. Allocator to customize Value internal array. + * Below is an example of a simple implementation (actual implementation use + * memory pool). + \code +class DefaultValueArrayAllocator : public ValueArrayAllocator +{ +public: // overridden from ValueArrayAllocator + virtual ~DefaultValueArrayAllocator() + { + } + + virtual ValueInternalArray *newArray() + { + return new ValueInternalArray(); + } + + virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) + { + return new ValueInternalArray( other ); + } + + virtual void destruct( ValueInternalArray *array ) + { + delete array; + } + + virtual void reallocateArrayPageIndex( Value **&indexes, + ValueInternalArray::PageIndex &indexCount, + ValueInternalArray::PageIndex minNewIndexCount ) + { + ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; + if ( minNewIndexCount > newIndexCount ) + newIndexCount = minNewIndexCount; + void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); + if ( !newIndexes ) + throw std::bad_alloc(); + indexCount = newIndexCount; + indexes = static_cast( newIndexes ); + } + virtual void releaseArrayPageIndex( Value **indexes, + ValueInternalArray::PageIndex indexCount ) + { + if ( indexes ) + free( indexes ); + } + + virtual Value *allocateArrayPage() + { + return static_cast( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) ); + } + + virtual void releaseArrayPage( Value *value ) + { + if ( value ) + free( value ); + } +}; + \endcode + */ + class JSON_API ValueArrayAllocator + { + public: + virtual ~ValueArrayAllocator(); + virtual ValueInternalArray *newArray() = 0; + virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0; + virtual void destructArray( ValueInternalArray *array ) = 0; + /** \brief Reallocate array page index. + * Reallocates an array of pointer on each page. + * \param indexes [input] pointer on the current index. May be \c NULL. + * [output] pointer on the new index of at least + * \a minNewIndexCount pages. + * \param indexCount [input] current number of pages in the index. + * [output] number of page the reallocated index can handle. + * \b MUST be >= \a minNewIndexCount. + * \param minNewIndexCount Minimum number of page the new index must be able to + * handle. + */ + virtual void reallocateArrayPageIndex( Value **&indexes, + ValueInternalArray::PageIndex &indexCount, + ValueInternalArray::PageIndex minNewIndexCount ) = 0; + virtual void releaseArrayPageIndex( Value **indexes, + ValueInternalArray::PageIndex indexCount ) = 0; + virtual Value *allocateArrayPage() = 0; + virtual void releaseArrayPage( Value *value ) = 0; + }; +#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP + + + /** \brief base class for Value iterators. + * + */ + class ValueIteratorBase + { + public: + typedef unsigned int size_t; + typedef int difference_type; + typedef ValueIteratorBase SelfType; + + ValueIteratorBase(); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + explicit ValueIteratorBase( const Value::ObjectValues::iterator ¤t ); +#else + ValueIteratorBase( const ValueInternalArray::IteratorState &state ); + ValueIteratorBase( const ValueInternalMap::IteratorState &state ); +#endif + + bool operator ==( const SelfType &other ) const + { + return isEqual( other ); + } + + bool operator !=( const SelfType &other ) const + { + return !isEqual( other ); + } + + difference_type operator -( const SelfType &other ) const + { + return computeDistance( other ); + } + + /// Return either the index or the member name of the referenced value as a Value. + Value key() const; + + /// Return the index of the referenced Value. -1 if it is not an arrayValue. + UInt index() const; + + /// Return the member name of the referenced Value. "" if it is not an objectValue. + const char *memberName() const; + + protected: + Value &deref() const; + + void increment(); + + void decrement(); + + difference_type computeDistance( const SelfType &other ) const; + + bool isEqual( const SelfType &other ) const; + + void copy( const SelfType &other ); + + private: +#ifndef JSON_VALUE_USE_INTERNAL_MAP + Value::ObjectValues::iterator current_; + // Indicates that iterator is for a null value. + bool isNull_; +#else + union + { + ValueInternalArray::IteratorState array_; + ValueInternalMap::IteratorState map_; + } iterator_; + bool isArray_; +#endif + }; + + /** \brief const iterator for object and array value. + * + */ + class ValueConstIterator : public ValueIteratorBase + { + friend class Value; + public: + typedef unsigned int size_t; + typedef int difference_type; + typedef const Value &reference; + typedef const Value *pointer; + typedef ValueConstIterator SelfType; + + ValueConstIterator(); + private: + /*! \internal Use by Value to create an iterator. + */ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + explicit ValueConstIterator( const Value::ObjectValues::iterator ¤t ); +#else + ValueConstIterator( const ValueInternalArray::IteratorState &state ); + ValueConstIterator( const ValueInternalMap::IteratorState &state ); +#endif + public: + SelfType &operator =( const ValueIteratorBase &other ); + + SelfType operator++( int ) + { + SelfType temp( *this ); + ++*this; + return temp; + } + + SelfType operator--( int ) + { + SelfType temp( *this ); + --*this; + return temp; + } + + SelfType &operator--() + { + decrement(); + return *this; + } + + SelfType &operator++() + { + increment(); + return *this; + } + + reference operator *() const + { + return deref(); + } + }; + + + /** \brief Iterator for object and array value. + */ + class ValueIterator : public ValueIteratorBase + { + friend class Value; + public: + typedef unsigned int size_t; + typedef int difference_type; + typedef Value &reference; + typedef Value *pointer; + typedef ValueIterator SelfType; + + ValueIterator(); + ValueIterator( const ValueConstIterator &other ); + ValueIterator( const ValueIterator &other ); + private: + /*! \internal Use by Value to create an iterator. + */ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + explicit ValueIterator( const Value::ObjectValues::iterator ¤t ); +#else + ValueIterator( const ValueInternalArray::IteratorState &state ); + ValueIterator( const ValueInternalMap::IteratorState &state ); +#endif + public: + + SelfType &operator =( const SelfType &other ); + + SelfType operator++( int ) + { + SelfType temp( *this ); + ++*this; + return temp; + } + + SelfType operator--( int ) + { + SelfType temp( *this ); + --*this; + return temp; + } + + SelfType &operator--() + { + decrement(); + return *this; + } + + SelfType &operator++() + { + increment(); + return *this; + } + + reference operator *() const + { + return deref(); + } + }; + + +} // namespace Json + + +#endif // CPPTL_JSON_H_INCLUDED diff --git a/tools/polly/lib/JSON/include/json/writer.h b/tools/polly/lib/JSON/include/json/writer.h new file mode 100644 index 00000000000..5f4b83be418 --- /dev/null +++ b/tools/polly/lib/JSON/include/json/writer.h @@ -0,0 +1,174 @@ +#ifndef JSON_WRITER_H_INCLUDED +# define JSON_WRITER_H_INCLUDED + +# include "value.h" +# include +# include +# include + +namespace Json { + + class Value; + + /** \brief Abstract class for writers. + */ + class JSON_API Writer + { + public: + virtual ~Writer(); + + virtual std::string write( const Value &root ) = 0; + }; + + /** \brief Outputs a Value in JSON format without formatting (not human friendly). + * + * The JSON document is written in a single line. It is not intended for 'human' consumption, + * but may be usefull to support feature such as RPC where bandwith is limited. + * \sa Reader, Value + */ + class JSON_API FastWriter : public Writer + { + public: + FastWriter(); + virtual ~FastWriter(){} + + void enableYAMLCompatibility(); + + public: // overridden from Writer + virtual std::string write( const Value &root ); + + private: + void writeValue( const Value &value ); + + std::string document_; + bool yamlCompatiblityEnabled_; + }; + + /** \brief Writes a Value in JSON format in a human friendly way. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value types, + * and all the values fit on one lines, then print the array on a single line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their #CommentPlacement. + * + * \sa Reader, Value, Value::setComment() + */ + class JSON_API StyledWriter: public Writer + { + public: + StyledWriter(); + virtual ~StyledWriter(){} + + public: // overridden from Writer + /** \brief Serialize a Value in JSON format. + * \param root Value to serialize. + * \return String containing the JSON document that represents the root value. + */ + virtual std::string write( const Value &root ); + + private: + void writeValue( const Value &value ); + void writeArrayValue( const Value &value ); + bool isMultineArray( const Value &value ); + void pushValue( const std::string &value ); + void writeIndent(); + void writeWithIndent( const std::string &value ); + void indent(); + void unindent(); + void writeCommentBeforeValue( const Value &root ); + void writeCommentAfterValueOnSameLine( const Value &root ); + bool hasCommentForValue( const Value &value ); + static std::string normalizeEOL( const std::string &text ); + + typedef std::vector ChildValues; + + ChildValues childValues_; + std::string document_; + std::string indentString_; + int rightMargin_; + int indentSize_; + bool addChildValues_; + }; + + /** \brief Writes a Value in JSON format in a human friendly way, + to a stream rather than to a string. + * + * The rules for line break and indent are as follow: + * - Object value: + * - if empty then print {} without indent and line break + * - if not empty the print '{', line break & indent, print one value per line + * and then unindent and line break and print '}'. + * - Array value: + * - if empty then print [] without indent and line break + * - if the array contains no object value, empty array or some other value types, + * and all the values fit on one lines, then print the array on a single line. + * - otherwise, it the values do not fit on one line, or the array contains + * object or non empty array, then print one value per line. + * + * If the Value have comments then they are outputed according to their #CommentPlacement. + * + * \param indentation Each level will be indented by this amount extra. + * \sa Reader, Value, Value::setComment() + */ + class JSON_API StyledStreamWriter + { + public: + StyledStreamWriter( std::string indentation="\t" ); + ~StyledStreamWriter(){} + + public: + /** \brief Serialize a Value in JSON format. + * \param out Stream to write to. (Can be ostringstream, e.g.) + * \param root Value to serialize. + * \note There is no point in deriving from Writer, since write() should not return a value. + */ + void write( std::ostream &out, const Value &root ); + + private: + void writeValue( const Value &value ); + void writeArrayValue( const Value &value ); + bool isMultineArray( const Value &value ); + void pushValue( const std::string &value ); + void writeIndent(); + void writeWithIndent( const std::string &value ); + void indent(); + void unindent(); + void writeCommentBeforeValue( const Value &root ); + void writeCommentAfterValueOnSameLine( const Value &root ); + bool hasCommentForValue( const Value &value ); + static std::string normalizeEOL( const std::string &text ); + + typedef std::vector ChildValues; + + ChildValues childValues_; + std::ostream* document_; + std::string indentString_; + int rightMargin_; + std::string indentation_; + bool addChildValues_; + }; + + std::string JSON_API valueToString( Int value ); + std::string JSON_API valueToString( UInt value ); + std::string JSON_API valueToString( double value ); + std::string JSON_API valueToString( bool value ); + std::string JSON_API valueToQuotedString( const char *value ); + + /// \brief Output using the StyledStreamWriter. + /// \see Json::operator>>() + std::ostream& operator<<( std::ostream&, const Value &root ); + +} // namespace Json + + + +#endif // JSON_WRITER_H_INCLUDED diff --git a/tools/polly/lib/JSON/json_batchallocator.h b/tools/polly/lib/JSON/json_batchallocator.h new file mode 100644 index 00000000000..87ea5ed8078 --- /dev/null +++ b/tools/polly/lib/JSON/json_batchallocator.h @@ -0,0 +1,125 @@ +#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED +# define JSONCPP_BATCHALLOCATOR_H_INCLUDED + +# include +# include + +# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION + +namespace Json { + +/* Fast memory allocator. + * + * This memory allocator allocates memory for a batch of object (specified by + * the page size, the number of object in each page). + * + * It does not allow the destruction of a single object. All the allocated objects + * can be destroyed at once. The memory can be either released or reused for future + * allocation. + * + * The in-place new operator must be used to construct the object using the pointer + * returned by allocate. + */ +template +class BatchAllocator +{ +public: + typedef AllocatedType Type; + + BatchAllocator( unsigned int objectsPerPage = 255 ) + : freeHead_( 0 ) + , objectsPerPage_( objectsPerPage ) + { +// printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() ); + assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space. + assert( objectsPerPage >= 16 ); + batches_ = allocateBatch( 0 ); // allocated a dummy page + currentBatch_ = batches_; + } + + ~BatchAllocator() + { + for ( BatchInfo *batch = batches_; batch; ) + { + BatchInfo *nextBatch = batch->next_; + free( batch ); + batch = nextBatch; + } + } + + /// allocate space for an array of objectPerAllocation object. + /// @warning it is the responsability of the caller to call objects constructors. + AllocatedType *allocate() + { + if ( freeHead_ ) // returns node from free list. + { + AllocatedType *object = freeHead_; + freeHead_ = *(AllocatedType **)object; + return object; + } + if ( currentBatch_->used_ == currentBatch_->end_ ) + { + currentBatch_ = currentBatch_->next_; + while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ ) + currentBatch_ = currentBatch_->next_; + + if ( !currentBatch_ ) // no free batch found, allocate a new one + { + currentBatch_ = allocateBatch( objectsPerPage_ ); + currentBatch_->next_ = batches_; // insert at the head of the list + batches_ = currentBatch_; + } + } + AllocatedType *allocated = currentBatch_->used_; + currentBatch_->used_ += objectPerAllocation; + return allocated; + } + + /// Release the object. + /// @warning it is the responsability of the caller to actually destruct the object. + void release( AllocatedType *object ) + { + assert( object != 0 ); + *(AllocatedType **)object = freeHead_; + freeHead_ = object; + } + +private: + struct BatchInfo + { + BatchInfo *next_; + AllocatedType *used_; + AllocatedType *end_; + AllocatedType buffer_[objectPerAllocation]; + }; + + // disabled copy constructor and assignement operator. + BatchAllocator( const BatchAllocator & ); + void operator =( const BatchAllocator &); + + static BatchInfo *allocateBatch( unsigned int objectsPerPage ) + { + const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation + + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage; + BatchInfo *batch = static_cast( malloc( mallocSize ) ); + batch->next_ = 0; + batch->used_ = batch->buffer_; + batch->end_ = batch->buffer_ + objectsPerPage; + return batch; + } + + BatchInfo *batches_; + BatchInfo *currentBatch_; + /// Head of a single linked list within the allocated space of freeed object + AllocatedType *freeHead_; + unsigned int objectsPerPage_; +}; + + +} // namespace Json + +# endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION + +#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED + diff --git a/tools/polly/lib/JSON/json_internalarray.inl b/tools/polly/lib/JSON/json_internalarray.inl new file mode 100644 index 00000000000..9b985d2585f --- /dev/null +++ b/tools/polly/lib/JSON/json_internalarray.inl @@ -0,0 +1,448 @@ +// included by json_value.cpp +// everything is within Json namespace + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueInternalArray +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueArrayAllocator::~ValueArrayAllocator() +{ +} + +// ////////////////////////////////////////////////////////////////// +// class DefaultValueArrayAllocator +// ////////////////////////////////////////////////////////////////// +#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +class DefaultValueArrayAllocator : public ValueArrayAllocator +{ +public: // overridden from ValueArrayAllocator + virtual ~DefaultValueArrayAllocator() + { + } + + virtual ValueInternalArray *newArray() + { + return new ValueInternalArray(); + } + + virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) + { + return new ValueInternalArray( other ); + } + + virtual void destructArray( ValueInternalArray *array ) + { + delete array; + } + + virtual void reallocateArrayPageIndex( Value **&indexes, + ValueInternalArray::PageIndex &indexCount, + ValueInternalArray::PageIndex minNewIndexCount ) + { + ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; + if ( minNewIndexCount > newIndexCount ) + newIndexCount = minNewIndexCount; + void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); + if ( !newIndexes ) + throw std::bad_alloc(); + indexCount = newIndexCount; + indexes = static_cast( newIndexes ); + } + virtual void releaseArrayPageIndex( Value **indexes, + ValueInternalArray::PageIndex indexCount ) + { + if ( indexes ) + free( indexes ); + } + + virtual Value *allocateArrayPage() + { + return static_cast( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) ); + } + + virtual void releaseArrayPage( Value *value ) + { + if ( value ) + free( value ); + } +}; + +#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +/// @todo make this thread-safe (lock when accessign batch allocator) +class DefaultValueArrayAllocator : public ValueArrayAllocator +{ +public: // overridden from ValueArrayAllocator + virtual ~DefaultValueArrayAllocator() + { + } + + virtual ValueInternalArray *newArray() + { + ValueInternalArray *array = arraysAllocator_.allocate(); + new (array) ValueInternalArray(); // placement new + return array; + } + + virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) + { + ValueInternalArray *array = arraysAllocator_.allocate(); + new (array) ValueInternalArray( other ); // placement new + return array; + } + + virtual void destructArray( ValueInternalArray *array ) + { + if ( array ) + { + array->~ValueInternalArray(); + arraysAllocator_.release( array ); + } + } + + virtual void reallocateArrayPageIndex( Value **&indexes, + ValueInternalArray::PageIndex &indexCount, + ValueInternalArray::PageIndex minNewIndexCount ) + { + ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; + if ( minNewIndexCount > newIndexCount ) + newIndexCount = minNewIndexCount; + void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); + if ( !newIndexes ) + throw std::bad_alloc(); + indexCount = newIndexCount; + indexes = static_cast( newIndexes ); + } + virtual void releaseArrayPageIndex( Value **indexes, + ValueInternalArray::PageIndex indexCount ) + { + if ( indexes ) + free( indexes ); + } + + virtual Value *allocateArrayPage() + { + return static_cast( pagesAllocator_.allocate() ); + } + + virtual void releaseArrayPage( Value *value ) + { + if ( value ) + pagesAllocator_.release( value ); + } +private: + BatchAllocator arraysAllocator_; + BatchAllocator pagesAllocator_; +}; +#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR + +static ValueArrayAllocator *&arrayAllocator() +{ + static DefaultValueArrayAllocator defaultAllocator; + static ValueArrayAllocator *arrayAllocator = &defaultAllocator; + return arrayAllocator; +} + +static struct DummyArrayAllocatorInitializer { + DummyArrayAllocatorInitializer() + { + arrayAllocator(); // ensure arrayAllocator() statics are initialized before main(). + } +} dummyArrayAllocatorInitializer; + +// ////////////////////////////////////////////////////////////////// +// class ValueInternalArray +// ////////////////////////////////////////////////////////////////// +bool +ValueInternalArray::equals( const IteratorState &x, + const IteratorState &other ) +{ + return x.array_ == other.array_ + && x.currentItemIndex_ == other.currentItemIndex_ + && x.currentPageIndex_ == other.currentPageIndex_; +} + + +void +ValueInternalArray::increment( IteratorState &it ) +{ + JSON_ASSERT_MESSAGE( it.array_ && + (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ + != it.array_->size_, + "ValueInternalArray::increment(): moving iterator beyond end" ); + ++(it.currentItemIndex_); + if ( it.currentItemIndex_ == itemsPerPage ) + { + it.currentItemIndex_ = 0; + ++(it.currentPageIndex_); + } +} + + +void +ValueInternalArray::decrement( IteratorState &it ) +{ + JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_ + && it.currentItemIndex_ == 0, + "ValueInternalArray::decrement(): moving iterator beyond end" ); + if ( it.currentItemIndex_ == 0 ) + { + it.currentItemIndex_ = itemsPerPage-1; + --(it.currentPageIndex_); + } + else + { + --(it.currentItemIndex_); + } +} + + +Value & +ValueInternalArray::unsafeDereference( const IteratorState &it ) +{ + return (*(it.currentPageIndex_))[it.currentItemIndex_]; +} + + +Value & +ValueInternalArray::dereference( const IteratorState &it ) +{ + JSON_ASSERT_MESSAGE( it.array_ && + (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ + < it.array_->size_, + "ValueInternalArray::dereference(): dereferencing invalid iterator" ); + return unsafeDereference( it ); +} + +void +ValueInternalArray::makeBeginIterator( IteratorState &it ) const +{ + it.array_ = const_cast( this ); + it.currentItemIndex_ = 0; + it.currentPageIndex_ = pages_; +} + + +void +ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const +{ + it.array_ = const_cast( this ); + it.currentItemIndex_ = index % itemsPerPage; + it.currentPageIndex_ = pages_ + index / itemsPerPage; +} + + +void +ValueInternalArray::makeEndIterator( IteratorState &it ) const +{ + makeIterator( it, size_ ); +} + + +ValueInternalArray::ValueInternalArray() + : pages_( 0 ) + , size_( 0 ) + , pageCount_( 0 ) +{ +} + + +ValueInternalArray::ValueInternalArray( const ValueInternalArray &other ) + : pages_( 0 ) + , pageCount_( 0 ) + , size_( other.size_ ) +{ + PageIndex minNewPages = other.size_ / itemsPerPage; + arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); + JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, + "ValueInternalArray::reserve(): bad reallocation" ); + IteratorState itOther; + other.makeBeginIterator( itOther ); + Value *value; + for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) ) + { + if ( index % itemsPerPage == 0 ) + { + PageIndex pageIndex = index / itemsPerPage; + value = arrayAllocator()->allocateArrayPage(); + pages_[pageIndex] = value; + } + new (value) Value( dereference( itOther ) ); + } +} + + +ValueInternalArray & +ValueInternalArray::operator =( const ValueInternalArray &other ) +{ + ValueInternalArray temp( other ); + swap( temp ); + return *this; +} + + +ValueInternalArray::~ValueInternalArray() +{ + // destroy all constructed items + IteratorState it; + IteratorState itEnd; + makeBeginIterator( it); + makeEndIterator( itEnd ); + for ( ; !equals(it,itEnd); increment(it) ) + { + Value *value = &dereference(it); + value->~Value(); + } + // release all pages + PageIndex lastPageIndex = size_ / itemsPerPage; + for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex ) + arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); + // release pages index + arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ ); +} + + +void +ValueInternalArray::swap( ValueInternalArray &other ) +{ + Value **tempPages = pages_; + pages_ = other.pages_; + other.pages_ = tempPages; + ArrayIndex tempSize = size_; + size_ = other.size_; + other.size_ = tempSize; + PageIndex tempPageCount = pageCount_; + pageCount_ = other.pageCount_; + other.pageCount_ = tempPageCount; +} + +void +ValueInternalArray::clear() +{ + ValueInternalArray dummy; + swap( dummy ); +} + + +void +ValueInternalArray::resize( ArrayIndex newSize ) +{ + if ( newSize == 0 ) + clear(); + else if ( newSize < size_ ) + { + IteratorState it; + IteratorState itEnd; + makeIterator( it, newSize ); + makeIterator( itEnd, size_ ); + for ( ; !equals(it,itEnd); increment(it) ) + { + Value *value = &dereference(it); + value->~Value(); + } + PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage; + PageIndex lastPageIndex = size_ / itemsPerPage; + for ( ; pageIndex < lastPageIndex; ++pageIndex ) + arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); + size_ = newSize; + } + else if ( newSize > size_ ) + resolveReference( newSize ); +} + + +void +ValueInternalArray::makeIndexValid( ArrayIndex index ) +{ + // Need to enlarge page index ? + if ( index >= pageCount_ * itemsPerPage ) + { + PageIndex minNewPages = (index + 1) / itemsPerPage; + arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); + JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" ); + } + + // Need to allocate new pages ? + ArrayIndex nextPageIndex = + (size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage + : size_; + if ( nextPageIndex <= index ) + { + PageIndex pageIndex = nextPageIndex / itemsPerPage; + PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1; + for ( ; pageToAllocate-- > 0; ++pageIndex ) + pages_[pageIndex] = arrayAllocator()->allocateArrayPage(); + } + + // Initialize all new entries + IteratorState it; + IteratorState itEnd; + makeIterator( it, size_ ); + size_ = index + 1; + makeIterator( itEnd, size_ ); + for ( ; !equals(it,itEnd); increment(it) ) + { + Value *value = &dereference(it); + new (value) Value(); // Construct a default value using placement new + } +} + +Value & +ValueInternalArray::resolveReference( ArrayIndex index ) +{ + if ( index >= size_ ) + makeIndexValid( index ); + return pages_[index/itemsPerPage][index%itemsPerPage]; +} + +Value * +ValueInternalArray::find( ArrayIndex index ) const +{ + if ( index >= size_ ) + return 0; + return &(pages_[index/itemsPerPage][index%itemsPerPage]); +} + +ValueInternalArray::ArrayIndex +ValueInternalArray::size() const +{ + return size_; +} + +int +ValueInternalArray::distance( const IteratorState &x, const IteratorState &y ) +{ + return indexOf(y) - indexOf(x); +} + + +ValueInternalArray::ArrayIndex +ValueInternalArray::indexOf( const IteratorState &iterator ) +{ + if ( !iterator.array_ ) + return ArrayIndex(-1); + return ArrayIndex( + (iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage + + iterator.currentItemIndex_ ); +} + + +int +ValueInternalArray::compare( const ValueInternalArray &other ) const +{ + int sizeDiff( size_ - other.size_ ); + if ( sizeDiff != 0 ) + return sizeDiff; + + for ( ArrayIndex index =0; index < size_; ++index ) + { + int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare( + other.pages_[index/itemsPerPage][index%itemsPerPage] ); + if ( diff != 0 ) + return diff; + } + return 0; +} diff --git a/tools/polly/lib/JSON/json_internalmap.inl b/tools/polly/lib/JSON/json_internalmap.inl new file mode 100644 index 00000000000..19771488d6b --- /dev/null +++ b/tools/polly/lib/JSON/json_internalmap.inl @@ -0,0 +1,607 @@ +// included by json_value.cpp +// everything is within Json namespace + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueInternalMap +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +/** \internal MUST be safely initialized using memset( this, 0, sizeof(ValueInternalLink) ); + * This optimization is used by the fast allocator. + */ +ValueInternalLink::ValueInternalLink() + : previous_( 0 ) + , next_( 0 ) +{ +} + +ValueInternalLink::~ValueInternalLink() +{ + for ( int index =0; index < itemPerLink; ++index ) + { + if ( !items_[index].isItemAvailable() ) + { + if ( !items_[index].isMemberNameStatic() ) + free( keys_[index] ); + } + else + break; + } +} + + + +ValueMapAllocator::~ValueMapAllocator() +{ +} + +#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +class DefaultValueMapAllocator : public ValueMapAllocator +{ +public: // overridden from ValueMapAllocator + virtual ValueInternalMap *newMap() + { + return new ValueInternalMap(); + } + + virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) + { + return new ValueInternalMap( other ); + } + + virtual void destructMap( ValueInternalMap *map ) + { + delete map; + } + + virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) + { + return new ValueInternalLink[size]; + } + + virtual void releaseMapBuckets( ValueInternalLink *links ) + { + delete [] links; + } + + virtual ValueInternalLink *allocateMapLink() + { + return new ValueInternalLink(); + } + + virtual void releaseMapLink( ValueInternalLink *link ) + { + delete link; + } +}; +#else +/// @todo make this thread-safe (lock when accessign batch allocator) +class DefaultValueMapAllocator : public ValueMapAllocator +{ +public: // overridden from ValueMapAllocator + virtual ValueInternalMap *newMap() + { + ValueInternalMap *map = mapsAllocator_.allocate(); + new (map) ValueInternalMap(); // placement new + return map; + } + + virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) + { + ValueInternalMap *map = mapsAllocator_.allocate(); + new (map) ValueInternalMap( other ); // placement new + return map; + } + + virtual void destructMap( ValueInternalMap *map ) + { + if ( map ) + { + map->~ValueInternalMap(); + mapsAllocator_.release( map ); + } + } + + virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) + { + return new ValueInternalLink[size]; + } + + virtual void releaseMapBuckets( ValueInternalLink *links ) + { + delete [] links; + } + + virtual ValueInternalLink *allocateMapLink() + { + ValueInternalLink *link = linksAllocator_.allocate(); + memset( link, 0, sizeof(ValueInternalLink) ); + return link; + } + + virtual void releaseMapLink( ValueInternalLink *link ) + { + link->~ValueInternalLink(); + linksAllocator_.release( link ); + } +private: + BatchAllocator mapsAllocator_; + BatchAllocator linksAllocator_; +}; +#endif + +static ValueMapAllocator *&mapAllocator() +{ + static DefaultValueMapAllocator defaultAllocator; + static ValueMapAllocator *mapAllocator = &defaultAllocator; + return mapAllocator; +} + +static struct DummyMapAllocatorInitializer { + DummyMapAllocatorInitializer() + { + mapAllocator(); // ensure mapAllocator() statics are initialized before main(). + } +} dummyMapAllocatorInitializer; + + + +// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32. + +/* +use linked list hash map. +buckets array is a container. +linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124) +value have extra state: valid, available, deleted +*/ + + +ValueInternalMap::ValueInternalMap() + : buckets_( 0 ) + , tailLink_( 0 ) + , bucketsSize_( 0 ) + , itemCount_( 0 ) +{ +} + + +ValueInternalMap::ValueInternalMap( const ValueInternalMap &other ) + : buckets_( 0 ) + , tailLink_( 0 ) + , bucketsSize_( 0 ) + , itemCount_( 0 ) +{ + reserve( other.itemCount_ ); + IteratorState it; + IteratorState itEnd; + other.makeBeginIterator( it ); + other.makeEndIterator( itEnd ); + for ( ; !equals(it,itEnd); increment(it) ) + { + bool isStatic; + const char *memberName = key( it, isStatic ); + const Value &aValue = value( it ); + resolveReference(memberName, isStatic) = aValue; + } +} + + +ValueInternalMap & +ValueInternalMap::operator =( const ValueInternalMap &other ) +{ + ValueInternalMap dummy( other ); + swap( dummy ); + return *this; +} + + +ValueInternalMap::~ValueInternalMap() +{ + if ( buckets_ ) + { + for ( BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex ) + { + ValueInternalLink *link = buckets_[bucketIndex].next_; + while ( link ) + { + ValueInternalLink *linkToRelease = link; + link = link->next_; + mapAllocator()->releaseMapLink( linkToRelease ); + } + } + mapAllocator()->releaseMapBuckets( buckets_ ); + } +} + + +void +ValueInternalMap::swap( ValueInternalMap &other ) +{ + ValueInternalLink *tempBuckets = buckets_; + buckets_ = other.buckets_; + other.buckets_ = tempBuckets; + ValueInternalLink *tempTailLink = tailLink_; + tailLink_ = other.tailLink_; + other.tailLink_ = tempTailLink; + BucketIndex tempBucketsSize = bucketsSize_; + bucketsSize_ = other.bucketsSize_; + other.bucketsSize_ = tempBucketsSize; + BucketIndex tempItemCount = itemCount_; + itemCount_ = other.itemCount_; + other.itemCount_ = tempItemCount; +} + + +void +ValueInternalMap::clear() +{ + ValueInternalMap dummy; + swap( dummy ); +} + + +ValueInternalMap::BucketIndex +ValueInternalMap::size() const +{ + return itemCount_; +} + +bool +ValueInternalMap::reserveDelta( BucketIndex growth ) +{ + return reserve( itemCount_ + growth ); +} + +bool +ValueInternalMap::reserve( BucketIndex newItemCount ) +{ + if ( !buckets_ && newItemCount > 0 ) + { + buckets_ = mapAllocator()->allocateMapBuckets( 1 ); + bucketsSize_ = 1; + tailLink_ = &buckets_[0]; + } +// BucketIndex idealBucketCount = (newItemCount + ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink; + return true; +} + + +const Value * +ValueInternalMap::find( const char *key ) const +{ + if ( !bucketsSize_ ) + return 0; + HashKey hashedKey = hash( key ); + BucketIndex bucketIndex = hashedKey % bucketsSize_; + for ( const ValueInternalLink *current = &buckets_[bucketIndex]; + current != 0; + current = current->next_ ) + { + for ( BucketIndex index=0; index < ValueInternalLink::itemPerLink; ++index ) + { + if ( current->items_[index].isItemAvailable() ) + return 0; + if ( strcmp( key, current->keys_[index] ) == 0 ) + return ¤t->items_[index]; + } + } + return 0; +} + + +Value * +ValueInternalMap::find( const char *key ) +{ + const ValueInternalMap *constThis = this; + return const_cast( constThis->find( key ) ); +} + + +Value & +ValueInternalMap::resolveReference( const char *key, + bool isStatic ) +{ + HashKey hashedKey = hash( key ); + if ( bucketsSize_ ) + { + BucketIndex bucketIndex = hashedKey % bucketsSize_; + ValueInternalLink **previous = 0; + BucketIndex index; + for ( ValueInternalLink *current = &buckets_[bucketIndex]; + current != 0; + previous = ¤t->next_, current = current->next_ ) + { + for ( index=0; index < ValueInternalLink::itemPerLink; ++index ) + { + if ( current->items_[index].isItemAvailable() ) + return setNewItem( key, isStatic, current, index ); + if ( strcmp( key, current->keys_[index] ) == 0 ) + return current->items_[index]; + } + } + } + + reserveDelta( 1 ); + return unsafeAdd( key, isStatic, hashedKey ); +} + + +void +ValueInternalMap::remove( const char *key ) +{ + HashKey hashedKey = hash( key ); + if ( !bucketsSize_ ) + return; + BucketIndex bucketIndex = hashedKey % bucketsSize_; + for ( ValueInternalLink *link = &buckets_[bucketIndex]; + link != 0; + link = link->next_ ) + { + BucketIndex index; + for ( index =0; index < ValueInternalLink::itemPerLink; ++index ) + { + if ( link->items_[index].isItemAvailable() ) + return; + if ( strcmp( key, link->keys_[index] ) == 0 ) + { + doActualRemove( link, index, bucketIndex ); + return; + } + } + } +} + +void +ValueInternalMap::doActualRemove( ValueInternalLink *link, + BucketIndex index, + BucketIndex bucketIndex ) +{ + // find last item of the bucket and swap it with the 'removed' one. + // set removed items flags to 'available'. + // if last page only contains 'available' items, then desallocate it (it's empty) + ValueInternalLink *&lastLink = getLastLinkInBucket( index ); + BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1 + for ( ; + lastItemIndex < ValueInternalLink::itemPerLink; + ++lastItemIndex ) // may be optimized with dicotomic search + { + if ( lastLink->items_[lastItemIndex].isItemAvailable() ) + break; + } + + BucketIndex lastUsedIndex = lastItemIndex - 1; + Value *valueToDelete = &link->items_[index]; + Value *valueToPreserve = &lastLink->items_[lastUsedIndex]; + if ( valueToDelete != valueToPreserve ) + valueToDelete->swap( *valueToPreserve ); + if ( lastUsedIndex == 0 ) // page is now empty + { // remove it from bucket linked list and delete it. + ValueInternalLink *linkPreviousToLast = lastLink->previous_; + if ( linkPreviousToLast != 0 ) // can not deleted bucket link. + { + mapAllocator()->releaseMapLink( lastLink ); + linkPreviousToLast->next_ = 0; + lastLink = linkPreviousToLast; + } + } + else + { + Value dummy; + valueToPreserve->swap( dummy ); // restore deleted to default Value. + valueToPreserve->setItemUsed( false ); + } + --itemCount_; +} + + +ValueInternalLink *& +ValueInternalMap::getLastLinkInBucket( BucketIndex bucketIndex ) +{ + if ( bucketIndex == bucketsSize_ - 1 ) + return tailLink_; + ValueInternalLink *&previous = buckets_[bucketIndex+1].previous_; + if ( !previous ) + previous = &buckets_[bucketIndex]; + return previous; +} + + +Value & +ValueInternalMap::setNewItem( const char *key, + bool isStatic, + ValueInternalLink *link, + BucketIndex index ) +{ + char *duplicatedKey = valueAllocator()->makeMemberName( key ); + ++itemCount_; + link->keys_[index] = duplicatedKey; + link->items_[index].setItemUsed(); + link->items_[index].setMemberNameIsStatic( isStatic ); + return link->items_[index]; // items already default constructed. +} + + +Value & +ValueInternalMap::unsafeAdd( const char *key, + bool isStatic, + HashKey hashedKey ) +{ + JSON_ASSERT_MESSAGE( bucketsSize_ > 0, "ValueInternalMap::unsafeAdd(): internal logic error." ); + BucketIndex bucketIndex = hashedKey % bucketsSize_; + ValueInternalLink *&previousLink = getLastLinkInBucket( bucketIndex ); + ValueInternalLink *link = previousLink; + BucketIndex index; + for ( index =0; index < ValueInternalLink::itemPerLink; ++index ) + { + if ( link->items_[index].isItemAvailable() ) + break; + } + if ( index == ValueInternalLink::itemPerLink ) // need to add a new page + { + ValueInternalLink *newLink = mapAllocator()->allocateMapLink(); + index = 0; + link->next_ = newLink; + previousLink = newLink; + link = newLink; + } + return setNewItem( key, isStatic, link, index ); +} + + +ValueInternalMap::HashKey +ValueInternalMap::hash( const char *key ) const +{ + HashKey hash = 0; + while ( *key ) + hash += *key++ * 37; + return hash; +} + + +int +ValueInternalMap::compare( const ValueInternalMap &other ) const +{ + int sizeDiff( itemCount_ - other.itemCount_ ); + if ( sizeDiff != 0 ) + return sizeDiff; + // Strict order guaranty is required. Compare all keys FIRST, then compare values. + IteratorState it; + IteratorState itEnd; + makeBeginIterator( it ); + makeEndIterator( itEnd ); + for ( ; !equals(it,itEnd); increment(it) ) + { + if ( !other.find( key( it ) ) ) + return 1; + } + + // All keys are equals, let's compare values + makeBeginIterator( it ); + for ( ; !equals(it,itEnd); increment(it) ) + { + const Value *otherValue = other.find( key( it ) ); + int valueDiff = value(it).compare( *otherValue ); + if ( valueDiff != 0 ) + return valueDiff; + } + return 0; +} + + +void +ValueInternalMap::makeBeginIterator( IteratorState &it ) const +{ + it.map_ = const_cast( this ); + it.bucketIndex_ = 0; + it.itemIndex_ = 0; + it.link_ = buckets_; +} + + +void +ValueInternalMap::makeEndIterator( IteratorState &it ) const +{ + it.map_ = const_cast( this ); + it.bucketIndex_ = bucketsSize_; + it.itemIndex_ = 0; + it.link_ = 0; +} + + +bool +ValueInternalMap::equals( const IteratorState &x, const IteratorState &other ) +{ + return x.map_ == other.map_ + && x.bucketIndex_ == other.bucketIndex_ + && x.link_ == other.link_ + && x.itemIndex_ == other.itemIndex_; +} + + +void +ValueInternalMap::incrementBucket( IteratorState &iterator ) +{ + ++iterator.bucketIndex_; + JSON_ASSERT_MESSAGE( iterator.bucketIndex_ <= iterator.map_->bucketsSize_, + "ValueInternalMap::increment(): attempting to iterate beyond end." ); + if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ ) + iterator.link_ = 0; + else + iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]); + iterator.itemIndex_ = 0; +} + + +void +ValueInternalMap::increment( IteratorState &iterator ) +{ + JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterator using invalid iterator." ); + ++iterator.itemIndex_; + if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink ) + { + JSON_ASSERT_MESSAGE( iterator.link_ != 0, + "ValueInternalMap::increment(): attempting to iterate beyond end." ); + iterator.link_ = iterator.link_->next_; + if ( iterator.link_ == 0 ) + incrementBucket( iterator ); + } + else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() ) + { + incrementBucket( iterator ); + } +} + + +void +ValueInternalMap::decrement( IteratorState &iterator ) +{ + if ( iterator.itemIndex_ == 0 ) + { + JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterate using invalid iterator." ); + if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] ) + { + JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0, "Attempting to iterate beyond beginning." ); + --(iterator.bucketIndex_); + } + iterator.link_ = iterator.link_->previous_; + iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1; + } +} + + +const char * +ValueInternalMap::key( const IteratorState &iterator ) +{ + JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." ); + return iterator.link_->keys_[iterator.itemIndex_]; +} + +const char * +ValueInternalMap::key( const IteratorState &iterator, bool &isStatic ) +{ + JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." ); + isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic(); + return iterator.link_->keys_[iterator.itemIndex_]; +} + + +Value & +ValueInternalMap::value( const IteratorState &iterator ) +{ + JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." ); + return iterator.link_->items_[iterator.itemIndex_]; +} + + +int +ValueInternalMap::distance( const IteratorState &x, const IteratorState &y ) +{ + int offset = 0; + IteratorState it = x; + while ( !equals( it, y ) ) + increment( it ); + return offset; +} diff --git a/tools/polly/lib/JSON/json_reader.cpp b/tools/polly/lib/JSON/json_reader.cpp new file mode 100644 index 00000000000..680c2b6b26b --- /dev/null +++ b/tools/polly/lib/JSON/json_reader.cpp @@ -0,0 +1,890 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#if _MSC_VER >= 1400 // VC++ 8.0 +#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. +#endif + +namespace Json { + +// Implementation of class Features +// //////////////////////////////// + +Features::Features() + : allowComments_( true ) + , strictRoot_( false ) +{ +} + + +Features +Features::all() +{ + return Features(); +} + + +Features +Features::strictMode() +{ + Features features; + features.allowComments_ = false; + features.strictRoot_ = true; + return features; +} + +// Implementation of class Reader +// //////////////////////////////// + + +static inline bool +in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4 ) +{ + return c == c1 || c == c2 || c == c3 || c == c4; +} + +static inline bool +in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4, Reader::Char c5 ) +{ + return c == c1 || c == c2 || c == c3 || c == c4 || c == c5; +} + + +static bool +containsNewLine( Reader::Location begin, + Reader::Location end ) +{ + for ( ;begin < end; ++begin ) + if ( *begin == '\n' || *begin == '\r' ) + return true; + return false; +} + +static std::string codePointToUTF8(unsigned int cp) +{ + std::string result; + + // based on description from http://en.wikipedia.org/wiki/UTF-8 + + if (cp <= 0x7f) + { + result.resize(1); + result[0] = static_cast(cp); + } + else if (cp <= 0x7FF) + { + result.resize(2); + result[1] = static_cast(0x80 | (0x3f & cp)); + result[0] = static_cast(0xC0 | (0x1f & (cp >> 6))); + } + else if (cp <= 0xFFFF) + { + result.resize(3); + result[2] = static_cast(0x80 | (0x3f & cp)); + result[1] = 0x80 | static_cast((0x3f & (cp >> 6))); + result[0] = 0xE0 | static_cast((0xf & (cp >> 12))); + } + else if (cp <= 0x10FFFF) + { + result.resize(4); + result[3] = static_cast(0x80 | (0x3f & cp)); + result[2] = static_cast(0x80 | (0x3f & (cp >> 6))); + result[1] = static_cast(0x80 | (0x3f & (cp >> 12))); + result[0] = static_cast(0xF0 | (0x7 & (cp >> 18))); + } + + return result; +} + + +// Class Reader +// ////////////////////////////////////////////////////////////////// + +Reader::Reader() + : features_( Features::all() ) +{ +} + + +Reader::Reader( const Features &features ) + : features_( features ) +{ +} + + +bool +Reader::parse( const std::string &document, + Value &root, + bool collectComments ) +{ + document_ = document; + const char *begin = document_.c_str(); + const char *end = begin + document_.length(); + return parse( begin, end, root, collectComments ); +} + + +bool +Reader::parse( std::istream& sin, + Value &root, + bool collectComments ) +{ + //std::istream_iterator begin(sin); + //std::istream_iterator end; + // Those would allow streamed input from a file, if parse() were a + // template function. + + // Since std::string is reference-counted, this at least does not + // create an extra copy. + std::string doc; + std::getline(sin, doc, (char)EOF); + return parse( doc, root, collectComments ); +} + +bool +Reader::parse( const char *beginDoc, const char *endDoc, + Value &root, + bool collectComments ) +{ + if ( !features_.allowComments_ ) + { + collectComments = false; + } + + begin_ = beginDoc; + end_ = endDoc; + collectComments_ = collectComments; + current_ = begin_; + lastValueEnd_ = 0; + lastValue_ = 0; + commentsBefore_ = ""; + errors_.clear(); + while ( !nodes_.empty() ) + nodes_.pop(); + nodes_.push( &root ); + + bool successful = readValue(); + Token token; + skipCommentTokens( token ); + if ( collectComments_ && !commentsBefore_.empty() ) + root.setComment( commentsBefore_, commentAfter ); + if ( features_.strictRoot_ ) + { + if ( !root.isArray() && !root.isObject() ) + { + // Set error location to start of doc, ideally should be first token found in doc + token.type_ = tokenError; + token.start_ = beginDoc; + token.end_ = endDoc; + addError( "A valid JSON document must be either an array or an object value.", + token ); + return false; + } + } + return successful; +} + + +bool +Reader::readValue() +{ + Token token; + skipCommentTokens( token ); + bool successful = true; + + if ( collectComments_ && !commentsBefore_.empty() ) + { + currentValue().setComment( commentsBefore_, commentBefore ); + commentsBefore_ = ""; + } + + + switch ( token.type_ ) + { + case tokenObjectBegin: + successful = readObject( token ); + break; + case tokenArrayBegin: + successful = readArray( token ); + break; + case tokenNumber: + successful = decodeNumber( token ); + break; + case tokenString: + successful = decodeString( token ); + break; + case tokenTrue: + currentValue() = true; + break; + case tokenFalse: + currentValue() = false; + break; + case tokenNull: + currentValue() = Value(); + break; + default: + return addError( "Syntax error: value, object or array expected.", token ); + } + + if ( collectComments_ ) + { + lastValueEnd_ = current_; + lastValue_ = ¤tValue(); + } + + return successful; +} + + +void +Reader::skipCommentTokens( Token &token ) +{ + if ( features_.allowComments_ ) + { + do + { + readToken( token ); + } + while ( token.type_ == tokenComment ); + } + else + { + readToken( token ); + } +} + + +bool +Reader::expectToken( TokenType type, Token &token, const char *message ) +{ + readToken( token ); + if ( token.type_ != type ) + return addError( message, token ); + return true; +} + + +bool +Reader::readToken( Token &token ) +{ + skipSpaces(); + token.start_ = current_; + Char c = getNextChar(); + bool ok = true; + switch ( c ) + { + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = readString(); + break; + case '/': + token.type_ = tokenComment; + ok = readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + token.type_ = tokenNumber; + readNumber(); + break; + case 't': + token.type_ = tokenTrue; + ok = match( "rue", 3 ); + break; + case 'f': + token.type_ = tokenFalse; + ok = match( "alse", 4 ); + break; + case 'n': + token.type_ = tokenNull; + ok = match( "ull", 3 ); + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; + } + if ( !ok ) + token.type_ = tokenError; + token.end_ = current_; + return true; +} + + +void +Reader::skipSpaces() +{ + while ( current_ != end_ ) + { + Char c = *current_; + if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ) + ++current_; + else + break; + } +} + + +bool +Reader::match( Location pattern, + int patternLength ) +{ + if ( end_ - current_ < patternLength ) + return false; + int index = patternLength; + while ( index-- ) + if ( current_[index] != pattern[index] ) + return false; + current_ += patternLength; + return true; +} + + +bool +Reader::readComment() +{ + Location commentBegin = current_ - 1; + Char c = getNextChar(); + bool successful = false; + if ( c == '*' ) + successful = readCStyleComment(); + else if ( c == '/' ) + successful = readCppStyleComment(); + if ( !successful ) + return false; + + if ( collectComments_ ) + { + CommentPlacement placement = commentBefore; + if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) ) + { + if ( c != '*' || !containsNewLine( commentBegin, current_ ) ) + placement = commentAfterOnSameLine; + } + + addComment( commentBegin, current_, placement ); + } + return true; +} + + +void +Reader::addComment( Location begin, + Location end, + CommentPlacement placement ) +{ + assert( collectComments_ ); + if ( placement == commentAfterOnSameLine ) + { + assert( lastValue_ != 0 ); + lastValue_->setComment( std::string( begin, end ), placement ); + } + else + { + if ( !commentsBefore_.empty() ) + commentsBefore_ += "\n"; + commentsBefore_ += std::string( begin, end ); + } +} + + +bool +Reader::readCStyleComment() +{ + while ( current_ != end_ ) + { + Char c = getNextChar(); + if ( c == '*' && *current_ == '/' ) + break; + } + return getNextChar() == '/'; +} + + +bool +Reader::readCppStyleComment() +{ + while ( current_ != end_ ) + { + Char c = getNextChar(); + if ( c == '\r' || c == '\n' ) + break; + } + return true; +} + + +void +Reader::readNumber() +{ + while ( current_ != end_ ) + { + if ( !(*current_ >= '0' && *current_ <= '9') && + !in( *current_, '.', 'e', 'E', '+', '-' ) ) + break; + ++current_; + } +} + +bool +Reader::readString() +{ + Char c = 0; + while ( current_ != end_ ) + { + c = getNextChar(); + if ( c == '\\' ) + getNextChar(); + else if ( c == '"' ) + break; + } + return c == '"'; +} + + +bool +Reader::readObject( Token &tokenStart ) +{ + Token tokenName; + std::string name; + currentValue() = Value( objectValue ); + while ( readToken( tokenName ) ) + { + bool initialTokenOk = true; + while ( tokenName.type_ == tokenComment && initialTokenOk ) + initialTokenOk = readToken( tokenName ); + if ( !initialTokenOk ) + break; + if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object + return true; + if ( tokenName.type_ != tokenString ) + break; + + name = ""; + if ( !decodeString( tokenName, name ) ) + return recoverFromError( tokenObjectEnd ); + + Token colon; + if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator ) + { + return addErrorAndRecover( "Missing ':' after object member name", + colon, + tokenObjectEnd ); + } + Value &value = currentValue()[ name ]; + nodes_.push( &value ); + bool ok = readValue(); + nodes_.pop(); + if ( !ok ) // error already set + return recoverFromError( tokenObjectEnd ); + + Token comma; + if ( !readToken( comma ) + || ( comma.type_ != tokenObjectEnd && + comma.type_ != tokenArraySeparator && + comma.type_ != tokenComment ) ) + { + return addErrorAndRecover( "Missing ',' or '}' in object declaration", + comma, + tokenObjectEnd ); + } + bool finalizeTokenOk = true; + while ( comma.type_ == tokenComment && + finalizeTokenOk ) + finalizeTokenOk = readToken( comma ); + if ( comma.type_ == tokenObjectEnd ) + return true; + } + return addErrorAndRecover( "Missing '}' or object member name", + tokenName, + tokenObjectEnd ); +} + + +bool +Reader::readArray( Token &tokenStart ) +{ + currentValue() = Value( arrayValue ); + skipSpaces(); + if ( *current_ == ']' ) // empty array + { + Token endArray; + readToken( endArray ); + return true; + } + int index = 0; + while ( true ) + { + Value &value = currentValue()[ index++ ]; + nodes_.push( &value ); + bool ok = readValue(); + nodes_.pop(); + if ( !ok ) // error already set + return recoverFromError( tokenArrayEnd ); + + Token token; + // Accept Comment after last item in the array. + ok = readToken( token ); + while ( token.type_ == tokenComment && ok ) + { + ok = readToken( token ); + } + bool badTokenType = ( token.type_ == tokenArraySeparator && + token.type_ == tokenArrayEnd ); + if ( !ok || badTokenType ) + { + return addErrorAndRecover( "Missing ',' or ']' in array declaration", + token, + tokenArrayEnd ); + } + if ( token.type_ == tokenArrayEnd ) + break; + } + return true; +} + + +bool +Reader::decodeNumber( Token &token ) +{ + bool isDouble = false; + for ( Location inspect = token.start_; inspect != token.end_; ++inspect ) + { + isDouble = isDouble + || in( *inspect, '.', 'e', 'E', '+' ) + || ( *inspect == '-' && inspect != token.start_ ); + } + if ( isDouble ) + return decodeDouble( token ); + Location current = token.start_; + bool isNegative = *current == '-'; + if ( isNegative ) + ++current; + Value::UInt threshold = (isNegative ? Value::UInt(-Value::minInt) + : Value::maxUInt) / 10; + Value::UInt value = 0; + while ( current < token.end_ ) + { + Char c = *current++; + if ( c < '0' || c > '9' ) + return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token ); + if ( value >= threshold ) + return decodeDouble( token ); + value = value * 10 + Value::UInt(c - '0'); + } + if ( isNegative ) + currentValue() = -Value::Int( value ); + else if ( value <= Value::UInt(Value::maxInt) ) + currentValue() = Value::Int( value ); + else + currentValue() = value; + return true; +} + + +bool +Reader::decodeDouble( Token &token ) +{ + double value = 0; + const int bufferSize = 32; + int count; + int length = int(token.end_ - token.start_); + if ( length <= bufferSize ) + { + Char buffer[bufferSize]; + memcpy( buffer, token.start_, length ); + buffer[length] = 0; + count = sscanf( buffer, "%lf", &value ); + } + else + { + std::string buffer( token.start_, token.end_ ); + count = sscanf( buffer.c_str(), "%lf", &value ); + } + + if ( count != 1 ) + return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token ); + currentValue() = value; + return true; +} + + +bool +Reader::decodeString( Token &token ) +{ + std::string decoded; + if ( !decodeString( token, decoded ) ) + return false; + currentValue() = decoded; + return true; +} + + +bool +Reader::decodeString( Token &token, std::string &decoded ) +{ + decoded.reserve( token.end_ - token.start_ - 2 ); + Location current = token.start_ + 1; // skip '"' + Location end = token.end_ - 1; // do not include '"' + while ( current != end ) + { + Char c = *current++; + if ( c == '"' ) + break; + else if ( c == '\\' ) + { + if ( current == end ) + return addError( "Empty escape sequence in string", token, current ); + Char escape = *current++; + switch ( escape ) + { + case '"': decoded += '"'; break; + case '/': decoded += '/'; break; + case '\\': decoded += '\\'; break; + case 'b': decoded += '\b'; break; + case 'f': decoded += '\f'; break; + case 'n': decoded += '\n'; break; + case 'r': decoded += '\r'; break; + case 't': decoded += '\t'; break; + case 'u': + { + unsigned int unicode; + if ( !decodeUnicodeCodePoint( token, current, end, unicode ) ) + return false; + decoded += codePointToUTF8(unicode); + } + break; + default: + return addError( "Bad escape sequence in string", token, current ); + } + } + else + { + decoded += c; + } + } + return true; +} + +bool +Reader::decodeUnicodeCodePoint( Token &token, + Location ¤t, + Location end, + unsigned int &unicode ) +{ + + if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) ) + return false; + if (unicode >= 0xD800 && unicode <= 0xDBFF) + { + // surrogate pairs + if (end - current < 6) + return addError( "additional six characters expected to parse unicode surrogate pair.", token, current ); + unsigned int surrogatePair; + if (*(current++) == '\\' && *(current++)== 'u') + { + if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair )) + { + unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + } + else + return false; + } + else + return addError( "expecting another \\u token to begin the second half of a unicode surrogate pair", token, current ); + } + return true; +} + +bool +Reader::decodeUnicodeEscapeSequence( Token &token, + Location ¤t, + Location end, + unsigned int &unicode ) +{ + if ( end - current < 4 ) + return addError( "Bad unicode escape sequence in string: four digits expected.", token, current ); + unicode = 0; + for ( int index =0; index < 4; ++index ) + { + Char c = *current++; + unicode *= 16; + if ( c >= '0' && c <= '9' ) + unicode += c - '0'; + else if ( c >= 'a' && c <= 'f' ) + unicode += c - 'a' + 10; + else if ( c >= 'A' && c <= 'F' ) + unicode += c - 'A' + 10; + else + return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current ); + } + return true; +} + + +bool +Reader::addError( const std::string &message, + Token &token, + Location extra ) +{ + ErrorInfo info; + info.token_ = token; + info.message_ = message; + info.extra_ = extra; + errors_.push_back( info ); + return false; +} + + +bool +Reader::recoverFromError( TokenType skipUntilToken ) +{ + int errorCount = int(errors_.size()); + Token skip; + while ( true ) + { + if ( !readToken(skip) ) + errors_.resize( errorCount ); // discard errors caused by recovery + if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream ) + break; + } + errors_.resize( errorCount ); + return false; +} + + +bool +Reader::addErrorAndRecover( const std::string &message, + Token &token, + TokenType skipUntilToken ) +{ + addError( message, token ); + return recoverFromError( skipUntilToken ); +} + + +Value & +Reader::currentValue() +{ + return *(nodes_.top()); +} + + +Reader::Char +Reader::getNextChar() +{ + if ( current_ == end_ ) + return 0; + return *current_++; +} + + +void +Reader::getLocationLineAndColumn( Location location, + int &line, + int &column ) const +{ + Location current = begin_; + Location lastLineStart = current; + line = 0; + while ( current < location && current != end_ ) + { + Char c = *current++; + if ( c == '\r' ) + { + if ( *current == '\n' ) + ++current; + lastLineStart = current; + ++line; + } + else if ( c == '\n' ) + { + lastLineStart = current; + ++line; + } + } + // column & line start at 1 + column = int(location - lastLineStart) + 1; + ++line; +} + + +std::string +Reader::getLocationLineAndColumn( Location location ) const +{ + int line, column; + getLocationLineAndColumn( location, line, column ); + char buffer[18+16+16+1]; + sprintf( buffer, "Line %d, Column %d", line, column ); + return buffer; +} + + +std::string +Reader::getFormatedErrorMessages() const +{ + std::string formattedMessage; + for ( Errors::const_iterator itError = errors_.begin(); + itError != errors_.end(); + ++itError ) + { + const ErrorInfo &error = *itError; + formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n"; + formattedMessage += " " + error.message_ + "\n"; + if ( error.extra_ ) + formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n"; + } + return formattedMessage; +} + + +std::istream& operator>>( std::istream &sin, Value &root ) +{ + Json::Reader reader; + bool ok = reader.parse(sin, root, true); + //JSON_ASSERT( ok ); +#if JSON_USE_EXCEPTION + if (!ok) throw std::runtime_error(reader.getFormatedErrorMessages()); +#else + assert(ok && "Bad Format!"); + (void) ok; +#endif + return sin; +} + + +} // namespace Json diff --git a/tools/polly/lib/JSON/json_value.cpp b/tools/polly/lib/JSON/json_value.cpp new file mode 100644 index 00000000000..04e96ea507d --- /dev/null +++ b/tools/polly/lib/JSON/json_value.cpp @@ -0,0 +1,1727 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef JSON_USE_CPPTL +# include +#endif +#include // size_t +#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR +# include "json_batchallocator.h" +#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR + +// Disable warnings. We do not fix these warnings, as this is a file imported +// into Polly and we do not want to diverge from the original source. +#pragma clang diagnostic ignored "-Wcovered-switch-default" + +#define JSON_ASSERT_UNREACHABLE assert( false ) +#define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw +// Do not use throw when exception is disable. +#if JSON_USE_EXCEPTION +# define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message ); +#else +# define JSON_ASSERT_MESSAGE( condition, message ) JSON_ASSERT( condition ) // @todo <= provide the message +#endif + +namespace Json { + +const Value Value::null; +const Int Value::minInt = Int( ~(UInt(-1)/2) ); +const Int Value::maxInt = Int( UInt(-1)/2 ); +const UInt Value::maxUInt = UInt(-1); + +// A "safe" implementation of strdup. Allow null pointer to be passed. +// Also avoid warning on msvc80. +// +//inline char *safeStringDup( const char *czstring ) +//{ +// if ( czstring ) +// { +// const size_t length = (unsigned int)( strlen(czstring) + 1 ); +// char *newString = static_cast( malloc( length ) ); +// memcpy( newString, czstring, length ); +// return newString; +// } +// return 0; +//} +// +//inline char *safeStringDup( const std::string &str ) +//{ +// if ( !str.empty() ) +// { +// const size_t length = str.length(); +// char *newString = static_cast( malloc( length + 1 ) ); +// memcpy( newString, str.c_str(), length ); +// newString[length] = 0; +// return newString; +// } +// return 0; +//} + +ValueAllocator::~ValueAllocator() +{ +} + +class DefaultValueAllocator : public ValueAllocator +{ +public: + virtual ~DefaultValueAllocator() + { + } + + virtual char *makeMemberName( const char *memberName ) + { + return duplicateStringValue( memberName ); + } + + virtual void releaseMemberName( char *memberName ) + { + releaseStringValue( memberName ); + } + + virtual char *duplicateStringValue( const char *value, + unsigned int length = unknown ) + { + //@todo invesgate this old optimization + //if ( !value || value[0] == 0 ) + // return 0; + + if ( length == unknown ) + length = (unsigned int)strlen(value); + char *newString = static_cast( malloc( length + 1 ) ); + memcpy( newString, value, length ); + newString[length] = 0; + return newString; + } + + virtual void releaseStringValue( char *value ) + { + if ( value ) + free( value ); + } +}; + +static ValueAllocator *&valueAllocator() +{ + static DefaultValueAllocator defaultAllocator; + static ValueAllocator *valueAllocator = &defaultAllocator; + return valueAllocator; +} + +static struct DummyValueAllocatorInitializer { + DummyValueAllocatorInitializer() + { + valueAllocator(); // ensure valueAllocator() statics are initialized before main(). + } +} dummyValueAllocatorInitializer; + + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ValueInternals... +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +#ifdef JSON_VALUE_USE_INTERNAL_MAP +# include "json_internalarray.inl" +# include "json_internalmap.inl" +#endif // JSON_VALUE_USE_INTERNAL_MAP + +# include "json_valueiterator.inl" + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::CommentInfo +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + + +Value::CommentInfo::CommentInfo() + : comment_( 0 ) +{ +} + +Value::CommentInfo::~CommentInfo() +{ + if ( comment_ ) + valueAllocator()->releaseStringValue( comment_ ); +} + + +void +Value::CommentInfo::setComment( const char *text ) +{ + if ( comment_ ) + valueAllocator()->releaseStringValue( comment_ ); + JSON_ASSERT( text ); + JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /"); + // It seems that /**/ style comments are acceptable as well. + comment_ = valueAllocator()->duplicateStringValue( text ); +} + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::CZString +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +# ifndef JSON_VALUE_USE_INTERNAL_MAP + +// Notes: index_ indicates if the string was allocated when +// a string is stored. + +Value::CZString::CZString( int index ) + : cstr_( 0 ) + , index_( index ) +{ +} + +Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate ) + : cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr) + : cstr ) + , index_( allocate ) +{ +} + +Value::CZString::CZString( const CZString &other ) +: cstr_( other.index_ != noDuplication && other.cstr_ != 0 + ? valueAllocator()->makeMemberName( other.cstr_ ) + : other.cstr_ ) + , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) + : other.index_ ) +{ +} + +Value::CZString::~CZString() +{ + if ( cstr_ && index_ == duplicate ) + valueAllocator()->releaseMemberName( const_cast( cstr_ ) ); +} + +void +Value::CZString::swap( CZString &other ) +{ + std::swap( cstr_, other.cstr_ ); + std::swap( index_, other.index_ ); +} + +Value::CZString & +Value::CZString::operator =( const CZString &other ) +{ + CZString temp( other ); + swap( temp ); + return *this; +} + +bool +Value::CZString::operator<( const CZString &other ) const +{ + if ( cstr_ ) + return strcmp( cstr_, other.cstr_ ) < 0; + return index_ < other.index_; +} + +bool +Value::CZString::operator==( const CZString &other ) const +{ + if ( cstr_ ) + return strcmp( cstr_, other.cstr_ ) == 0; + return index_ == other.index_; +} + + +int +Value::CZString::index() const +{ + return index_; +} + + +const char * +Value::CZString::c_str() const +{ + return cstr_; +} + +bool +Value::CZString::isStaticString() const +{ + return index_ == noDuplication; +} + +#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class Value::Value +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +/*! \internal Default constructor initialization must be equivalent to: + * memset( this, 0, sizeof(Value) ) + * This optimization is used in ValueInternalMap fast allocator. + */ +Value::Value( ValueType type ) + : type_( type ) + , allocated_( 0 ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + switch ( type ) + { + case nullValue: + break; + case intValue: + case uintValue: + value_.int_ = 0; + break; + case realValue: + value_.real_ = 0.0; + break; + case stringValue: + value_.string_ = 0; + break; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(); + break; +#else + case arrayValue: + value_.array_ = arrayAllocator()->newArray(); + break; + case objectValue: + value_.map_ = mapAllocator()->newMap(); + break; +#endif + case booleanValue: + value_.bool_ = false; + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + + +Value::Value( Int value ) + : type_( intValue ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.int_ = value; +} + + +Value::Value( UInt value ) + : type_( uintValue ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.uint_ = value; +} + +Value::Value( double value ) + : type_( realValue ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.real_ = value; +} + +Value::Value( const char *value ) + : type_( stringValue ) + , allocated_( true ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.string_ = valueAllocator()->duplicateStringValue( value ); +} + + +Value::Value( const char *beginValue, + const char *endValue ) + : type_( stringValue ) + , allocated_( true ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.string_ = valueAllocator()->duplicateStringValue( beginValue, + UInt(endValue - beginValue) ); +} + + +Value::Value( const std::string &value ) + : type_( stringValue ) + , allocated_( true ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(), + (unsigned int)value.length() ); + +} + +Value::Value( const StaticString &value ) + : type_( stringValue ) + , allocated_( false ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.string_ = const_cast( value.c_str() ); +} + + +# ifdef JSON_USE_CPPTL +Value::Value( const CppTL::ConstString &value ) + : type_( stringValue ) + , allocated_( true ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() ); +} +# endif + +Value::Value( bool value ) + : type_( booleanValue ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + value_.bool_ = value; +} + + +Value::Value( const Value &other ) + : type_( other.type_ ) + , comments_( 0 ) +# ifdef JSON_VALUE_USE_INTERNAL_MAP + , itemIsUsed_( 0 ) +#endif +{ + switch ( type_ ) + { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + value_ = other.value_; + break; + case stringValue: + if ( other.value_.string_ ) + { + value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ ); + allocated_ = true; + } + else + value_.string_ = 0; + break; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues( *other.value_.map_ ); + break; +#else + case arrayValue: + value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ ); + break; + case objectValue: + value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ ); + break; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + if ( other.comments_ ) + { + comments_ = new CommentInfo[numberOfCommentPlacement]; + for ( int comment =0; comment < numberOfCommentPlacement; ++comment ) + { + const CommentInfo &otherComment = other.comments_[comment]; + if ( otherComment.comment_ ) + comments_[comment].setComment( otherComment.comment_ ); + } + } +} + + +Value::~Value() +{ + switch ( type_ ) + { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + break; + case stringValue: + if ( allocated_ ) + valueAllocator()->releaseStringValue( value_.string_ ); + break; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + delete value_.map_; + break; +#else + case arrayValue: + arrayAllocator()->destructArray( value_.array_ ); + break; + case objectValue: + mapAllocator()->destructMap( value_.map_ ); + break; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + + if ( comments_ ) + delete[] comments_; +} + +Value & +Value::operator=( const Value &other ) +{ + Value temp( other ); + swap( temp ); + return *this; +} + +void +Value::swap( Value &other ) +{ + ValueType temp = type_; + type_ = other.type_; + other.type_ = temp; + std::swap( value_, other.value_ ); + int temp2 = allocated_; + allocated_ = other.allocated_; + other.allocated_ = temp2; +} + +ValueType +Value::type() const +{ + return type_; +} + + +int +Value::compare( const Value &other ) +{ + /* + int typeDelta = other.type_ - type_; + switch ( type_ ) + { + case nullValue: + + return other.type_ == type_; + case intValue: + if ( other.type_.isNumeric() + case uintValue: + case realValue: + case booleanValue: + break; + case stringValue, + break; + case arrayValue: + delete value_.array_; + break; + case objectValue: + delete value_.map_; + default: + JSON_ASSERT_UNREACHABLE; + } + */ + return 0; // unreachable +} + +bool +Value::operator <( const Value &other ) const +{ + int typeDelta = type_ - other.type_; + if ( typeDelta ) + return typeDelta < 0 ? true : false; + switch ( type_ ) + { + case nullValue: + return false; + case intValue: + return value_.int_ < other.value_.int_; + case uintValue: + return value_.uint_ < other.value_.uint_; + case realValue: + return value_.real_ < other.value_.real_; + case booleanValue: + return value_.bool_ < other.value_.bool_; + case stringValue: + return ( value_.string_ == 0 && other.value_.string_ ) + || ( other.value_.string_ + && value_.string_ + && strcmp( value_.string_, other.value_.string_ ) < 0 ); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + { + int delta = int( value_.map_->size() - other.value_.map_->size() ); + if ( delta ) + return delta < 0; + return (*value_.map_) < (*other.value_.map_); + } +#else + case arrayValue: + return value_.array_->compare( *(other.value_.array_) ) < 0; + case objectValue: + return value_.map_->compare( *(other.value_.map_) ) < 0; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + return 0; // unreachable +} + +bool +Value::operator <=( const Value &other ) const +{ + return !(other > *this); +} + +bool +Value::operator >=( const Value &other ) const +{ + return !(*this < other); +} + +bool +Value::operator >( const Value &other ) const +{ + return other < *this; +} + +bool +Value::operator ==( const Value &other ) const +{ + //if ( type_ != other.type_ ) + // GCC 2.95.3 says: + // attempt to take address of bit-field structure member `Json::Value::type_' + // Beats me, but a temp solves the problem. + int temp = other.type_; + if ( type_ != temp ) + return false; + switch ( type_ ) + { + case nullValue: + return true; + case intValue: + return value_.int_ == other.value_.int_; + case uintValue: + return value_.uint_ == other.value_.uint_; + case realValue: + return value_.real_ == other.value_.real_; + case booleanValue: + return value_.bool_ == other.value_.bool_; + case stringValue: + return ( value_.string_ == other.value_.string_ ) + || ( other.value_.string_ + && value_.string_ + && strcmp( value_.string_, other.value_.string_ ) == 0 ); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + return value_.map_->size() == other.value_.map_->size() + && (*value_.map_) == (*other.value_.map_); +#else + case arrayValue: + return value_.array_->compare( *(other.value_.array_) ) == 0; + case objectValue: + return value_.map_->compare( *(other.value_.map_) ) == 0; +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + return 0; // unreachable +} + +bool +Value::operator !=( const Value &other ) const +{ + return !( *this == other ); +} + +const char * +Value::asCString() const +{ + JSON_ASSERT( type_ == stringValue ); + return value_.string_; +} + + +std::string +Value::asString() const +{ + switch ( type_ ) + { + case nullValue: + return ""; + case stringValue: + return value_.string_ ? value_.string_ : ""; + case booleanValue: + return value_.bool_ ? "true" : "false"; + case intValue: + case uintValue: + case realValue: + case arrayValue: + case objectValue: + JSON_ASSERT_MESSAGE( false, "Type is not convertible to string" ); + default: + JSON_ASSERT_UNREACHABLE; + } + return ""; // unreachable +} + +# ifdef JSON_USE_CPPTL +CppTL::ConstString +Value::asConstString() const +{ + return CppTL::ConstString( asString().c_str() ); +} +# endif + +Value::Int +Value::asInt() const +{ + switch ( type_ ) + { + case nullValue: + return 0; + case intValue: + return value_.int_; + case uintValue: + JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" ); + return value_.uint_; + case realValue: + JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" ); + return Int( value_.real_ ); + case booleanValue: + return value_.bool_ ? 1 : 0; + case stringValue: + case arrayValue: + case objectValue: + JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" ); + default: + JSON_ASSERT_UNREACHABLE; + } + return 0; // unreachable; +} + +Value::UInt +Value::asUInt() const +{ + switch ( type_ ) + { + case nullValue: + return 0; + case intValue: + JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" ); + return value_.int_; + case uintValue: + return value_.uint_; + case realValue: + JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" ); + return UInt( value_.real_ ); + case booleanValue: + return value_.bool_ ? 1 : 0; + case stringValue: + case arrayValue: + case objectValue: + JSON_ASSERT_MESSAGE( false, "Type is not convertible to uint" ); + default: + JSON_ASSERT_UNREACHABLE; + } + return 0; // unreachable; +} + +double +Value::asDouble() const +{ + switch ( type_ ) + { + case nullValue: + return 0.0; + case intValue: + return value_.int_; + case uintValue: + return value_.uint_; + case realValue: + return value_.real_; + case booleanValue: + return value_.bool_ ? 1.0 : 0.0; + case stringValue: + case arrayValue: + case objectValue: + JSON_ASSERT_MESSAGE( false, "Type is not convertible to double" ); + default: + JSON_ASSERT_UNREACHABLE; + } + return 0; // unreachable; +} + +bool +Value::asBool() const +{ + switch ( type_ ) + { + case nullValue: + return false; + case intValue: + case uintValue: + return value_.int_ != 0; + case realValue: + return value_.real_ != 0.0; + case booleanValue: + return value_.bool_; + case stringValue: + return value_.string_ && value_.string_[0] != 0; + case arrayValue: + case objectValue: + return value_.map_->size() != 0; + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable; +} + + +bool +Value::isConvertibleTo( ValueType other ) const +{ + switch ( type_ ) + { + case nullValue: + return true; + case intValue: + return ( other == nullValue && value_.int_ == 0 ) + || other == intValue + || ( other == uintValue && value_.int_ >= 0 ) + || other == realValue + || other == stringValue + || other == booleanValue; + case uintValue: + return ( other == nullValue && value_.uint_ == 0 ) + || ( other == intValue && value_.uint_ <= (unsigned)maxInt ) + || other == uintValue + || other == realValue + || other == stringValue + || other == booleanValue; + case realValue: + return ( other == nullValue && value_.real_ == 0.0 ) + || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt ) + || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt ) + || other == realValue + || other == stringValue + || other == booleanValue; + case booleanValue: + return ( other == nullValue && value_.bool_ == false ) + || other == intValue + || other == uintValue + || other == realValue + || other == stringValue + || other == booleanValue; + case stringValue: + return other == stringValue + || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) ); + case arrayValue: + return other == arrayValue + || ( other == nullValue && value_.map_->size() == 0 ); + case objectValue: + return other == objectValue + || ( other == nullValue && value_.map_->size() == 0 ); + default: + JSON_ASSERT_UNREACHABLE; + } + return false; // unreachable; +} + + +/// Number of values in array or object +Value::UInt +Value::size() const +{ + switch ( type_ ) + { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + case stringValue: + return 0; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: // size of the array is highest index + 1 + if ( !value_.map_->empty() ) + { + ObjectValues::const_iterator itLast = value_.map_->end(); + --itLast; + return (*itLast).first.index()+1; + } + return 0; + case objectValue: + return Int( value_.map_->size() ); +#else + case arrayValue: + return Int( value_.array_->size() ); + case objectValue: + return Int( value_.map_->size() ); +#endif + default: + JSON_ASSERT_UNREACHABLE; + } + return 0; // unreachable; +} + + +bool +Value::empty() const +{ + if ( isNull() || isArray() || isObject() ) + return size() == 0u; + else + return false; +} + + +bool +Value::operator!() const +{ + return isNull(); +} + + +void +Value::clear() +{ + JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue ); + + switch ( type_ ) + { +#ifndef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + case objectValue: + value_.map_->clear(); + break; +#else + case arrayValue: + value_.array_->clear(); + break; + case objectValue: + value_.map_->clear(); + break; +#endif + default: + break; + } +} + +void +Value::resize( UInt newSize ) +{ + JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); + if ( type_ == nullValue ) + *this = Value( arrayValue ); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + UInt oldSize = size(); + if ( newSize == 0 ) + clear(); + else if ( newSize > oldSize ) + (*this)[ newSize - 1 ]; + else + { + for ( UInt index = newSize; index < oldSize; ++index ) + value_.map_->erase( index ); + assert( size() == newSize ); + } +#else + value_.array_->resize( newSize ); +#endif +} + + +Value & +Value::operator[]( UInt index ) +{ + JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); + if ( type_ == nullValue ) + *this = Value( arrayValue ); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString key( index ); + ObjectValues::iterator it = value_.map_->lower_bound( key ); + if ( it != value_.map_->end() && (*it).first == key ) + return (*it).second; + + ObjectValues::value_type defaultValue( key, null ); + it = value_.map_->insert( it, defaultValue ); + return (*it).second; +#else + return value_.array_->resolveReference( index ); +#endif +} + + +const Value & +Value::operator[]( UInt index ) const +{ + JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); + if ( type_ == nullValue ) + return null; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString key( index ); + ObjectValues::const_iterator it = value_.map_->find( key ); + if ( it == value_.map_->end() ) + return null; + return (*it).second; +#else + Value *value = value_.array_->find( index ); + return value ? *value : null; +#endif +} + + +Value & +Value::operator[]( const char *key ) +{ + return resolveReference( key, false ); +} + + +Value & +Value::resolveReference( const char *key, + bool isStatic ) +{ + JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + if ( type_ == nullValue ) + *this = Value( objectValue ); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString actualKey( key, isStatic ? CZString::noDuplication + : CZString::duplicateOnCopy ); + ObjectValues::iterator it = value_.map_->lower_bound( actualKey ); + if ( it != value_.map_->end() && (*it).first == actualKey ) + return (*it).second; + + ObjectValues::value_type defaultValue( actualKey, null ); + it = value_.map_->insert( it, defaultValue ); + Value &value = (*it).second; + return value; +#else + return value_.map_->resolveReference( key, isStatic ); +#endif +} + + +Value +Value::get( UInt index, + const Value &defaultValue ) const +{ + const Value *value = &((*this)[index]); + return value == &null ? defaultValue : *value; +} + + +bool +Value::isValidIndex( UInt index ) const +{ + return index < size(); +} + + + +const Value & +Value::operator[]( const char *key ) const +{ + JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + if ( type_ == nullValue ) + return null; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString actualKey( key, CZString::noDuplication ); + ObjectValues::const_iterator it = value_.map_->find( actualKey ); + if ( it == value_.map_->end() ) + return null; + return (*it).second; +#else + const Value *value = value_.map_->find( key ); + return value ? *value : null; +#endif +} + + +Value & +Value::operator[]( const std::string &key ) +{ + return (*this)[ key.c_str() ]; +} + + +const Value & +Value::operator[]( const std::string &key ) const +{ + return (*this)[ key.c_str() ]; +} + +Value & +Value::operator[]( const StaticString &key ) +{ + return resolveReference( key, true ); +} + + +# ifdef JSON_USE_CPPTL +Value & +Value::operator[]( const CppTL::ConstString &key ) +{ + return (*this)[ key.c_str() ]; +} + + +const Value & +Value::operator[]( const CppTL::ConstString &key ) const +{ + return (*this)[ key.c_str() ]; +} +# endif + + +Value & +Value::append( const Value &value ) +{ + return (*this)[size()] = value; +} + + +Value +Value::get( const char *key, + const Value &defaultValue ) const +{ + const Value *value = &((*this)[key]); + return value == &null ? defaultValue : *value; +} + + +Value +Value::get( const std::string &key, + const Value &defaultValue ) const +{ + return get( key.c_str(), defaultValue ); +} + +Value +Value::removeMember( const char* key ) +{ + JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + if ( type_ == nullValue ) + return null; +#ifndef JSON_VALUE_USE_INTERNAL_MAP + CZString actualKey( key, CZString::noDuplication ); + ObjectValues::iterator it = value_.map_->find( actualKey ); + if ( it == value_.map_->end() ) + return null; + Value old(it->second); + value_.map_->erase(it); + return old; +#else + Value *value = value_.map_->find( key ); + if (value){ + Value old(*value); + value_.map_.remove( key ); + return old; + } else { + return null; + } +#endif +} + +Value +Value::removeMember( const std::string &key ) +{ + return removeMember( key.c_str() ); +} + +# ifdef JSON_USE_CPPTL +Value +Value::get( const CppTL::ConstString &key, + const Value &defaultValue ) const +{ + return get( key.c_str(), defaultValue ); +} +# endif + +bool +Value::isMember( const char *key ) const +{ + const Value *value = &((*this)[key]); + return value != &null; +} + + +bool +Value::isMember( const std::string &key ) const +{ + return isMember( key.c_str() ); +} + + +# ifdef JSON_USE_CPPTL +bool +Value::isMember( const CppTL::ConstString &key ) const +{ + return isMember( key.c_str() ); +} +#endif + +Value::Members +Value::getMemberNames() const +{ + JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + if ( type_ == nullValue ) + return Value::Members(); + Members members; + members.reserve( value_.map_->size() ); +#ifndef JSON_VALUE_USE_INTERNAL_MAP + ObjectValues::const_iterator it = value_.map_->begin(); + ObjectValues::const_iterator itEnd = value_.map_->end(); + for ( ; it != itEnd; ++it ) + members.push_back( std::string( (*it).first.c_str() ) ); +#else + ValueInternalMap::IteratorState it; + ValueInternalMap::IteratorState itEnd; + value_.map_->makeBeginIterator( it ); + value_.map_->makeEndIterator( itEnd ); + for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) ) + members.push_back( std::string( ValueInternalMap::key( it ) ) ); +#endif + return members; +} +// +//# ifdef JSON_USE_CPPTL +//EnumMemberNames +//Value::enumMemberNames() const +//{ +// if ( type_ == objectValue ) +// { +// return CppTL::Enum::any( CppTL::Enum::transform( +// CppTL::Enum::keys( *(value_.map_), CppTL::Type() ), +// MemberNamesTransform() ) ); +// } +// return EnumMemberNames(); +//} +// +// +//EnumValues +//Value::enumValues() const +//{ +// if ( type_ == objectValue || type_ == arrayValue ) +// return CppTL::Enum::anyValues( *(value_.map_), +// CppTL::Type() ); +// return EnumValues(); +//} +// +//# endif + + +bool +Value::isNull() const +{ + return type_ == nullValue; +} + + +bool +Value::isBool() const +{ + return type_ == booleanValue; +} + + +bool +Value::isInt() const +{ + return type_ == intValue; +} + + +bool +Value::isUInt() const +{ + return type_ == uintValue; +} + + +bool +Value::isIntegral() const +{ + return type_ == intValue + || type_ == uintValue + || type_ == booleanValue; +} + + +bool +Value::isDouble() const +{ + return type_ == realValue; +} + + +bool +Value::isNumeric() const +{ + return isIntegral() || isDouble(); +} + + +bool +Value::isString() const +{ + return type_ == stringValue; +} + + +bool +Value::isArray() const +{ + return type_ == nullValue || type_ == arrayValue; +} + + +bool +Value::isObject() const +{ + return type_ == nullValue || type_ == objectValue; +} + + +void +Value::setComment( const char *comment, + CommentPlacement placement ) +{ + if ( !comments_ ) + comments_ = new CommentInfo[numberOfCommentPlacement]; + comments_[placement].setComment( comment ); +} + + +void +Value::setComment( const std::string &comment, + CommentPlacement placement ) +{ + setComment( comment.c_str(), placement ); +} + + +bool +Value::hasComment( CommentPlacement placement ) const +{ + return comments_ != 0 && comments_[placement].comment_ != 0; +} + +std::string +Value::getComment( CommentPlacement placement ) const +{ + if ( hasComment(placement) ) + return comments_[placement].comment_; + return ""; +} + + +std::string +Value::toStyledString() const +{ + StyledWriter writer; + return writer.write( *this ); +} + + +Value::const_iterator +Value::begin() const +{ + switch ( type_ ) + { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if ( value_.array_ ) + { + ValueInternalArray::IteratorState it; + value_.array_->makeBeginIterator( it ); + return const_iterator( it ); + } + break; + case objectValue: + if ( value_.map_ ) + { + ValueInternalMap::IteratorState it; + value_.map_->makeBeginIterator( it ); + return const_iterator( it ); + } + break; +#else + case arrayValue: + case objectValue: + if ( value_.map_ ) + return const_iterator( value_.map_->begin() ); + break; +#endif + default: + break; + } + return const_iterator(); +} + +Value::const_iterator +Value::end() const +{ + switch ( type_ ) + { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if ( value_.array_ ) + { + ValueInternalArray::IteratorState it; + value_.array_->makeEndIterator( it ); + return const_iterator( it ); + } + break; + case objectValue: + if ( value_.map_ ) + { + ValueInternalMap::IteratorState it; + value_.map_->makeEndIterator( it ); + return const_iterator( it ); + } + break; +#else + case arrayValue: + case objectValue: + if ( value_.map_ ) + return const_iterator( value_.map_->end() ); + break; +#endif + default: + break; + } + return const_iterator(); +} + + +Value::iterator +Value::begin() +{ + switch ( type_ ) + { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if ( value_.array_ ) + { + ValueInternalArray::IteratorState it; + value_.array_->makeBeginIterator( it ); + return iterator( it ); + } + break; + case objectValue: + if ( value_.map_ ) + { + ValueInternalMap::IteratorState it; + value_.map_->makeBeginIterator( it ); + return iterator( it ); + } + break; +#else + case arrayValue: + case objectValue: + if ( value_.map_ ) + return iterator( value_.map_->begin() ); + break; +#endif + default: + break; + } + return iterator(); +} + +Value::iterator +Value::end() +{ + switch ( type_ ) + { +#ifdef JSON_VALUE_USE_INTERNAL_MAP + case arrayValue: + if ( value_.array_ ) + { + ValueInternalArray::IteratorState it; + value_.array_->makeEndIterator( it ); + return iterator( it ); + } + break; + case objectValue: + if ( value_.map_ ) + { + ValueInternalMap::IteratorState it; + value_.map_->makeEndIterator( it ); + return iterator( it ); + } + break; +#else + case arrayValue: + case objectValue: + if ( value_.map_ ) + return iterator( value_.map_->end() ); + break; +#endif + default: + break; + } + return iterator(); +} + + +// class PathArgument +// ////////////////////////////////////////////////////////////////// + +PathArgument::PathArgument() + : kind_( kindNone ) +{ +} + + +PathArgument::PathArgument( Value::UInt index ) + : index_( index ) + , kind_( kindIndex ) +{ +} + + +PathArgument::PathArgument( const char *key ) + : key_( key ) + , kind_( kindKey ) +{ +} + + +PathArgument::PathArgument( const std::string &key ) + : key_( key.c_str() ) + , kind_( kindKey ) +{ +} + +// class Path +// ////////////////////////////////////////////////////////////////// + +Path::Path( const std::string &path, + const PathArgument &a1, + const PathArgument &a2, + const PathArgument &a3, + const PathArgument &a4, + const PathArgument &a5 ) +{ + InArgs in; + in.push_back( &a1 ); + in.push_back( &a2 ); + in.push_back( &a3 ); + in.push_back( &a4 ); + in.push_back( &a5 ); + makePath( path, in ); +} + + +void +Path::makePath( const std::string &path, + const InArgs &in ) +{ + const char *current = path.c_str(); + const char *end = current + path.length(); + InArgs::const_iterator itInArg = in.begin(); + while ( current != end ) + { + if ( *current == '[' ) + { + ++current; + if ( *current == '%' ) + addPathInArg( path, in, itInArg, PathArgument::kindIndex ); + else + { + Value::UInt index = 0; + for ( ; current != end && *current >= '0' && *current <= '9'; ++current ) + index = index * 10 + Value::UInt(*current - '0'); + args_.push_back( index ); + } + if ( current == end || *current++ != ']' ) + invalidPath( path, int(current - path.c_str()) ); + } + else if ( *current == '%' ) + { + addPathInArg( path, in, itInArg, PathArgument::kindKey ); + ++current; + } + else if ( *current == '.' ) + { + ++current; + } + else + { + const char *beginName = current; + while ( current != end && !strchr( "[.", *current ) ) + ++current; + args_.push_back( std::string( beginName, current ) ); + } + } +} + + +void +Path::addPathInArg( const std::string &path, + const InArgs &in, + InArgs::const_iterator &itInArg, + PathArgument::Kind kind ) +{ + if ( itInArg == in.end() ) + { + // Error: missing argument %d + } + else if ( (*itInArg)->kind_ != kind ) + { + // Error: bad argument type + } + else + { + args_.push_back( **itInArg ); + } +} + + +void +Path::invalidPath( const std::string &path, + int location ) +{ + // Error: invalid path. +} + + +const Value & +Path::resolve( const Value &root ) const +{ + const Value *node = &root; + for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) + { + const PathArgument &arg = *it; + if ( arg.kind_ == PathArgument::kindIndex ) + { + if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) + { + // Error: unable to resolve path (array value expected at position... + } + node = &((*node)[arg.index_]); + } + else if ( arg.kind_ == PathArgument::kindKey ) + { + if ( !node->isObject() ) + { + // Error: unable to resolve path (object value expected at position...) + } + node = &((*node)[arg.key_]); + if ( node == &Value::null ) + { + // Error: unable to resolve path (object has no member named '' at position...) + } + } + } + return *node; +} + + +Value +Path::resolve( const Value &root, + const Value &defaultValue ) const +{ + const Value *node = &root; + for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) + { + const PathArgument &arg = *it; + if ( arg.kind_ == PathArgument::kindIndex ) + { + if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) + return defaultValue; + node = &((*node)[arg.index_]); + } + else if ( arg.kind_ == PathArgument::kindKey ) + { + if ( !node->isObject() ) + return defaultValue; + node = &((*node)[arg.key_]); + if ( node == &Value::null ) + return defaultValue; + } + } + return *node; +} + + +Value & +Path::make( Value &root ) const +{ + Value *node = &root; + for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) + { + const PathArgument &arg = *it; + if ( arg.kind_ == PathArgument::kindIndex ) + { + if ( !node->isArray() ) + { + // Error: node is not an array at position ... + } + node = &((*node)[arg.index_]); + } + else if ( arg.kind_ == PathArgument::kindKey ) + { + if ( !node->isObject() ) + { + // Error: node is not an object at position... + } + node = &((*node)[arg.key_]); + } + } + return *node; +} + + +} // namespace Json diff --git a/tools/polly/lib/JSON/json_valueiterator.inl b/tools/polly/lib/JSON/json_valueiterator.inl new file mode 100644 index 00000000000..736e260ea03 --- /dev/null +++ b/tools/polly/lib/JSON/json_valueiterator.inl @@ -0,0 +1,292 @@ +// included by json_value.cpp +// everything is within Json namespace + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIteratorBase +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIteratorBase::ValueIteratorBase() +#ifndef JSON_VALUE_USE_INTERNAL_MAP + : current_() + , isNull_( true ) +{ +} +#else + : isArray_( true ) + , isNull_( true ) +{ + iterator_.array_ = ValueInternalArray::IteratorState(); +} +#endif + + +#ifndef JSON_VALUE_USE_INTERNAL_MAP +ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator ¤t ) + : current_( current ) + , isNull_( false ) +{ +} +#else +ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state ) + : isArray_( true ) +{ + iterator_.array_ = state; +} + + +ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state ) + : isArray_( false ) +{ + iterator_.map_ = state; +} +#endif + +Value & +ValueIteratorBase::deref() const +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + return current_->second; +#else + if ( isArray_ ) + return ValueInternalArray::dereference( iterator_.array_ ); + return ValueInternalMap::value( iterator_.map_ ); +#endif +} + + +void +ValueIteratorBase::increment() +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + ++current_; +#else + if ( isArray_ ) + ValueInternalArray::increment( iterator_.array_ ); + ValueInternalMap::increment( iterator_.map_ ); +#endif +} + + +void +ValueIteratorBase::decrement() +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + --current_; +#else + if ( isArray_ ) + ValueInternalArray::decrement( iterator_.array_ ); + ValueInternalMap::decrement( iterator_.map_ ); +#endif +} + + +ValueIteratorBase::difference_type +ValueIteratorBase::computeDistance( const SelfType &other ) const +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP +# ifdef JSON_USE_CPPTL_SMALLMAP + return current_ - other.current_; +# else + // Iterator for null value are initialized using the default + // constructor, which initialize current_ to the default + // std::map::iterator. As begin() and end() are two instance + // of the default std::map::iterator, they can not be compared. + // To allow this, we handle this comparison specifically. + if ( isNull_ && other.isNull_ ) + { + return 0; + } + + + // Usage of std::distance is not portable (does not compile with Sun Studio 12 RogueWave STL, + // which is the one used by default). + // Using a portable hand-made version for non random iterator instead: + // return difference_type( std::distance( current_, other.current_ ) ); + difference_type myDistance = 0; + for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it ) + { + ++myDistance; + } + return myDistance; +# endif +#else + if ( isArray_ ) + return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ ); + return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ ); +#endif +} + + +bool +ValueIteratorBase::isEqual( const SelfType &other ) const +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + if ( isNull_ ) + { + return other.isNull_; + } + return current_ == other.current_; +#else + if ( isArray_ ) + return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ ); + return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ ); +#endif +} + + +void +ValueIteratorBase::copy( const SelfType &other ) +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + current_ = other.current_; +#else + if ( isArray_ ) + iterator_.array_ = other.iterator_.array_; + iterator_.map_ = other.iterator_.map_; +#endif +} + + +Value +ValueIteratorBase::key() const +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + const Value::CZString czstring = (*current_).first; + if ( czstring.c_str() ) + { + if ( czstring.isStaticString() ) + return Value( StaticString( czstring.c_str() ) ); + return Value( czstring.c_str() ); + } + return Value( czstring.index() ); +#else + if ( isArray_ ) + return Value( ValueInternalArray::indexOf( iterator_.array_ ) ); + bool isStatic; + const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic ); + if ( isStatic ) + return Value( StaticString( memberName ) ); + return Value( memberName ); +#endif +} + + +UInt +ValueIteratorBase::index() const +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + const Value::CZString czstring = (*current_).first; + if ( !czstring.c_str() ) + return czstring.index(); + return Value::UInt( -1 ); +#else + if ( isArray_ ) + return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) ); + return Value::UInt( -1 ); +#endif +} + + +const char * +ValueIteratorBase::memberName() const +{ +#ifndef JSON_VALUE_USE_INTERNAL_MAP + const char *name = (*current_).first.c_str(); + return name ? name : ""; +#else + if ( !isArray_ ) + return ValueInternalMap::key( iterator_.map_ ); + return ""; +#endif +} + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueConstIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueConstIterator::ValueConstIterator() +{ +} + + +#ifndef JSON_VALUE_USE_INTERNAL_MAP +ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator ¤t ) + : ValueIteratorBase( current ) +{ +} +#else +ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state ) + : ValueIteratorBase( state ) +{ +} + +ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state ) + : ValueIteratorBase( state ) +{ +} +#endif + +ValueConstIterator & +ValueConstIterator::operator =( const ValueIteratorBase &other ) +{ + copy( other ); + return *this; +} + + +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// class ValueIterator +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////// + +ValueIterator::ValueIterator() +{ +} + + +#ifndef JSON_VALUE_USE_INTERNAL_MAP +ValueIterator::ValueIterator( const Value::ObjectValues::iterator ¤t ) + : ValueIteratorBase( current ) +{ +} +#else +ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state ) + : ValueIteratorBase( state ) +{ +} + +ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state ) + : ValueIteratorBase( state ) +{ +} +#endif + +ValueIterator::ValueIterator( const ValueConstIterator &other ) + : ValueIteratorBase( other ) +{ +} + +ValueIterator::ValueIterator( const ValueIterator &other ) + : ValueIteratorBase( other ) +{ +} + +ValueIterator & +ValueIterator::operator =( const SelfType &other ) +{ + copy( other ); + return *this; +} diff --git a/tools/polly/lib/JSON/json_writer.cpp b/tools/polly/lib/JSON/json_writer.cpp new file mode 100644 index 00000000000..cdf4188f2ec --- /dev/null +++ b/tools/polly/lib/JSON/json_writer.cpp @@ -0,0 +1,829 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#if _MSC_VER >= 1400 // VC++ 8.0 +#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. +#endif + +namespace Json { + +static bool isControlCharacter(char ch) +{ + return ch > 0 && ch <= 0x1F; +} + +static bool containsControlCharacter( const char* str ) +{ + while ( *str ) + { + if ( isControlCharacter( *(str++) ) ) + return true; + } + return false; +} +static void uintToString( unsigned int value, + char *¤t ) +{ + *--current = 0; + do + { + *--current = (value % 10) + '0'; + value /= 10; + } + while ( value != 0 ); +} + +std::string valueToString( Int value ) +{ + char buffer[32]; + char *current = buffer + sizeof(buffer); + bool isNegative = value < 0; + if ( isNegative ) + value = -value; + uintToString( UInt(value), current ); + if ( isNegative ) + *--current = '-'; + assert( current >= buffer ); + return current; +} + + +std::string valueToString( UInt value ) +{ + char buffer[32]; + char *current = buffer + sizeof(buffer); + uintToString( value, current ); + assert( current >= buffer ); + return current; +} + +std::string valueToString( double value ) +{ + char buffer[32]; +#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning. + sprintf_s(buffer, sizeof(buffer), "%#.16g", value); +#else + sprintf(buffer, "%#.16g", value); +#endif + char* ch = buffer + strlen(buffer) - 1; + if (*ch != '0') return buffer; // nothing to truncate, so save time + while(ch > buffer && *ch == '0'){ + --ch; + } + char* last_nonzero = ch; + while(ch >= buffer){ + switch(*ch){ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + --ch; + continue; + case '.': + // Truncate zeroes to save bytes in output, but keep one. + *(last_nonzero+2) = '\0'; + return buffer; + default: + return buffer; + } + } + return buffer; +} + + +std::string valueToString( bool value ) +{ + return value ? "true" : "false"; +} + +std::string valueToQuotedString( const char *value ) +{ + // Not sure how to handle unicode... + if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value )) + return std::string("\"") + value + "\""; + // We have to walk value and escape any special characters. + // Appending to std::string is not efficient, but this should be rare. + // (Note: forward slashes are *not* rare, but I am not escaping them.) + unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL + std::string result; + result.reserve(maxsize); // to avoid lots of mallocs + result += "\""; + for (const char* c=value; *c != 0; ++c) + { + switch(*c) + { + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\f': + result += "\\f"; + break; + case '\n': + result += "\\n"; + break; + case '\r': + result += "\\r"; + break; + case '\t': + result += "\\t"; + break; + //case '/': + // Even though \/ is considered a legal escape in JSON, a bare + // slash is also legal, so I see no reason to escape it. + // (I hope I am not misunderstanding something. + // blep notes: actually escaping \/ may be useful in javascript to avoid (*c); + result += oss.str(); + } + else + { + result += *c; + } + break; + } + } + result += "\""; + return result; +} + +// Class Writer +// ////////////////////////////////////////////////////////////////// +Writer::~Writer() +{ +} + + +// Class FastWriter +// ////////////////////////////////////////////////////////////////// + +FastWriter::FastWriter() + : yamlCompatiblityEnabled_( false ) +{ +} + + +void +FastWriter::enableYAMLCompatibility() +{ + yamlCompatiblityEnabled_ = true; +} + + +std::string +FastWriter::write( const Value &root ) +{ + document_ = ""; + writeValue( root ); + document_ += "\n"; + return document_; +} + + +void +FastWriter::writeValue( const Value &value ) +{ + switch ( value.type() ) + { + case nullValue: + document_ += "null"; + break; + case intValue: + document_ += valueToString( value.asInt() ); + break; + case uintValue: + document_ += valueToString( value.asUInt() ); + break; + case realValue: + document_ += valueToString( value.asDouble() ); + break; + case stringValue: + document_ += valueToQuotedString( value.asCString() ); + break; + case booleanValue: + document_ += valueToString( value.asBool() ); + break; + case arrayValue: + { + document_ += "["; + int size = value.size(); + for ( int index =0; index < size; ++index ) + { + if ( index > 0 ) + document_ += ","; + writeValue( value[index] ); + } + document_ += "]"; + } + break; + case objectValue: + { + Value::Members members( value.getMemberNames() ); + document_ += "{"; + for ( Value::Members::iterator it = members.begin(); + it != members.end(); + ++it ) + { + const std::string &name = *it; + if ( it != members.begin() ) + document_ += ","; + document_ += valueToQuotedString( name.c_str() ); + document_ += yamlCompatiblityEnabled_ ? ": " + : ":"; + writeValue( value[name] ); + } + document_ += "}"; + } + break; + } +} + + +// Class StyledWriter +// ////////////////////////////////////////////////////////////////// + +StyledWriter::StyledWriter() + : rightMargin_( 74 ) + , indentSize_( 3 ) +{ +} + + +std::string +StyledWriter::write( const Value &root ) +{ + document_ = ""; + addChildValues_ = false; + indentString_ = ""; + writeCommentBeforeValue( root ); + writeValue( root ); + writeCommentAfterValueOnSameLine( root ); + document_ += "\n"; + return document_; +} + + +void +StyledWriter::writeValue( const Value &value ) +{ + switch ( value.type() ) + { + case nullValue: + pushValue( "null" ); + break; + case intValue: + pushValue( valueToString( value.asInt() ) ); + break; + case uintValue: + pushValue( valueToString( value.asUInt() ) ); + break; + case realValue: + pushValue( valueToString( value.asDouble() ) ); + break; + case stringValue: + pushValue( valueToQuotedString( value.asCString() ) ); + break; + case booleanValue: + pushValue( valueToString( value.asBool() ) ); + break; + case arrayValue: + writeArrayValue( value); + break; + case objectValue: + { + Value::Members members( value.getMemberNames() ); + if ( members.empty() ) + pushValue( "{}" ); + else + { + writeWithIndent( "{" ); + indent(); + Value::Members::iterator it = members.begin(); + while ( true ) + { + const std::string &name = *it; + const Value &childValue = value[name]; + writeCommentBeforeValue( childValue ); + writeWithIndent( valueToQuotedString( name.c_str() ) ); + document_ += " : "; + writeValue( childValue ); + if ( ++it == members.end() ) + { + writeCommentAfterValueOnSameLine( childValue ); + break; + } + document_ += ","; + writeCommentAfterValueOnSameLine( childValue ); + } + unindent(); + writeWithIndent( "}" ); + } + } + break; + } +} + + +void +StyledWriter::writeArrayValue( const Value &value ) +{ + unsigned size = value.size(); + if ( size == 0 ) + pushValue( "[]" ); + else + { + bool isArrayMultiLine = isMultineArray( value ); + if ( isArrayMultiLine ) + { + writeWithIndent( "[" ); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index =0; + while ( true ) + { + const Value &childValue = value[index]; + writeCommentBeforeValue( childValue ); + if ( hasChildValue ) + writeWithIndent( childValues_[index] ); + else + { + writeIndent(); + writeValue( childValue ); + } + if ( ++index == size ) + { + writeCommentAfterValueOnSameLine( childValue ); + break; + } + document_ += ","; + writeCommentAfterValueOnSameLine( childValue ); + } + unindent(); + writeWithIndent( "]" ); + } + else // output on a single line + { + assert( childValues_.size() == size ); + document_ += "[ "; + for ( unsigned index =0; index < size; ++index ) + { + if ( index > 0 ) + document_ += ", "; + document_ += childValues_[index]; + } + document_ += " ]"; + } + } +} + + +bool +StyledWriter::isMultineArray( const Value &value ) +{ + int size = value.size(); + bool isMultiLine = size*3 >= rightMargin_ ; + childValues_.clear(); + for ( int index =0; index < size && !isMultiLine; ++index ) + { + const Value &childValue = value[index]; + isMultiLine = isMultiLine || + ( (childValue.isArray() || childValue.isObject()) && + childValue.size() > 0 ); + } + if ( !isMultiLine ) // check if line length > max line length + { + childValues_.reserve( size ); + addChildValues_ = true; + int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]' + for ( int index =0; index < size && !isMultiLine; ++index ) + { + writeValue( value[index] ); + lineLength += int( childValues_[index].length() ); + isMultiLine = isMultiLine && hasCommentForValue( value[index] ); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + + +void +StyledWriter::pushValue( const std::string &value ) +{ + if ( addChildValues_ ) + childValues_.push_back( value ); + else + document_ += value; +} + + +void +StyledWriter::writeIndent() +{ + if ( !document_.empty() ) + { + char last = document_[document_.length()-1]; + if ( last == ' ' ) // already indented + return; + if ( last != '\n' ) // Comments may add new-line + document_ += '\n'; + } + document_ += indentString_; +} + + +void +StyledWriter::writeWithIndent( const std::string &value ) +{ + writeIndent(); + document_ += value; +} + + +void +StyledWriter::indent() +{ + indentString_ += std::string( indentSize_, ' ' ); +} + + +void +StyledWriter::unindent() +{ + assert( int(indentString_.size()) >= indentSize_ ); + indentString_.resize( indentString_.size() - indentSize_ ); +} + + +void +StyledWriter::writeCommentBeforeValue( const Value &root ) +{ + if ( !root.hasComment( commentBefore ) ) + return; + document_ += normalizeEOL( root.getComment( commentBefore ) ); + document_ += "\n"; +} + + +void +StyledWriter::writeCommentAfterValueOnSameLine( const Value &root ) +{ + if ( root.hasComment( commentAfterOnSameLine ) ) + document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) ); + + if ( root.hasComment( commentAfter ) ) + { + document_ += "\n"; + document_ += normalizeEOL( root.getComment( commentAfter ) ); + document_ += "\n"; + } +} + + +bool +StyledWriter::hasCommentForValue( const Value &value ) +{ + return value.hasComment( commentBefore ) + || value.hasComment( commentAfterOnSameLine ) + || value.hasComment( commentAfter ); +} + + +std::string +StyledWriter::normalizeEOL( const std::string &text ) +{ + std::string normalized; + normalized.reserve( text.length() ); + const char *begin = text.c_str(); + const char *end = begin + text.length(); + const char *current = begin; + while ( current != end ) + { + char c = *current++; + if ( c == '\r' ) // mac or dos EOL + { + if ( *current == '\n' ) // convert dos EOL + ++current; + normalized += '\n'; + } + else // handle unix EOL & other char + normalized += c; + } + return normalized; +} + + +// Class StyledStreamWriter +// ////////////////////////////////////////////////////////////////// + +StyledStreamWriter::StyledStreamWriter( std::string indentation ) + : document_(NULL) + , rightMargin_( 74 ) + , indentation_( indentation ) +{ +} + + +void +StyledStreamWriter::write( std::ostream &out, const Value &root ) +{ + document_ = &out; + addChildValues_ = false; + indentString_ = ""; + writeCommentBeforeValue( root ); + writeValue( root ); + writeCommentAfterValueOnSameLine( root ); + *document_ << "\n"; + document_ = NULL; // Forget the stream, for safety. +} + + +void +StyledStreamWriter::writeValue( const Value &value ) +{ + switch ( value.type() ) + { + case nullValue: + pushValue( "null" ); + break; + case intValue: + pushValue( valueToString( value.asInt() ) ); + break; + case uintValue: + pushValue( valueToString( value.asUInt() ) ); + break; + case realValue: + pushValue( valueToString( value.asDouble() ) ); + break; + case stringValue: + pushValue( valueToQuotedString( value.asCString() ) ); + break; + case booleanValue: + pushValue( valueToString( value.asBool() ) ); + break; + case arrayValue: + writeArrayValue( value); + break; + case objectValue: + { + Value::Members members( value.getMemberNames() ); + if ( members.empty() ) + pushValue( "{}" ); + else + { + writeWithIndent( "{" ); + indent(); + Value::Members::iterator it = members.begin(); + while ( true ) + { + const std::string &name = *it; + const Value &childValue = value[name]; + writeCommentBeforeValue( childValue ); + writeWithIndent( valueToQuotedString( name.c_str() ) ); + *document_ << " : "; + writeValue( childValue ); + if ( ++it == members.end() ) + { + writeCommentAfterValueOnSameLine( childValue ); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine( childValue ); + } + unindent(); + writeWithIndent( "}" ); + } + } + break; + } +} + + +void +StyledStreamWriter::writeArrayValue( const Value &value ) +{ + unsigned size = value.size(); + if ( size == 0 ) + pushValue( "[]" ); + else + { + bool isArrayMultiLine = isMultineArray( value ); + if ( isArrayMultiLine ) + { + writeWithIndent( "[" ); + indent(); + bool hasChildValue = !childValues_.empty(); + unsigned index =0; + while ( true ) + { + const Value &childValue = value[index]; + writeCommentBeforeValue( childValue ); + if ( hasChildValue ) + writeWithIndent( childValues_[index] ); + else + { + writeIndent(); + writeValue( childValue ); + } + if ( ++index == size ) + { + writeCommentAfterValueOnSameLine( childValue ); + break; + } + *document_ << ","; + writeCommentAfterValueOnSameLine( childValue ); + } + unindent(); + writeWithIndent( "]" ); + } + else // output on a single line + { + assert( childValues_.size() == size ); + *document_ << "[ "; + for ( unsigned index =0; index < size; ++index ) + { + if ( index > 0 ) + *document_ << ", "; + *document_ << childValues_[index]; + } + *document_ << " ]"; + } + } +} + + +bool +StyledStreamWriter::isMultineArray( const Value &value ) +{ + int size = value.size(); + bool isMultiLine = size*3 >= rightMargin_ ; + childValues_.clear(); + for ( int index =0; index < size && !isMultiLine; ++index ) + { + const Value &childValue = value[index]; + isMultiLine = isMultiLine || + ( (childValue.isArray() || childValue.isObject()) && + childValue.size() > 0 ); + } + if ( !isMultiLine ) // check if line length > max line length + { + childValues_.reserve( size ); + addChildValues_ = true; + int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]' + for ( int index =0; index < size && !isMultiLine; ++index ) + { + writeValue( value[index] ); + lineLength += int( childValues_[index].length() ); + isMultiLine = isMultiLine && hasCommentForValue( value[index] ); + } + addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= rightMargin_; + } + return isMultiLine; +} + + +void +StyledStreamWriter::pushValue( const std::string &value ) +{ + if ( addChildValues_ ) + childValues_.push_back( value ); + else + *document_ << value; +} + + +void +StyledStreamWriter::writeIndent() +{ + /* + Some comments in this method would have been nice. ;-) + + if ( !document_.empty() ) + { + char last = document_[document_.length()-1]; + if ( last == ' ' ) // already indented + return; + if ( last != '\n' ) // Comments may add new-line + *document_ << '\n'; + } + */ + *document_ << '\n' << indentString_; +} + + +void +StyledStreamWriter::writeWithIndent( const std::string &value ) +{ + writeIndent(); + *document_ << value; +} + + +void +StyledStreamWriter::indent() +{ + indentString_ += indentation_; +} + + +void +StyledStreamWriter::unindent() +{ + assert( indentString_.size() >= indentation_.size() ); + indentString_.resize( indentString_.size() - indentation_.size() ); +} + + +void +StyledStreamWriter::writeCommentBeforeValue( const Value &root ) +{ + if ( !root.hasComment( commentBefore ) ) + return; + *document_ << normalizeEOL( root.getComment( commentBefore ) ); + *document_ << "\n"; +} + + +void +StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root ) +{ + if ( root.hasComment( commentAfterOnSameLine ) ) + *document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) ); + + if ( root.hasComment( commentAfter ) ) + { + *document_ << "\n"; + *document_ << normalizeEOL( root.getComment( commentAfter ) ); + *document_ << "\n"; + } +} + + +bool +StyledStreamWriter::hasCommentForValue( const Value &value ) +{ + return value.hasComment( commentBefore ) + || value.hasComment( commentAfterOnSameLine ) + || value.hasComment( commentAfter ); +} + + +std::string +StyledStreamWriter::normalizeEOL( const std::string &text ) +{ + std::string normalized; + normalized.reserve( text.length() ); + const char *begin = text.c_str(); + const char *end = begin + text.length(); + const char *current = begin; + while ( current != end ) + { + char c = *current++; + if ( c == '\r' ) // mac or dos EOL + { + if ( *current == '\n' ) // convert dos EOL + ++current; + normalized += '\n'; + } + else // handle unix EOL & other char + normalized += c; + } + return normalized; +} + + +std::ostream& operator<<( std::ostream &sout, const Value &root ) +{ + Json::StyledStreamWriter writer; + writer.write(sout, root); + return sout; +} + + +} // namespace Json diff --git a/tools/polly/lib/JSON/sconscript b/tools/polly/lib/JSON/sconscript new file mode 100644 index 00000000000..6e7c6c8a076 --- /dev/null +++ b/tools/polly/lib/JSON/sconscript @@ -0,0 +1,8 @@ +Import( 'env buildLibrary' ) + +buildLibrary( env, Split( """ + json_reader.cpp + json_value.cpp + json_writer.cpp + """ ), + 'json' ) diff --git a/tools/polly/lib/Makefile b/tools/polly/lib/Makefile new file mode 100755 index 00000000000..d81635282c9 --- /dev/null +++ b/tools/polly/lib/Makefile @@ -0,0 +1,81 @@ +##===- polly/lib/Makefile -----------------------*- Makefile -*-===## + +# +# Indicate where we are relative to the top of the source tree. +# +LEVEL :=.. + +LIBRARYNAME=LLVMPolly +LOADABLE_MODULE = 1 + +include $(LEVEL)/Makefile.config + +CPP.Flags += $(POLLY_INC) + +DIRS = Exchange +USEDLIBS = pollyexchange.a + +DIRS += Analysis +USEDLIBS += pollyanalysis.a + +# This needs to be added after the files that use it, otherwise some functions +# from pollysupport are not available. They will be eliminated if they are +# not used at the time of linking pollysupport.a +DIRS += Support +USEDLIBS += pollysupport.a + +DIRS += JSON +USEDLIBS += pollyjson.a + +# TODO: Export symbols for RTTI or EH? + +# +# Include Makefile.common so we know what to do. +# +include $(LEVEL)/Makefile.common + +LIBS += $(POLLY_LD) $(POLLY_LIB) + +$(LibDir)/libpollyanalysis.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/Analysis/$(BuildMode)/.dir \ + $(PROJ_SRC_DIR)/Analysis/* + $(Verb) if [ -d $(PROJ_SRC_DIR)/Analysis ]; then\ + if ([ ! -f Analysis/Makefile ] || \ + command test Analysis/Makefile -ot $(PROJ_SRC_DIR)/Analysis/Makefile ); then \ + $(MKDIR) Analysis; \ + $(CP) $(PROJ_SRC_DIR)/Analysis/Makefile Analysis/Makefile; \ + fi; \ + ($(MAKE) -C Analysis $@ ) || exit 1; \ + fi + +$(LibDir)/libpollyexchange.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/Exchange/$(BuildMode)/.dir \ + $(PROJ_SRC_DIR)/Exchange/* + $(Verb) if [ -d $(PROJ_SRC_DIR)/Exchange ]; then\ + if ([ ! -f Exchange/Makefile ] || \ + command test Exchange/Makefile -ot $(PROJ_SRC_DIR)/Exchange/Makefile ); then \ + $(MKDIR) Exchange; \ + $(CP) $(PROJ_SRC_DIR)/Exchange/Makefile Exchange/Makefile; \ + fi; \ + ($(MAKE) -C Exchange $@ ) || exit 1; \ + fi + +$(LibDir)/libpollysupport.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/Support/$(BuildMode)/.dir \ + $(PROJ_SRC_DIR)/Support/* + $(Verb) if [ -d $(PROJ_SRC_DIR)/Support ]; then\ + if ([ ! -f Support/Makefile ] || \ + command test Support/Makefile -ot $(PROJ_SRC_DIR)/Support/Makefile ); then \ + $(MKDIR) Support; \ + $(CP) $(PROJ_SRC_DIR)/Support/Makefile Support/Makefile; \ + fi; \ + ($(MAKE) -C Support $@ ) || exit 1; \ + fi + +$(LibDir)/libpollyjson.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/JSON/$(BuildMode)/.dir \ + $(PROJ_SRC_DIR)/JSON/* + $(Verb) if [ -d $(PROJ_SRC_DIR)/JSON ]; then\ + if ([ ! -f JSON/Makefile ] || \ + command test JSON/Makefile -ot $(PROJ_SRC_DIR)/JSON/Makefile ); then \ + $(MKDIR) JSON; \ + $(CP) $(PROJ_SRC_DIR)/JSON/Makefile JSON/Makefile; \ + fi; \ + ($(MAKE) -C JSON $@ ) || exit 1; \ + fi diff --git a/tools/polly/lib/MayAliasSet.cpp b/tools/polly/lib/MayAliasSet.cpp new file mode 100755 index 00000000000..71355902582 --- /dev/null +++ b/tools/polly/lib/MayAliasSet.cpp @@ -0,0 +1,47 @@ +//===---------- MayAliasSet.cpp - May-Alais Set for base pointers --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the MayAliasSet class +// +//===----------------------------------------------------------------------===// + +#include "polly/TempScopInfo.h" +#include "polly/MayAliasSet.h" + +#include "llvm/LLVMContext.h" +#include "llvm/Analysis/RegionInfo.h" +#include "llvm/Analysis/RegionIterator.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AliasSetTracker.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/Support/raw_ostream.h" + +#include "llvm/Support/Debug.h" + +using namespace llvm; +using namespace polly; + +void MayAliasSet::print(raw_ostream &OS) const { + OS << "Must alias {"; + + for (const_iterator I = mustalias_begin(), E = mustalias_end(); I != E; ++I) { + WriteAsOperand(OS, *I, false); + OS << ", "; + } + + OS << "} May alias {"; + OS << '}'; +} + +void MayAliasSet::dump() const { + print(dbgs()); +} + +void MayAliasSetInfo::buildMayAliasSets(TempScop &Scop, AliasAnalysis &AA) { +} diff --git a/tools/polly/lib/Pocc.cpp b/tools/polly/lib/Pocc.cpp new file mode 100644 index 00000000000..6bed2e3663f --- /dev/null +++ b/tools/polly/lib/Pocc.cpp @@ -0,0 +1,287 @@ +//===- Pocc.cpp - Pocc interface ----------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Pocc[1] interface. +// +// Pocc, the polyhedral compilation collection is a collection of polyhedral +// tools. It is used as an optimizer in polly +// +// [1] http://www-roc.inria.fr/~pouchet/software/pocc/ +// +//===----------------------------------------------------------------------===// + +#include "polly/Cloog.h" +#include "polly/LinkAllPasses.h" + +#ifdef SCOPLIB_FOUND +#include "polly/ScopInfo.h" +#include "polly/Dependences.h" +#include "polly/CodeGeneration.h" +#include "polly/ScheduleOptimizer.h" + +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/system_error.h" +#include "llvm/ADT/OwningPtr.h" + +#include "polly/ScopLib.h" + +#include "isl/space.h" +#include "isl/map.h" +#include "isl/constraint.h" + + +using namespace llvm; +using namespace polly; + +static cl::opt +PlutoFuse("pluto-fuse", + cl::desc(""), cl::Hidden, + cl::value_desc("Set fuse mode of Pluto"), + cl::init("maxfuse")); + +namespace { + + class Pocc : public ScopPass { + sys::Path plutoStderr; + sys::Path plutoStdout; + std::vector arguments; + + public: + static char ID; + explicit Pocc() : ScopPass(ID) {} + + std::string getFileName(Region *R) const; + virtual bool runOnScop(Scop &S); + void printScop(llvm::raw_ostream &OS) const; + void getAnalysisUsage(AnalysisUsage &AU) const; + }; + +} + +char Pocc::ID = 0; +bool Pocc::runOnScop(Scop &S) { + Dependences *D = &getAnalysis(); + + // Only the final read statement in the SCoP. No need to optimize anything. + // (In case we would try, Pocc complains that there is no statement in the + // SCoP). + if (S.begin() + 1 == S.end()) + return false; + + // Create the scop file. + sys::Path tempDir = sys::Path::GetTemporaryDirectory(); + sys::Path scopFile = tempDir; + scopFile.appendComponent("polly.scop"); + scopFile.createFileOnDisk(); + + FILE *F = fopen(scopFile.c_str(), "w"); + + arguments.clear(); + + if (!F) { + errs() << "Cannot open file: " << tempDir.c_str() << "\n"; + errs() << "Skipping export.\n"; + return false; + } + + ScopLib scoplib(&S); + scoplib.print(F); + fclose(F); + + // Execute pocc + sys::Program program; + + sys::Path pocc = sys::Program::FindProgramByName("pocc"); + + arguments.push_back("pocc"); + arguments.push_back("--read-scop"); + arguments.push_back(scopFile.c_str()); + arguments.push_back("--pluto-tile-scat"); + arguments.push_back("--candl-dep-isl-simp"); + arguments.push_back("--cloogify-scheds"); + arguments.push_back("--output-scop"); + arguments.push_back("--pluto"); + arguments.push_back("--pluto-bounds"); + arguments.push_back("10"); + arguments.push_back("--pluto-fuse"); + + arguments.push_back(PlutoFuse.c_str()); + + if (!DisablePollyTiling) + arguments.push_back("--pluto-tile"); + + if (EnablePollyVector) + arguments.push_back("--pluto-prevector"); + + arguments.push_back(0); + + plutoStdout = tempDir; + plutoStdout.appendComponent("pluto.stdout"); + plutoStderr = tempDir; + plutoStderr.appendComponent("pluto.stderr"); + + std::vector redirect; + redirect.push_back(0); + redirect.push_back(&plutoStdout); + redirect.push_back(&plutoStderr); + + program.ExecuteAndWait(pocc, &arguments[0], 0, + (sys::Path const **) &redirect[0]); + + // Read the created scop file + sys::Path newScopFile = tempDir; + newScopFile.appendComponent("polly.pocc.c.scop"); + + FILE *poccFile = fopen(newScopFile.c_str(), "r"); + ScopLib newScoplib(&S, poccFile, D); + + if (!newScoplib.updateScattering()) { + errs() << "Failure when calculating the optimization with " + "the following command: "; + for (std::vector::const_iterator AI = arguments.begin(), + AE = arguments.end(); AI != AE; ++AI) + if (*AI) + errs() << " " << *AI; + errs() << "\n"; + return false; + } else + fclose(poccFile); + + if (!EnablePollyVector) + return false; + + // Find the innermost dimension that is not a constant dimension. This + // dimension will be vectorized. + unsigned scatterDims = S.getScatterDim(); + int lastLoop = scatterDims - 1; + + while (lastLoop) { + bool isSingleValued = true; + + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { + if ((*SI)->isFinalRead()) + continue; + + isl_map *scat = (*SI)->getScattering(); + isl_map *projected = isl_map_project_out(scat, isl_dim_out, lastLoop, + scatterDims - lastLoop); + + if (!isl_map_is_bijective(projected)) { + isSingleValued = false; + break; + } + } + + if (!isSingleValued) + break; + + lastLoop--; + } + + // Strip mine the innermost loop. + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { + if ((*SI)->isFinalRead()) + continue; + isl_map *scat = (*SI)->getScattering(); + int scatDims = (*SI)->getNumScattering(); + isl_space *Space = isl_space_alloc(S.getIslCtx(), S.getNumParams(), + scatDims, scatDims + 1); + isl_basic_map *map = isl_basic_map_universe(isl_space_copy(Space)); + isl_local_space *LSpace = isl_local_space_from_space(Space); + + for (int i = 0; i <= lastLoop - 1; i++) { + isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LSpace)); + + isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1); + isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1); + + map = isl_basic_map_add_constraint(map, c); + } + + for (int i = lastLoop; i < scatDims; i++) { + isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LSpace)); + + isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1); + isl_constraint_set_coefficient_si(c, isl_dim_out, i + 1, -1); + + map = isl_basic_map_add_constraint(map, c); + } + + isl_constraint *c; + + int vectorWidth = 4; + c = isl_inequality_alloc(isl_local_space_copy(LSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, -vectorWidth); + isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, 1); + map = isl_basic_map_add_constraint(map, c); + + c = isl_inequality_alloc(LSpace); + isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, vectorWidth); + isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, -1); + isl_constraint_set_constant_si(c, vectorWidth - 1); + map = isl_basic_map_add_constraint(map, c); + + isl_map *transform = isl_map_from_basic_map(map); + transform = isl_map_set_tuple_name(transform, isl_dim_out, "scattering"); + transform = isl_map_set_tuple_name(transform, isl_dim_in, "scattering"); + + scat = isl_map_apply_range(scat, isl_map_copy(transform)); + (*SI)->setScattering(scat); + } + + return false; +} + +void Pocc::printScop(raw_ostream &OS) const { + OwningPtr stdoutBuffer; + OwningPtr stderrBuffer; + + OS << "Command line: "; + + for (std::vector::const_iterator AI = arguments.begin(), + AE = arguments.end(); AI != AE; ++AI) + if (*AI) + OS << " " << *AI; + + OS << "\n"; + + if (error_code ec = MemoryBuffer::getFile(plutoStdout.c_str(), stdoutBuffer)) + OS << "Could not open pocc stdout file: " + ec.message(); + else { + OS << "pocc stdout: " << stdoutBuffer->getBufferIdentifier() << "\n"; + OS << stdoutBuffer->getBuffer() << "\n"; + } + + if (error_code ec = MemoryBuffer::getFile(plutoStderr.c_str(), stderrBuffer)) + OS << "Could not open pocc stderr file: " + ec.message(); + else { + OS << "pocc stderr: " << plutoStderr.c_str() << "\n"; + OS << stderrBuffer->getBuffer() << "\n"; + } +} + +void Pocc::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); +} + +INITIALIZE_PASS_BEGIN(Pocc, "polly-opt-pocc", + "Polly - Optimize the scop using pocc", false, false) +INITIALIZE_PASS_DEPENDENCY(Dependences) +INITIALIZE_PASS_DEPENDENCY(ScopInfo) +INITIALIZE_PASS_END(Pocc, "polly-opt-pocc", + "Polly - Optimize the scop using pocc", false, false) + +Pass* polly::createPoccPass() { + return new Pocc(); +} +#endif /* SCOPLIB_FOUND */ diff --git a/tools/polly/lib/RegionSimplify.cpp b/tools/polly/lib/RegionSimplify.cpp new file mode 100644 index 00000000000..733045da983 --- /dev/null +++ b/tools/polly/lib/RegionSimplify.cpp @@ -0,0 +1,222 @@ +//===- RegionSimplify.cpp -------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file converts refined regions detected by the RegionInfo analysis +// into simple regions. +// +//===----------------------------------------------------------------------===// + +#include "polly/LinkAllPasses.h" + +#include "llvm/Instructions.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/RegionPass.h" +#include "llvm/Analysis/RegionInfo.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +#define DEBUG_TYPE "region-simplify" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +STATISTIC(NumEntries, "The # of created entry edges"); +STATISTIC(NumExits, "The # of created exit edges"); + +namespace { +class RegionSimplify: public RegionPass { + // Remember the modified region. + Region *r; + void createSingleEntryEdge(Region *R); + void createSingleExitEdge(Region *R); +public: + static char ID; + explicit RegionSimplify() : RegionPass(ID), r(0) {} + + virtual void print(raw_ostream &O, const Module *M) const; + + virtual bool runOnRegion(Region *R, RGPassManager &RGM); + virtual void getAnalysisUsage(AnalysisUsage &AU) const; +}; +} + +char RegionSimplify::ID = 0; + +INITIALIZE_PASS_BEGIN(RegionSimplify, "polly-region-simplify", + "Transform refined regions into simple regions", false, + false) +INITIALIZE_PASS_DEPENDENCY(RegionInfo) +INITIALIZE_PASS_END(RegionSimplify, "polly-region-simplify", + "Transform refined regions into simple regions", false, + false) +namespace polly { + Pass *createRegionSimplifyPass() { + return new RegionSimplify(); + } +} + +void RegionSimplify::print(raw_ostream &O, const Module *M) const { + if (r == 0) return; + + BasicBlock *enteringBlock = r->getEnteringBlock(); + BasicBlock *exitingBlock = r->getExitingBlock(); + + O << "Region: " << r->getNameStr() << " Edges:\t"; + + if (enteringBlock) + O << "Entering: [" << enteringBlock->getName() << " -> " + << r->getEntry()->getName() << "], "; + + if (exitingBlock) { + O << "Exiting: [" << exitingBlock->getName() << " -> "; + if (r->getExit()) + O << r->getExit()->getName(); + else + O << ""; + O << "]"; + } + + O << "\n"; +} + +void RegionSimplify::getAnalysisUsage(AnalysisUsage &AU) const { + // Function SplitBlockPredecessors currently updates/preserves AliasAnalysis, + /// DominatorTree, LoopInfo, and LCCSA but no other analyses. + //AU.addPreserved(); Break SCEV-AA + AU.addPreserved (); + AU.addPreserved(); + AU.addPreservedID(LCSSAID); + + AU.addPreserved (); + AU.addRequired (); +} + +// createSingleEntryEdge - Split the entry basic block of the given +// region after the last PHINode to form a single entry edge. +void RegionSimplify::createSingleEntryEdge(Region *R) { + BasicBlock *oldEntry = R->getEntry(); + SmallVector Preds; + for (pred_iterator PI = pred_begin(oldEntry), PE = pred_end(oldEntry); + PI != PE; ++PI) + if (!R->contains(*PI)) + Preds.push_back(*PI); + + assert(Preds.size() && "This region has already a single entry edge"); + + BasicBlock *newEntry = SplitBlockPredecessors(oldEntry, Preds, + ".single_entry", this); + + RegionInfo *RI = &getAnalysis (); + // We do not update entry node for children of this region. + // This make it easier to extract children regions because they do not share + // the entry node with their parents. + // all parent regions whose entry is oldEntry are updated with newEntry + Region *r = R->getParent(); + + // Put the new entry to R's parent. + RI->setRegionFor(newEntry,r); + + while (r->getEntry() == oldEntry && !r->isTopLevelRegion()) { + r->replaceEntry(newEntry); + r = r->getParent(); + } + + // We do not update exit node for children of this region for the same reason + // of not updating entry node. + // All other regions whose exit is oldEntry are updated with new exit node + r = RI->getTopLevelRegion(); + std::vector RQ; + RQ.push_back(r); + + while (!RQ.empty()){ + r = RQ.back(); + RQ.pop_back(); + + for (Region::const_iterator RI = r->begin(), RE = r->end(); RI!=RE; ++RI) + RQ.push_back(*RI); + + if (r->getExit() == oldEntry && !R->contains(r)) + r->replaceExit(newEntry); + } + +} + +// createSingleExitEdge - Split the exit basic of the given region +// to form a single exit edge. +void RegionSimplify::createSingleExitEdge(Region *R) { + BasicBlock *oldExit = R->getExit(); + + SmallVector Preds; + for (pred_iterator PI = pred_begin(oldExit), PE = pred_end(oldExit); + PI != PE; ++PI) + if (R->contains(*PI)) + Preds.push_back(*PI); + + DEBUG(dbgs() << "Going to create single exit for:\n"); + DEBUG(R->print(dbgs(), true, 0, Region::PrintRN)); + BasicBlock *newExit = SplitBlockPredecessors(oldExit, Preds, + ".single_exit", this); + RegionInfo *RI = &getAnalysis(); + + // We do not need to update entry nodes because this split happens inside + // this region and it affects only this region and all of its children. + // The new split node belongs to this region + RI->setRegionFor(newExit,R); + DEBUG(dbgs() << "Adding new exiting block: " << newExit->getName() << '\n'); + + // all children of this region whose exit is oldExit is changed to newExit + std::vector RQ; + for (Region::const_iterator RI = R->begin(), RE = R->end(); RI!=RE; ++RI) + RQ.push_back(*RI); + + while (!RQ.empty()){ + R = RQ.back(); + RQ.pop_back(); + + if (R->getExit() != oldExit) + continue; + + for (Region::const_iterator RI = R->begin(), RE = R->end(); RI!=RE; ++RI) + RQ.push_back(*RI); + + R->replaceExit(newExit); + DEBUG(dbgs() << "Replacing exit for:\n"); + DEBUG(R->print(dbgs(), true, 0, Region::PrintRN)); + } + + DEBUG(dbgs() << "After split exit:\n"); + DEBUG(R->print(dbgs(), true, 0, Region::PrintRN)); +} + +bool RegionSimplify::runOnRegion(Region *R, RGPassManager &RGM) { + r = 0; + + if (!R->isTopLevelRegion()) { + + // split entry node if the region has multiple entry edges + if (!(R->getEnteringBlock()) + && (pred_begin(R->getEntry()) != pred_end(R->getEntry()))) { + createSingleEntryEdge(R); + r = R; + ++NumEntries; + } + + // split exit node if the region has multiple exit edges + if (!(R->getExitingBlock())) { + createSingleExitEdge(R); + r = R; + ++NumExits; + } + } + + return r != 0; +} diff --git a/tools/polly/lib/RegisterPasses.cpp b/tools/polly/lib/RegisterPasses.cpp new file mode 100644 index 00000000000..9bba19c2ec5 --- /dev/null +++ b/tools/polly/lib/RegisterPasses.cpp @@ -0,0 +1,251 @@ +//===------ RegisterPasses.cpp - Add the Polly Passes to default passes --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Add the Polly passes to the optimization passes executed at -O3. +// +//===----------------------------------------------------------------------===// +#include "polly/RegisterPasses.h" +#include "polly/LinkAllPasses.h" + +#include "polly/Cloog.h" +#include "polly/Dependences.h" +#include "polly/ScopDetection.h" +#include "polly/ScopInfo.h" +#include "polly/TempScopInfo.h" + +#include "llvm/Analysis/Passes.h" +#include "llvm/InitializePasses.h" +#include "llvm/PassManager.h" +#include "llvm/PassRegistry.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Support/CommandLine.h" + +#include + +using namespace llvm; + +static cl::opt +PollyEnabled("polly", cl::desc("Enable the default passes of Polly in -O3"), + cl::init(false)); + +static cl::opt +DisableScheduler("polly-no-optimizer", + cl::desc("Disable Polly Scheduling Optimizer"), cl::Hidden, + cl::init(false)); +static cl::opt +DisableCodegen("polly-no-codegen", + cl::desc("Disable Polly Code Generation"), cl::Hidden, + cl::init(false)); +static cl::opt +Optimizer("polly-optimizer", + cl::desc("Select the scheduling optimizer. " + "Either isl (default) or pocc."), + cl::Hidden, cl::init("isl")); +static cl::opt +ImportJScop("polly-run-import-jscop", + cl::desc("Export the JScop description of the detected Scops"), + cl::Hidden, cl::init(false)); +static cl::opt +ExportJScop("polly-run-export-jscop", + cl::desc("Export the JScop description of the detected Scops"), + cl::Hidden, cl::init(false)); +static cl::opt +PollyViewer("polly-show", + cl::desc("Enable the Polly DOT viewer in -O3"), cl::Hidden, + cl::value_desc("Run the Polly DOT viewer at -O3"), + cl::init(false)); + +static cl::opt +DeadCodeElim("polly-run-dce", + cl::desc("Run the dead code elimination"), + cl::Hidden, cl::init(false)); + +static cl::opt +PollyOnlyViewer("polly-show-only", + cl::desc("Enable the Polly DOT viewer in -O3 (no BB content)"), + cl::Hidden, + cl::value_desc("Run the Polly DOT viewer at -O3 (no BB content"), + cl::init(false)); +static cl::opt +PollyPrinter("polly-dot", + cl::desc("Enable the Polly DOT printer in -O3"), cl::Hidden, + cl::value_desc("Run the Polly DOT printer at -O3"), + cl::init(false)); +static cl::opt +PollyOnlyPrinter("polly-dot-only", + cl::desc("Enable the Polly DOT printer in -O3 (no BB content)"), + cl::Hidden, + cl::value_desc("Run the Polly DOT printer at -O3 (no BB content"), + cl::init(false)); + +void initializePollyPasses(PassRegistry &Registry) { + initializeCloogInfoPass(Registry); + initializeCodeGenerationPass(Registry); + initializeCodePreparationPass(Registry); + initializeDeadCodeElimPass(Registry); + initializeDependencesPass(Registry); + initializeIndependentBlocksPass(Registry); + initializeJSONExporterPass(Registry); + initializeJSONImporterPass(Registry); + initializeIslScheduleOptimizerPass(Registry); +#ifdef SCOPLIB_FOUND + initializePoccPass(Registry); +#endif + initializeRegionSimplifyPass(Registry); + initializeScopDetectionPass(Registry); + initializeScopInfoPass(Registry); + initializeTempScopInfoPass(Registry); +} + +// Statically register all Polly passes such that they are available after +// loading Polly. +class StaticInitializer { + +public: + StaticInitializer() { + PassRegistry &Registry = *PassRegistry::getPassRegistry(); + initializePollyPasses(Registry); + } +}; + +static StaticInitializer InitializeEverything; + +void registerPollyPreoptPasses(llvm::PassManagerBase &PM) { + // A standard set of optimization passes partially taken/copied from the + // set of default optimization passes. It is used to bring the code into + // a canonical form that can than be analyzed by Polly. This set of passes is + // most probably not yet optimal. TODO: Investigate optimal set of passes. + PM.add(llvm::createPromoteMemoryToRegisterPass()); + PM.add(llvm::createInstructionCombiningPass()); // Clean up after IPCP & DAE + PM.add(llvm::createCFGSimplificationPass()); // Clean up after IPCP & DAE + PM.add(llvm::createTailCallEliminationPass()); // Eliminate tail calls + PM.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs + PM.add(llvm::createReassociatePass()); // Reassociate expressions + PM.add(llvm::createLoopRotatePass()); // Rotate Loop + PM.add(llvm::createInstructionCombiningPass()); + PM.add(llvm::createIndVarSimplifyPass()); // Canonicalize indvars + + PM.add(polly::createCodePreparationPass()); + PM.add(polly::createRegionSimplifyPass()); + // FIXME: The next two passes should not be necessary here. They are currently + // because of two problems: + // + // 1. The RegionSimplifyPass destroys the canonical form of induction + // variables,as it produces PHI nodes with incorrectly ordered + // operands. To fix this we run IndVarSimplify. + // + // 2. IndVarSimplify does not preserve the region information and + // the regioninfo pass does currently not recover simple regions. + // As a result we need to run the RegionSimplify pass again to + // recover them + PM.add(llvm::createIndVarSimplifyPass()); + PM.add(polly::createRegionSimplifyPass()); +} + +void registerPollyPasses(llvm::PassManagerBase &PM, bool DisableScheduler, + bool DisableCodegen) { + bool RunScheduler = !DisableScheduler; + bool RunCodegen = !DisableCodegen; + + registerPollyPreoptPasses(PM); + + PM.add(polly::createScopInfoPass()); + + if (PollyViewer) + PM.add(polly::createDOTViewerPass()); + if (PollyOnlyViewer) + PM.add(polly::createDOTOnlyViewerPass()); + if (PollyPrinter) + PM.add(polly::createDOTPrinterPass()); + if (PollyOnlyPrinter) + PM.add(polly::createDOTOnlyPrinterPass()); + + if (ImportJScop) + PM.add(polly::createJSONImporterPass()); + + if (DeadCodeElim) + PM.add(polly::createDeadCodeElimPass()); + + if (RunScheduler) { + if (Optimizer == "pocc") { +#ifdef SCOPLIB_FOUND + PM.add(polly::createPoccPass()); +#else + errs() << "Polly is compiled without scoplib support. As scoplib is " + "required to run PoCC, PoCC is also not available. Falling " + "back to the isl optimizer.\n"; + PM.add(polly::createIslScheduleOptimizerPass()); +#endif + } else if (Optimizer == "isl") { + PM.add(polly::createIslScheduleOptimizerPass()); + } else { + errs() << "Invalid optimizer. Only 'isl' and 'pocc' allowed. " + "Falling back to 'isl'.\n"; + PM.add(polly::createIslScheduleOptimizerPass()); + } + } + + if (ExportJScop) + PM.add(polly::createJSONExporterPass()); + + if (RunCodegen) + PM.add(polly::createCodeGenerationPass()); +} + +static +void registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder, + llvm::PassManagerBase &PM) { + + if (Builder.OptLevel == 0) + return; + + if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer || + ExportJScop || ImportJScop) + PollyEnabled = true; + + if (!PollyEnabled) { + if (DisableCodegen) + errs() << "The option -polly-no-codegen has no effect. " + "Polly was not enabled\n"; + + if (DisableScheduler) + errs() << "The option -polly-no-optimizer has no effect. " + "Polly was not enabled\n"; + + return; + } + + // Polly is only enabled at -O3 + if (Builder.OptLevel != 3) { + errs() << "Polly should only be run with -O3. Disabling Polly.\n"; + return; + } + + registerPollyPasses(PM, DisableScheduler, DisableCodegen); +} + +static void registerPollyOptLevel0Passes(const llvm::PassManagerBuilder &, + llvm::PassManagerBase &PM) { + registerPollyPreoptPasses(PM); +} + + +// Execute Polly together with a set of preparing passes. +// +// We run Polly that early to run before loop optimizer passes like LICM or +// the LoopIdomPass. Both transform the code in a way that Polly will recognize +// less scops. + +static llvm::RegisterStandardPasses +PassRegister(llvm::PassManagerBuilder::EP_EarlyAsPossible, + registerPollyEarlyAsPossiblePasses); +static llvm::RegisterStandardPasses +PassRegisterPreopt(llvm::PassManagerBuilder::EP_EnabledOnOptLevel0, + registerPollyOptLevel0Passes); diff --git a/tools/polly/lib/ScheduleOptimizer.cpp b/tools/polly/lib/ScheduleOptimizer.cpp new file mode 100644 index 00000000000..80ea97ce443 --- /dev/null +++ b/tools/polly/lib/ScheduleOptimizer.cpp @@ -0,0 +1,551 @@ +//===- Schedule.cpp - Calculate an optimized schedule ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass the isl to calculate a schedule that is optimized for parallelism +// and tileablility. The algorithm used in isl is an optimized version of the +// algorithm described in following paper: +// +// U. Bondhugula, A. Hartono, J. Ramanujam, and P. Sadayappan. +// A Practical Automatic Polyhedral Parallelizer and Locality Optimizer. +// In Proceedings of the 2008 ACM SIGPLAN Conference On Programming Language +// Design and Implementation, PLDI ’08, pages 101–113. ACM, 2008. +//===----------------------------------------------------------------------===// + +#include "polly/ScheduleOptimizer.h" + +#include "polly/CodeGeneration.h" +#include "polly/Dependences.h" +#include "polly/LinkAllPasses.h" +#include "polly/ScopInfo.h" + +#include "isl/aff.h" +#include "isl/band.h" +#include "isl/constraint.h" +#include "isl/map.h" +#include "isl/options.h" +#include "isl/schedule.h" +#include "isl/space.h" + +#define DEBUG_TYPE "polly-opt-isl" +#include "llvm/Support/Debug.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; +using namespace polly; + +namespace polly { + bool DisablePollyTiling; +} +static cl::opt +DisableTiling("polly-no-tiling", + cl::desc("Disable tiling in the scheduler"), cl::Hidden, + cl::location(polly::DisablePollyTiling), cl::init(false)); + +static cl::opt +SimplifyDeps("polly-opt-simplify-deps", + cl::desc("Dependences should be simplified (yes/no)"), + cl::Hidden, cl::init("yes")); + +static cl::opt +FusionStrategy("polly-opt-fusion", + cl::desc("The fusion strategy to choose (min/max)"), + cl::Hidden, cl::init("min")); + +static cl::opt +MaximizeBandDepth("polly-opt-maximize-bands", + cl::desc("Maximize the band depth (yes/no)"), + cl::Hidden, cl::init("yes")); + +namespace { + + class IslScheduleOptimizer : public ScopPass { + + public: + static char ID; + explicit IslScheduleOptimizer() : ScopPass(ID) {} + + virtual bool runOnScop(Scop &S); + void printScop(llvm::raw_ostream &OS) const; + void getAnalysisUsage(AnalysisUsage &AU) const; + }; + +} + +char IslScheduleOptimizer::ID = 0; + +static int getSingleMap(__isl_take isl_map *map, void *user) { + isl_map **singleMap = (isl_map **) user; + *singleMap = map; + + return 0; +} + +static void extendScattering(Scop &S, unsigned NewDimensions) { + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (Stmt->isFinalRead()) + continue; + + unsigned OldDimensions = Stmt->getNumScattering(); + isl_space *Space; + isl_basic_map *ChangeScattering; + + Space = isl_space_alloc(Stmt->getIslCtx(), 0, OldDimensions, NewDimensions); + ChangeScattering = isl_basic_map_universe(isl_space_copy(Space)); + isl_local_space *LocalSpace = isl_local_space_from_space(Space); + + for (unsigned i = 0; i < OldDimensions; i++) { + isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1); + isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1); + ChangeScattering = isl_basic_map_add_constraint(ChangeScattering, c); + } + + for (unsigned i = OldDimensions; i < NewDimensions; i++) { + isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1); + ChangeScattering = isl_basic_map_add_constraint(ChangeScattering, c); + } + + isl_map *ChangeScatteringMap = isl_map_from_basic_map(ChangeScattering); + + ChangeScatteringMap = isl_map_align_params(ChangeScatteringMap, + S.getParamSpace()); + isl_map *NewScattering = isl_map_apply_range(Stmt->getScattering(), + ChangeScatteringMap); + Stmt->setScattering(NewScattering); + isl_local_space_free(LocalSpace); + } +} + +// getTileMap - Create a map that describes a n-dimensonal tiling. +// +// getTileMap creates a map from a n-dimensional scattering space into an +// 2*n-dimensional scattering space. The map describes a rectangular tiling. +// +// Example: +// scheduleDimensions = 2, parameterDimensions = 1, tileSize = 32 +// +// tileMap := [p0] -> {[s0, s1] -> [t0, t1, s0, s1]: +// t0 % 32 = 0 and t0 <= s0 < t0 + 32 and +// t1 % 32 = 0 and t1 <= s1 < t1 + 32} +// +// Before tiling: +// +// for (i = 0; i < N; i++) +// for (j = 0; j < M; j++) +// S(i,j) +// +// After tiling: +// +// for (t_i = 0; t_i < N; i+=32) +// for (t_j = 0; t_j < M; j+=32) +// for (i = t_i; i < min(t_i + 32, N); i++) | Unknown that N % 32 = 0 +// for (j = t_j; j < t_j + 32; j++) | Known that M % 32 = 0 +// S(i,j) +// +static isl_basic_map *getTileMap(isl_ctx *ctx, int scheduleDimensions, + isl_space *SpaceModel, int tileSize = 32) { + // We construct + // + // tileMap := [p0] -> {[s0, s1] -> [t0, t1, p0, p1, a0, a1]: + // s0 = a0 * 32 and s0 = p0 and t0 <= p0 < t0 + 32 and + // s1 = a1 * 32 and s1 = p1 and t1 <= p1 < t1 + 32} + // + // and project out the auxilary dimensions a0 and a1. + isl_space *Space = isl_space_alloc(ctx, 0, scheduleDimensions, + scheduleDimensions * 3); + isl_basic_map *tileMap = isl_basic_map_universe(isl_space_copy(Space)); + + isl_local_space *LocalSpace = isl_local_space_from_space(Space); + + for (int x = 0; x < scheduleDimensions; x++) { + int sX = x; + int tX = x; + int pX = scheduleDimensions + x; + int aX = 2 * scheduleDimensions + x; + + isl_constraint *c; + + // sX = aX * tileSize; + c = isl_equality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_out, sX, 1); + isl_constraint_set_coefficient_si(c, isl_dim_out, aX, -tileSize); + tileMap = isl_basic_map_add_constraint(tileMap, c); + + // pX = sX; + c = isl_equality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_out, pX, 1); + isl_constraint_set_coefficient_si(c, isl_dim_in, sX, -1); + tileMap = isl_basic_map_add_constraint(tileMap, c); + + // tX <= pX + c = isl_inequality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_out, pX, 1); + isl_constraint_set_coefficient_si(c, isl_dim_out, tX, -1); + tileMap = isl_basic_map_add_constraint(tileMap, c); + + // pX <= tX + (tileSize - 1) + c = isl_inequality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_out, tX, 1); + isl_constraint_set_coefficient_si(c, isl_dim_out, pX, -1); + isl_constraint_set_constant_si(c, tileSize - 1); + tileMap = isl_basic_map_add_constraint(tileMap, c); + } + + // Project out auxilary dimensions. + // + // The auxilary dimensions are transformed into existentially quantified ones. + // This reduces the number of visible scattering dimensions and allows Cloog + // to produces better code. + tileMap = isl_basic_map_project_out(tileMap, isl_dim_out, + 2 * scheduleDimensions, + scheduleDimensions); + isl_local_space_free(LocalSpace); + return tileMap; +} + +// getScheduleForBand - Get the schedule for this band. +// +// Polly applies transformations like tiling on top of the isl calculated value. +// This can influence the number of scheduling dimension. The number of +// schedule dimensions is returned in the parameter 'Dimension'. +isl_union_map *getScheduleForBand(isl_band *Band, int *Dimensions) { + isl_union_map *PartialSchedule; + isl_ctx *ctx; + isl_space *Space; + isl_basic_map *TileMap; + isl_union_map *TileUMap; + + PartialSchedule = isl_band_get_partial_schedule(Band); + *Dimensions = isl_band_n_member(Band); + + if (DisableTiling) + return PartialSchedule; + + // It does not make any sense to tile a band with just one dimension. + if (*Dimensions == 1) + return PartialSchedule; + + ctx = isl_union_map_get_ctx(PartialSchedule); + Space = isl_union_map_get_space(PartialSchedule); + + TileMap = getTileMap(ctx, *Dimensions, Space); + TileUMap = isl_union_map_from_map(isl_map_from_basic_map(TileMap)); + TileUMap = isl_union_map_align_params(TileUMap, Space); + *Dimensions = 2 * *Dimensions; + + return isl_union_map_apply_range(PartialSchedule, TileUMap); +} + +// Create a map that pre-vectorizes one scheduling dimension. +// +// getPrevectorMap creates a map that maps each input dimension to the same +// output dimension, except for the dimension DimToVectorize. DimToVectorize is +// strip mined by 'VectorWidth' and the newly created point loop of +// DimToVectorize is moved to the innermost level. +// +// Example (DimToVectorize=0, ScheduleDimensions=2, VectorWidth=4): +// +// | Before transformation +// | +// | A[i,j] -> [i,j] +// | +// | for (i = 0; i < 128; i++) +// | for (j = 0; j < 128; j++) +// | A(i,j); +// +// Prevector map: +// [i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip +// +// | After transformation: +// | +// | A[i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip +// | +// | for (it = 0; it < 128; it+=4) +// | for (j = 0; j < 128; j++) +// | for (ip = max(0,it); ip < min(128, it + 3); ip++) +// | A(ip,j); +// +// The goal of this transformation is to create a trivially vectorizable loop. +// This means a parallel loop at the innermost level that has a constant number +// of iterations corresponding to the target vector width. +// +// This transformation creates a loop at the innermost level. The loop has a +// constant number of iterations, if the number of loop iterations at +// DimToVectorize can be devided by VectorWidth. The default VectorWidth is +// currently constant and not yet target specific. This function does not reason +// about parallelism. +static isl_map *getPrevectorMap(isl_ctx *ctx, int DimToVectorize, + int ScheduleDimensions, + int VectorWidth = 4) { + isl_space *Space; + isl_local_space *LocalSpace, *LocalSpaceRange; + isl_set *Modulo; + isl_map *TilingMap; + isl_constraint *c; + isl_aff *Aff; + int PointDimension; /* ip */ + int TileDimension; /* it */ + isl_int VectorWidthMP; + + assert (0 <= DimToVectorize && DimToVectorize < ScheduleDimensions); + + Space = isl_space_alloc(ctx, 0, ScheduleDimensions, ScheduleDimensions + 1); + TilingMap = isl_map_universe(isl_space_copy(Space)); + LocalSpace = isl_local_space_from_space(Space); + PointDimension = ScheduleDimensions; + TileDimension = DimToVectorize; + + // Create an identity map for everything except DimToVectorize and map + // DimToVectorize to the point loop at the innermost dimension. + for (int i = 0; i < ScheduleDimensions; i++) { + c = isl_equality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_in, i, -1); + + if (i == DimToVectorize) + isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, 1); + else + isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1); + + TilingMap = isl_map_add_constraint(TilingMap, c); + } + + // it % 'VectorWidth' = 0 + LocalSpaceRange = isl_local_space_range(isl_local_space_copy(LocalSpace)); + Aff = isl_aff_zero_on_domain(LocalSpaceRange); + Aff = isl_aff_set_constant_si(Aff, VectorWidth); + Aff = isl_aff_set_coefficient_si(Aff, isl_dim_in, TileDimension, 1); + isl_int_init(VectorWidthMP); + isl_int_set_si(VectorWidthMP, VectorWidth); + Aff = isl_aff_mod(Aff, VectorWidthMP); + isl_int_clear(VectorWidthMP); + Modulo = isl_pw_aff_zero_set(isl_pw_aff_from_aff(Aff)); + TilingMap = isl_map_intersect_range(TilingMap, Modulo); + + // it <= ip + c = isl_inequality_alloc(isl_local_space_copy(LocalSpace)); + isl_constraint_set_coefficient_si(c, isl_dim_out, TileDimension, -1); + isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, 1); + TilingMap = isl_map_add_constraint(TilingMap, c); + + // ip <= it + ('VectorWidth' - 1) + c = isl_inequality_alloc(LocalSpace); + isl_constraint_set_coefficient_si(c, isl_dim_out, TileDimension, 1); + isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, -1); + isl_constraint_set_constant_si(c, VectorWidth - 1); + TilingMap = isl_map_add_constraint(TilingMap, c); + + isl_map_dump(TilingMap); + + return TilingMap; +} + +// getScheduleForBandList - Get the scheduling map for a list of bands. +// +// We walk recursively the forest of bands to combine the schedules of the +// individual bands to the overall schedule. In case tiling is requested, +// the individual bands are tiled. +static isl_union_map *getScheduleForBandList(isl_band_list *BandList) { + int NumBands; + isl_union_map *Schedule; + isl_ctx *ctx; + + ctx = isl_band_list_get_ctx(BandList); + NumBands = isl_band_list_n_band(BandList); + Schedule = isl_union_map_empty(isl_space_params_alloc(ctx, 0)); + + for (int i = 0; i < NumBands; i++) { + isl_band *Band; + isl_union_map *PartialSchedule; + int ScheduleDimensions; + isl_space *Space; + + Band = isl_band_list_get_band(BandList, i); + PartialSchedule = getScheduleForBand(Band, &ScheduleDimensions); + Space = isl_union_map_get_space(PartialSchedule); + + if (isl_band_has_children(Band)) { + isl_band_list *Children; + isl_union_map *SuffixSchedule; + + Children = isl_band_get_children(Band); + SuffixSchedule = getScheduleForBandList(Children); + PartialSchedule = isl_union_map_flat_range_product(PartialSchedule, + SuffixSchedule); + isl_band_list_free(Children); + } else if (EnablePollyVector) { + for (int i = ScheduleDimensions - 1 ; i >= 0 ; i--) { + if (isl_band_member_is_zero_distance(Band, i)) { + isl_map *TileMap; + isl_union_map *TileUMap; + + TileMap = getPrevectorMap(ctx, i, ScheduleDimensions); + TileUMap = isl_union_map_from_map(TileMap); + TileUMap = isl_union_map_align_params(TileUMap, + isl_space_copy(Space)); + PartialSchedule = isl_union_map_apply_range(PartialSchedule, + TileUMap); + break; + } + } + } + + Schedule = isl_union_map_union(Schedule, PartialSchedule); + + isl_band_free(Band); + isl_space_free(Space); + } + + return Schedule; +} + +static isl_union_map *getScheduleMap(isl_schedule *Schedule) { + isl_band_list *BandList = isl_schedule_get_band_forest(Schedule); + isl_union_map *ScheduleMap = getScheduleForBandList(BandList); + isl_band_list_free(BandList); + return ScheduleMap; +} + +bool IslScheduleOptimizer::runOnScop(Scop &S) { + Dependences *D = &getAnalysis(); + + // Build input data. + int DependencyKinds = Dependences::TYPE_RAW + | Dependences::TYPE_WAR + | Dependences::TYPE_WAW; + + isl_union_map *Dependences = D->getDependences(DependencyKinds); + isl_union_set *Domain = NULL; + + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) + if ((*SI)->isFinalRead()) + continue; + else if (!Domain) + Domain = isl_union_set_from_set((*SI)->getDomain()); + else + Domain = isl_union_set_union(Domain, + isl_union_set_from_set((*SI)->getDomain())); + + if (!Domain) + return false; + + // Simplify the dependences by removing the constraints introduced by the + // domains. This can speed up the scheduling time significantly, as large + // constant coefficients will be removed from the dependences. The + // introduction of some additional dependences reduces the possible + // transformations, but in most cases, such transformation do not seem to be + // interesting anyway. In some cases this option may stop the scheduler to + // find any schedule. + if (SimplifyDeps == "yes") { + Dependences = isl_union_map_gist_domain(Dependences, + isl_union_set_copy(Domain)); + Dependences = isl_union_map_gist_range(Dependences, + isl_union_set_copy(Domain)); + } else if (SimplifyDeps != "no") { + errs() << "warning: Option -polly-opt-simplify-deps should either be 'yes' " + "or 'no'. Falling back to default: 'yes'\n"; + } + + isl_schedule *Schedule; + isl_union_map *Proximity = isl_union_map_copy(Dependences); + isl_union_map *Validity = Dependences; + + DEBUG(dbgs() << "\n\nCompute schedule from: "); + DEBUG(dbgs() << "Domain := "; isl_union_set_dump(Domain); dbgs() << ";\n"); + DEBUG(dbgs() << "Proximity := "; isl_union_map_dump(Proximity); + dbgs() << ";\n"); + DEBUG(dbgs() << "Validity := "; isl_union_map_dump(Validity); + dbgs() << ";\n"); + + int IslFusionStrategy; + + if (FusionStrategy == "max") { + IslFusionStrategy = ISL_SCHEDULE_FUSE_MAX; + } else if (FusionStrategy == "min") { + IslFusionStrategy = ISL_SCHEDULE_FUSE_MIN; + } else { + errs() << "warning: Unknown fusion strategy. Falling back to maximal " + "fusion.\n"; + IslFusionStrategy = ISL_SCHEDULE_FUSE_MAX; + } + + int IslMaximizeBands; + + if (MaximizeBandDepth == "yes") { + IslMaximizeBands = 1; + } else if (MaximizeBandDepth == "no") { + IslMaximizeBands = 0; + } else { + errs() << "warning: Option -polly-opt-maximize-bands should either be 'yes'" + " or 'no'. Falling back to default: 'yes'\n"; + IslMaximizeBands = 1; + } + + isl_options_set_schedule_fuse(S.getIslCtx(), IslFusionStrategy); + isl_options_set_schedule_maximize_band_depth(S.getIslCtx(), IslMaximizeBands); + + isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE); + Schedule = isl_union_set_compute_schedule(Domain, Validity, Proximity); + isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT); + + // In cases the scheduler is not able to optimize the code, we just do not + // touch the schedule. + if (!Schedule) + return false; + + isl_union_map *ScheduleMap = getScheduleMap(Schedule); + + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) { + ScopStmt *Stmt = *SI; + + if (Stmt->isFinalRead()) + continue; + + isl_set *Domain = Stmt->getDomain(); + isl_union_map *StmtBand; + StmtBand = isl_union_map_intersect_domain(isl_union_map_copy(ScheduleMap), + isl_union_set_from_set(Domain)); + isl_map *StmtSchedule; + isl_union_map_foreach_map(StmtBand, getSingleMap, &StmtSchedule); + Stmt->setScattering(StmtSchedule); + isl_union_map_free(StmtBand); + } + + isl_union_map_free(ScheduleMap); + isl_schedule_free(Schedule); + + unsigned MaxScatDims = 0; + + for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) + MaxScatDims = std::max((*SI)->getNumScattering(), MaxScatDims); + + extendScattering(S, MaxScatDims); + return false; +} + +void IslScheduleOptimizer::printScop(raw_ostream &OS) const { +} + +void IslScheduleOptimizer::getAnalysisUsage(AnalysisUsage &AU) const { + ScopPass::getAnalysisUsage(AU); + AU.addRequired(); +} + +INITIALIZE_PASS_BEGIN(IslScheduleOptimizer, "polly-opt-isl", + "Polly - Optimize schedule of SCoP", false, false) +INITIALIZE_PASS_DEPENDENCY(Dependences) +INITIALIZE_PASS_DEPENDENCY(ScopInfo) +INITIALIZE_PASS_END(IslScheduleOptimizer, "polly-opt-isl", + "Polly - Optimize schedule of SCoP", false, false) + +Pass* polly::createIslScheduleOptimizerPass() { + return new IslScheduleOptimizer(); +} diff --git a/tools/polly/lib/Support/CMakeLists.txt b/tools/polly/lib/Support/CMakeLists.txt new file mode 100755 index 00000000000..c6dfd87b243 --- /dev/null +++ b/tools/polly/lib/Support/CMakeLists.txt @@ -0,0 +1,5 @@ +add_polly_library(PollySupport + GICHelper.cpp + SCEVValidator.cpp + ScopHelper.cpp + ) diff --git a/tools/polly/lib/Support/GICHelper.cpp b/tools/polly/lib/Support/GICHelper.cpp new file mode 100644 index 00000000000..46184f33f4b --- /dev/null +++ b/tools/polly/lib/Support/GICHelper.cpp @@ -0,0 +1,112 @@ +//===- GmpConv.cpp - Recreate LLVM IR from the Scop. ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Functions for converting between gmp objects and apint. +// +//===----------------------------------------------------------------------===// +#include "polly/Support/GICHelper.h" + +#include "isl/set.h" +#include "isl/union_set.h" +#include "isl/map.h" +#include "isl/union_map.h" +#include "isl/schedule.h" + +using namespace llvm; + +void polly::MPZ_from_APInt (mpz_t v, const APInt apint, bool is_signed) { + // There is no sign taken from the data, rop will simply be a positive + // integer. An application can handle any sign itself, and apply it for + // instance with mpz_neg. + APInt abs; + if (is_signed) + abs = apint.abs(); + else + abs = apint; + + const uint64_t *rawdata = abs.getRawData(); + unsigned numWords = abs.getNumWords(); + + // TODO: Check if this is true for all platforms. + mpz_import(v, numWords, 1, sizeof (uint64_t), 0, 0, rawdata); + + if (is_signed && apint.isNegative()) mpz_neg(v, v); +} + +APInt polly::APInt_from_MPZ (const mpz_t mpz) { + uint64_t *p = NULL; + size_t sz; + + p = (uint64_t*) mpz_export(p, &sz, 1, sizeof(uint64_t), 0, 0, mpz); + + if (p) { + APInt A((unsigned)mpz_sizeinbase(mpz, 2), (unsigned)sz , p); + A = A.zext(A.getBitWidth() + 1); + free(p); + + if (mpz_sgn(mpz) == -1) + return -A; + else + return A; + } else { + uint64_t val = 0; + return APInt(1, 1, &val); + } +} + +std::string polly::stringFromIslObj(/*__isl_keep*/ isl_map *map) { + isl_printer *p = isl_printer_to_str(isl_map_get_ctx(map)); + isl_printer_print_map(p, map); + char *char_str = isl_printer_get_str(p); + std::string string(char_str); + free(char_str); + isl_printer_free(p); + return string; +} + +std::string polly::stringFromIslObj(/*__isl_keep*/ isl_set *set) { + isl_printer *p = isl_printer_to_str(isl_set_get_ctx(set)); + isl_printer_print_set(p, set); + char *char_str = isl_printer_get_str(p); + std::string string(char_str); + free(char_str); + isl_printer_free(p); + return string; +} + +std::string polly::stringFromIslObj(/*__isl_keep*/ isl_union_map *umap) { + isl_printer *p = isl_printer_to_str(isl_union_map_get_ctx(umap)); + isl_printer_print_union_map(p, umap); + char *char_str = isl_printer_get_str(p); + std::string string(char_str); + free(char_str); + isl_printer_free(p); + return string; +} + +std::string polly::stringFromIslObj(/*__isl_keep*/ isl_union_set *uset) { + isl_printer *p = isl_printer_to_str(isl_union_set_get_ctx(uset)); + isl_printer_print_union_set(p, uset); + char *char_str = isl_printer_get_str(p); + std::string string(char_str); + free(char_str); + isl_printer_free(p); + return string; +} + +std::string polly::stringFromIslObj(/*__isl_keep*/ isl_schedule *schedule) { + isl_ctx *ctx = isl_union_map_get_ctx(isl_schedule_get_map(schedule)); + isl_printer *p = isl_printer_to_str(ctx); + isl_printer_print_schedule(p, schedule); + char *char_str = isl_printer_get_str(p); + std::string string(char_str); + free(char_str); + isl_printer_free(p); + return string; +} diff --git a/tools/polly/lib/Support/Makefile b/tools/polly/lib/Support/Makefile new file mode 100755 index 00000000000..e7cae89ddd0 --- /dev/null +++ b/tools/polly/lib/Support/Makefile @@ -0,0 +1,16 @@ +##===- polly/lib/Support/Makefile ----------------*- Makefile -*-===## + +# +# Indicate where we are relative to the top of the source tree. +# +LEVEL=../.. + +LIBRARYNAME=pollysupport +BUILD_ARCHIVE = 1 + +CPP.Flags += $(POLLY_INC) + +# +# Include Makefile.common so we know what to do. +# +include $(LEVEL)/Makefile.common diff --git a/tools/polly/lib/Support/SCEVValidator.cpp b/tools/polly/lib/Support/SCEVValidator.cpp new file mode 100644 index 00000000000..0b87e9e755e --- /dev/null +++ b/tools/polly/lib/Support/SCEVValidator.cpp @@ -0,0 +1,302 @@ + +#include "polly/Support/SCEVValidator.h" + +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Analysis/RegionInfo.h" + +#include + +using namespace llvm; + +namespace SCEVType { + /// @brief The type of a SCEV + /// + /// To check for the validity of a SCEV we assign to each SCEV a type. The + /// possible types are INT, PARAM, IV and INVALID. The order of the types is + /// important. The subexpressions of SCEV with a type X can only have a type + /// that is smaller or equal than X. + enum TYPE { + // An integer value. + INT, + + // An expression that is constant during the execution of the Scop, + // but that may depend on parameters unknown at compile time. + PARAM, + + // An expression that may change during the execution of the SCoP. + IV, + + // An invalid expression. + INVALID + }; +} + +/// @brief The result the validator returns for a SCEV expression. +class ValidatorResult { + /// @brief The type of the expression + SCEVType::TYPE Type; + + /// @brief The set of Parameters in the expression. + std::vector Parameters; + +public: + + /// @brief Create an invalid result. + ValidatorResult() : Type(SCEVType::INVALID) {}; + + /// @brief The copy constructor + ValidatorResult(const ValidatorResult &Source) { + Type = Source.Type; + Parameters = Source.Parameters; + }; + + /// @brief Construct a result with a certain type and no parameters. + ValidatorResult(SCEVType::TYPE Type) : Type(Type) {}; + + /// @brief Construct a result with a certain type and a single parameter. + ValidatorResult(SCEVType::TYPE Type, const SCEV *Expr) : Type(Type) { + Parameters.push_back(Expr); + }; + + /// @brief Is the analyzed SCEV constant during the execution of the SCoP. + bool isConstant() { + return Type == SCEVType::INT || Type == SCEVType::PARAM; + } + + /// @brief Is the analyzed SCEV valid. + bool isValid() { + return Type != SCEVType::INVALID; + } + + /// @brief Is the analyzed SCEV of Type IV. + bool isIV() { + return Type == SCEVType::IV; + } + + /// @brief Is the analyzed SCEV of Type INT. + bool isINT() { + return Type == SCEVType::INT; + } + + /// @brief Get the parameters of this validator result. + std::vector getParameters() { + return Parameters; + } + + /// @brief Add the parameters of Source to this result. + void addParamsFrom(class ValidatorResult &Source) { + Parameters.insert(Parameters.end(), + Source.Parameters.begin(), + Source.Parameters.end()); + } + + /// @brief Merge a result. + /// + /// This means to merge the parameters and to set the Type to the most + /// specific Type that matches both. + void merge(class ValidatorResult &ToMerge) { + Type = std::max(Type, ToMerge.Type); + addParamsFrom(ToMerge); + } +}; + +/// Check if a SCEV is valid in a SCoP. +struct SCEVValidator + : public SCEVVisitor { +private: + const Region *R; + ScalarEvolution &SE; + const Value *BaseAddress; + +public: + SCEVValidator(const Region *R, ScalarEvolution &SE, + const Value *BaseAddress) : R(R), SE(SE), + BaseAddress(BaseAddress) {}; + + class ValidatorResult visitConstant(const SCEVConstant *Constant) { + return ValidatorResult(SCEVType::INT); + } + + class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) { + ValidatorResult Op = visit(Expr->getOperand()); + + // We currently do not represent a truncate expression as an affine + // expression. If it is constant during Scop execution, we treat it as a + // parameter, otherwise we bail out. + if (Op.isConstant()) + return ValidatorResult(SCEVType::PARAM, Expr); + + return ValidatorResult(SCEVType::INVALID); + } + + class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) { + ValidatorResult Op = visit(Expr->getOperand()); + + // We currently do not represent a zero extend expression as an affine + // expression. If it is constant during Scop execution, we treat it as a + // parameter, otherwise we bail out. + if (Op.isConstant()) + return ValidatorResult(SCEVType::PARAM, Expr); + + return ValidatorResult(SCEVType::INVALID); + } + + class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) { + // We currently allow only signed SCEV expressions. In the case of a + // signed value, a sign extend is a noop. + // + // TODO: Reconsider this when we add support for unsigned values. + return visit(Expr->getOperand()); + } + + class ValidatorResult visitAddExpr(const SCEVAddExpr *Expr) { + ValidatorResult Return(SCEVType::INT); + + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { + ValidatorResult Op = visit(Expr->getOperand(i)); + + if (!Op.isValid()) + return ValidatorResult(SCEVType::INVALID); + + Return.merge(Op); + } + + // TODO: Check for NSW and NUW. + return Return; + } + + class ValidatorResult visitMulExpr(const SCEVMulExpr *Expr) { + ValidatorResult Return(SCEVType::INT); + + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { + ValidatorResult Op = visit(Expr->getOperand(i)); + + if (Op.isINT()) + continue; + + if (!Op.isValid() || !Return.isINT()) + return ValidatorResult(SCEVType::INVALID); + + Return.merge(Op); + } + + // TODO: Check for NSW and NUW. + return Return; + } + + class ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) { + ValidatorResult LHS = visit(Expr->getLHS()); + ValidatorResult RHS = visit(Expr->getRHS()); + + // We currently do not represent an unsigned devision as an affine + // expression. If the division is constant during Scop execution we treat it + // as a parameter, otherwise we bail out. + if (LHS.isConstant() && RHS.isConstant()) + return ValidatorResult(SCEVType::PARAM, Expr); + + return ValidatorResult(SCEVType::INVALID); + } + + class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) { + if (!Expr->isAffine()) + return ValidatorResult(SCEVType::INVALID); + + ValidatorResult Start = visit(Expr->getStart()); + ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE)); + + if (!Start.isValid() || !Recurrence.isConstant()) + return ValidatorResult(SCEVType::INVALID); + + if (R->contains(Expr->getLoop())) { + if (Recurrence.isINT()) { + ValidatorResult Result(SCEVType::IV); + Result.addParamsFrom(Start); + return Result; + } + + return ValidatorResult(SCEVType::INVALID); + } + + if (Start.isConstant()) + return ValidatorResult(SCEVType::PARAM, Expr); + + return ValidatorResult(SCEVType::INVALID); + } + + class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) { + ValidatorResult Return(SCEVType::INT); + + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { + ValidatorResult Op = visit(Expr->getOperand(i)); + + if (!Op.isValid()) + return ValidatorResult(SCEVType::INVALID); + + Return.merge(Op); + } + + return Return; + } + + class ValidatorResult visitUMaxExpr(const SCEVUMaxExpr *Expr) { + ValidatorResult Return(SCEVType::PARAM); + + // We do not support unsigned operations. If 'Expr' is constant during Scop + // execution we treat this as a parameter, otherwise we bail out. + for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) { + ValidatorResult Op = visit(Expr->getOperand(i)); + + if (!Op.isConstant()) + return ValidatorResult(SCEVType::INVALID); + + Return.merge(Op); + } + + return Return; + } + + ValidatorResult visitUnknown(const SCEVUnknown *Expr) { + Value *V = Expr->getValue(); + + if (isa(V)) + return ValidatorResult(SCEVType::INVALID); + + if (Instruction *I = dyn_cast(Expr->getValue())) + if (R->contains(I)) + return ValidatorResult(SCEVType::INVALID); + + if (BaseAddress == V) + return ValidatorResult(SCEVType::INVALID); + + return ValidatorResult(SCEVType::PARAM, Expr); + } +}; + +namespace polly { + bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE, + const Value *BaseAddress) { + if (isa(Expr)) + return false; + + SCEVValidator Validator(R, SE, BaseAddress); + ValidatorResult Result = Validator.visit(Expr); + + return Result.isValid(); + } + + std::vector getParamsInAffineExpr(const Region *R, + const SCEV *Expr, + ScalarEvolution &SE, + const Value *BaseAddress) { + if (isa(Expr)) + return std::vector(); + + SCEVValidator Validator(R, SE, BaseAddress); + ValidatorResult Result = Validator.visit(Expr); + + return Result.getParameters(); + } +} + + diff --git a/tools/polly/lib/Support/ScopHelper.cpp b/tools/polly/lib/Support/ScopHelper.cpp new file mode 100644 index 00000000000..39ed55c1a6b --- /dev/null +++ b/tools/polly/lib/Support/ScopHelper.cpp @@ -0,0 +1,247 @@ +//===- ScopHelper.cpp - Some Helper Functions for Scop. ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Small functions that help with Scop and LLVM-IR. +// +//===----------------------------------------------------------------------===// + +#include "polly/Support/ScopHelper.h" + +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/RegionInfo.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" +#include "llvm/Support/CFG.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" + +#define DEBUG_TYPE "polly-scop-helper" +#include "llvm/Support/Debug.h" + +using namespace llvm; + + +namespace { +// Checks if a SCEV is invariant in a region. This is if all Values are +// referenced in this SCEV are defined outside the region. +class InvariantChecker: SCEVVisitor { + Region &R; + +public: + bool visitConstant(const SCEVConstant *S) { + return true; + } + + bool visitUnknown(const SCEVUnknown *S) { + Value *V = S->getValue(); + + // An Instruction defined outside the region is invariant. + if (Instruction *I = dyn_cast(V)) + return !R.contains(I); + + // A constant is invariant. + return true; + } + + bool visitNAryExpr(const SCEVNAryExpr *S) { + for (SCEVNAryExpr::op_iterator OI = S->op_begin(), OE = S->op_end(); + OI != OE; ++OI) + if (!visit(*OI)) + return false; + + return true; + } + + bool visitMulExpr(const SCEVMulExpr *S) { + return visitNAryExpr(S); + } + + bool visitCastExpr(const SCEVCastExpr *S) { + return visit(S->getOperand()); + } + + bool visitTruncateExpr(const SCEVTruncateExpr *S) { + return visit(S->getOperand()); + } + + bool visitZeroExtendExpr(const SCEVZeroExtendExpr *S) { + return visit(S->getOperand()); + } + + bool visitSignExtendExpr(const SCEVSignExtendExpr *S) { + return visit(S->getOperand()); + } + + bool visitAddExpr(const SCEVAddExpr *S) { + return visitNAryExpr(S); + } + + bool visitAddRecExpr(const SCEVAddRecExpr *S) { + // Check if the addrec is contained in the region. + if (R.contains(S->getLoop())) + return false; + + return visitNAryExpr(S); + } + + bool visitUDivExpr(const SCEVUDivExpr *S) { + return visit(S->getLHS()) && visit(S->getRHS()); + } + + bool visitSMaxExpr(const SCEVSMaxExpr *S) { + return visitNAryExpr(S); + } + + bool visitUMaxExpr(const SCEVUMaxExpr *S) { + return visitNAryExpr(S); + } + + bool visitCouldNotCompute(const SCEVCouldNotCompute *S) { + llvm_unreachable("SCEV cannot be checked"); + } + + InvariantChecker(Region &RefRegion) + : R(RefRegion) {} + + static bool isInvariantInRegion(const SCEV *S, Region &R) { + InvariantChecker Checker(R); + return Checker.visit(S); + } +}; +} + +// Helper function for Scop +// TODO: Add assertion to not allow parameter to be null +//===----------------------------------------------------------------------===// +// Temporary Hack for extended region tree. +// Cast the region to loop if there is a loop have the same header and exit. +Loop *polly::castToLoop(const Region &R, LoopInfo &LI) { + BasicBlock *entry = R.getEntry(); + + if (!LI.isLoopHeader(entry)) + return 0; + + Loop *L = LI.getLoopFor(entry); + + BasicBlock *exit = L->getExitBlock(); + + // Is the loop with multiple exits? + if (!exit) return 0; + + if (exit != R.getExit()) { + // SubRegion/ParentRegion with the same entry. + assert((R.getNode(R.getEntry())->isSubRegion() + || R.getParent()->getEntry() == entry) + && "Expect the loop is the smaller or bigger region"); + return 0; + } + + return L; +} + +Value *polly::getPointerOperand(Instruction &Inst) { + if (LoadInst *load = dyn_cast(&Inst)) + return load->getPointerOperand(); + else if (StoreInst *store = dyn_cast(&Inst)) + return store->getPointerOperand(); + else if (GetElementPtrInst *gep = dyn_cast(&Inst)) + return gep->getPointerOperand(); + + return 0; +} + +//===----------------------------------------------------------------------===// +// Helper functions + +bool polly::isInvariant(const SCEV *S, Region &R) { + return InvariantChecker::isInvariantInRegion(S, R); +} + +// Helper function to check parameter +bool polly::isParameter(const SCEV *Var, Region &RefRegion, + LoopInfo &LI, ScalarEvolution &SE) { + assert(Var && "Var can not be null!"); + + if (!isInvariant(Var, RefRegion)) + return false; + + if (isa(Var)) + return true; + + if (const SCEVUnknown *U = dyn_cast(Var)) { + if (isa(U->getValue())) + return false; + + if(isa(U->getValue())) + return false; + + return true; + } + + if (const SCEVCastExpr *Cast = dyn_cast(Var)) + return isParameter(Cast->getOperand(), RefRegion, LI, SE); + + return false; +} + +bool polly::isIndVar(const SCEV *Var, Region &RefRegion, + LoopInfo &LI, ScalarEvolution &SE) { + const SCEVAddRecExpr *AddRec = dyn_cast(Var); + + // AddRecExprs are no induction variables. + if (!AddRec) return false; + + Loop *L = const_cast(AddRec->getLoop()); + + // Is the addrec an induction variable of a loop contained in the current + // region. + if (!RefRegion.contains(L)) + return false; + + DEBUG(dbgs() << "Find AddRec: " << *AddRec + << " at region: " << RefRegion.getNameStr() << " as indvar\n"); + return true; +} + +bool polly::isIndVar(const Instruction *I, const LoopInfo *LI) { + Loop *L = LI->getLoopFor(I->getParent()); + + return L && I == L->getCanonicalInductionVariable(); +} + +bool polly::hasInvokeEdge(const PHINode *PN) { + for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) + if (InvokeInst *II = dyn_cast(PN->getIncomingValue(i))) + if (II->getParent() == PN->getIncomingBlock(i)) + return true; + + return false; +} + +BasicBlock *polly::createSingleExitEdge(Region *R, Pass *P) { + BasicBlock *BB = R->getExit(); + + SmallVector Preds; + for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) + if (R->contains(*PI)) + Preds.push_back(*PI); + + return SplitBlockPredecessors(BB, Preds, ".region", P); +} + +void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) { + // Find first non-alloca instruction. Every basic block has a non-alloc + // instruction, as every well formed basic block has a terminator. + BasicBlock::iterator I = EntryBlock->begin(); + while (isa(I)) ++I; + + // SplitBlock updates DT, DF and LI. + BasicBlock *NewEntry = SplitBlock(EntryBlock, I, P); + if (RegionInfo *RI = P->getAnalysisIfAvailable()) + RI->splitBlock(NewEntry, EntryBlock); +} diff --git a/tools/polly/svn.log b/tools/polly/svn.log new file mode 100644 index 00000000000..9a42cfc13a7 --- /dev/null +++ b/tools/polly/svn.log @@ -0,0 +1,3374 @@ +------------------------------------------------------------------------ +r170138 | spop | 2012-12-14 00:52:41 +0800 (Fri, 14 Dec 2012) | 1 line + +isl: detect vector parallelism +------------------------------------------------------------------------ +r170102 | grosser | 2012-12-13 14:24:06 +0800 (Thu, 13 Dec 2012) | 3 lines + +isl: Detect openmp parallelism + +Based on code written by Riyadh Baghdadi. +------------------------------------------------------------------------ +r169487 | andyg | 2012-12-06 15:59:18 +0800 (Thu, 06 Dec 2012) | 1 line + +Integrate polly test-suite into an llvm "make check-all" if built as part of the whole using cmake. +------------------------------------------------------------------------ +r169313 | grosser | 2012-12-05 05:54:37 +0800 (Wed, 05 Dec 2012) | 3 lines + +User isl sha commit id instead of the git tag + +Apperently the git tag causes trouble in some scripts. +------------------------------------------------------------------------ +r169161 | spop | 2012-12-04 05:34:09 +0800 (Tue, 04 Dec 2012) | 1 line + +adapt cloog codegen testcases to isl +------------------------------------------------------------------------ +r169160 | spop | 2012-12-04 05:33:55 +0800 (Tue, 04 Dec 2012) | 1 line + +use -polly-ast instead of -polly-cloog +------------------------------------------------------------------------ +r169159 | spop | 2012-12-04 05:33:40 +0800 (Tue, 04 Dec 2012) | 1 line + +execute cloog specific testcases only with CLOOG_FOUND +------------------------------------------------------------------------ +r169150 | grosser | 2012-12-04 04:47:57 +0800 (Tue, 04 Dec 2012) | 3 lines + +Update CLooG + +This cloog versions passes all tests with isl 0.11. +------------------------------------------------------------------------ +r169127 | grosser | 2012-12-03 22:44:14 +0800 (Mon, 03 Dec 2012) | 4 lines + +Use isl 0.11 + +We now switch to the newly released isl 0.11. This adds a couple of bug fixes +on top of the recent update. +------------------------------------------------------------------------ +r169100 | grosser | 2012-12-02 05:51:10 +0800 (Sun, 02 Dec 2012) | 17 lines + +Update the recommended isl version + +Recent changes in isl: + +- Allow analysis of loops during code generation + +This simplifies the detection of parallel loops. + +- Simplify the way costumized ast printers are defined + +This enables us to highlight parallel / vector loops in our debug output. + +- Compile time improvements for codegen contexts that include parameters + +- Various bug fixes + +This update also gets us in sync for the isl 0.11 release. +------------------------------------------------------------------------ +r168966 | grosser | 2012-11-30 09:05:05 +0800 (Fri, 30 Nov 2012) | 9 lines + +Remove unneeded preservation and restore of ValueMap and ClastVars in GPGPU code +generation. + +We don't use the exact same way to build loop body for GPGPU codegen as openmp +codegen and other transformations do currently, in which cases 'createLoop' +function is called recursively. GPGPU codegen may fail due to improper restore +of ValueMap and ClastVars . + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r168964 | grosser | 2012-11-30 08:39:49 +0800 (Fri, 30 Nov 2012) | 3 lines + +Add an additional input argument according to chanages of function polly::createLoop. + +Contributed-by: Yabin Hu +------------------------------------------------------------------------ +r168903 | grosser | 2012-11-30 01:34:50 +0800 (Fri, 30 Nov 2012) | 3 lines + +Update to Polly for LLVM r165262 which changes TargetData to Datalayout. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r168791 | patha | 2012-11-28 21:30:31 +0800 (Wed, 28 Nov 2012) | 4 lines + +Fix tests with broken datalayout strings. + +Buildbot failure at r168785. + +------------------------------------------------------------------------ +r168780 | grosser | 2012-11-28 18:12:21 +0800 (Wed, 28 Nov 2012) | 6 lines + +cmake: Fix installation of include files + +Install the configured Config/config.h file, rather than the +Config/config.h.cmake and Config/Config.h.in source files. + +Contributed-by: Richard Membarth +------------------------------------------------------------------------ +r168724 | spop | 2012-11-28 05:15:15 +0800 (Wed, 28 Nov 2012) | 1 line + +do not execute the OpenMP tests when cloog is not found +------------------------------------------------------------------------ +r168714 | spop | 2012-11-28 02:50:41 +0800 (Wed, 28 Nov 2012) | 1 line + +make IslAstInfo::printScop compatible with CloogInfo::printScop +------------------------------------------------------------------------ +r168628 | spop | 2012-11-27 07:03:41 +0800 (Tue, 27 Nov 2012) | 1 line + +do not require cloog from configure +------------------------------------------------------------------------ +r168624 | spop | 2012-11-27 06:16:19 +0800 (Tue, 27 Nov 2012) | 5 lines + +fix typo + +Caught while compiling polly without cloog: + +../tools/polly/lib/RegisterPasses.cpp:77: error: use of enum 'CodegenChoice' without previous declaration +------------------------------------------------------------------------ +r168623 | spop | 2012-11-27 06:16:17 +0800 (Tue, 27 Nov 2012) | 6 lines + +remove dependence on CLOOG_FOUND for PollyVectorizerChoice + +When polly was configured with cmake without cloog, compilation stopped with: + +../tools/polly/lib/CodeGen/BlockGenerators.cpp:662: error: 'PollyVectorizerChoice' was not declared in this scope +../tools/polly/lib/CodeGen/BlockGenerators.cpp:662: error: 'VECTORIZER_FIRST_NEED_GROUPED_UNROLL' was not declared in this scope +------------------------------------------------------------------------ +r168621 | spop | 2012-11-27 06:07:30 +0800 (Tue, 27 Nov 2012) | 1 line + +remove dead code +------------------------------------------------------------------------ +r168620 | spop | 2012-11-27 06:07:27 +0800 (Tue, 27 Nov 2012) | 1 line + +remove unused flag +------------------------------------------------------------------------ +r168311 | grosser | 2012-11-19 20:26:25 +0800 (Mon, 19 Nov 2012) | 1 line + +Make polly -Wdocumentation clean +------------------------------------------------------------------------ +r168279 | spop | 2012-11-18 12:34:31 +0800 (Sun, 18 Nov 2012) | 3 lines + +utils: use rmdir instead of rm to remove empty dirs + +as suggested by Sven Verdoolaege +------------------------------------------------------------------------ +r168252 | spop | 2012-11-17 12:57:41 +0800 (Sat, 17 Nov 2012) | 4 lines + +utils: remove the isl directory after cloning cloog + +This fixes my previous commit, thanks to "Dmitry N. Mikushin" + +------------------------------------------------------------------------ +r168250 | spop | 2012-11-17 11:43:48 +0800 (Sat, 17 Nov 2012) | 3 lines + +utils: remove existing cloog and isl dirs before git cloning + +Patch adapted from "Dmitry N. Mikushin" . +------------------------------------------------------------------------ +r168090 | spop | 2012-11-16 05:20:22 +0800 (Fri, 16 Nov 2012) | 5 lines + +autoconf: isl depends on gmp include files + +When libgmp header files are not installed in the default /usr/include location, +configure used to fail to find the gmp headers when testing for isl/ast.h. This +patch adds the gmp include path to the compiler flags before testing for ISL. +------------------------------------------------------------------------ +r167923 | grosser | 2012-11-14 16:25:52 +0800 (Wed, 14 Nov 2012) | 3 lines + +test: LLVM supports now vectors of arbitrary pointers + +This allows Polly to vectorize more code. Fix the relevant test cases. +------------------------------------------------------------------------ +r167372 | grosser | 2012-11-05 00:56:20 +0800 (Mon, 05 Nov 2012) | 4 lines + +Tests: Pipe test files into 'opt' + +Use 'opt < %s' instead of just 'opt %s' to ensure that no temporary files are +created. +------------------------------------------------------------------------ +r167284 | grosser | 2012-11-02 14:09:20 +0800 (Fri, 02 Nov 2012) | 1 line + +Tests: remove ModuleID lines +------------------------------------------------------------------------ +r167283 | grosser | 2012-11-02 14:08:39 +0800 (Fri, 02 Nov 2012) | 1 line + +Tests: move content of .c files in .ll +------------------------------------------------------------------------ +r167255 | grosser | 2012-11-02 05:44:59 +0800 (Fri, 02 Nov 2012) | 5 lines + +Remove runtime tests from polly test suite + +Similar to LLVM we now follow the policy of only having LLVM-IR level tests in +the Polly test suite. Testing for miscompilation of larger programs should be +done with the llvm test suite. +------------------------------------------------------------------------ +r167251 | grosser | 2012-11-02 05:28:32 +0800 (Fri, 02 Nov 2012) | 6 lines + +Dependences: Add support to calculate memory based dependences + +Instead of calculating exact value (flow) dependences, it is also possible to +calculate memory based dependences. Sometimes memory based dependences are a lot +easier to calculate. To evaluate the benefits, we add an option to calculate +memory based dependences (use -polly-value-dependences=false). +------------------------------------------------------------------------ +r167235 | grosser | 2012-11-02 00:45:20 +0800 (Fri, 02 Nov 2012) | 9 lines + +ScopDetection: Print line numbers of detected scops + +If the flags '-polly-report -g' are given, we print file name and line numbers +for the beginning and end of all detected scops. + + linear-algebra/kernels/gemm/gemm.c:23: Scop start + linear-algebra/kernels/gemm/gemm.c:42: Scop end + linear-algebra/kernels/gemm/gemm.c:77: Scop start + linear-algebra/kernels/gemm/gemm.c:82: Scop end +------------------------------------------------------------------------ +r167234 | grosser | 2012-11-02 00:45:18 +0800 (Fri, 02 Nov 2012) | 1 line + +Revert multiple adress space changes in Polly +------------------------------------------------------------------------ +r167215 | grosser | 2012-11-01 13:34:55 +0800 (Thu, 01 Nov 2012) | 14 lines + +Codegen: Selectively copy in array addresses for OpenMP code + +The detection of values that need to be copied in to the generated OpenMP +subfunction also detects the array base addresses needed in the SCoP. Hence, it +is not necessary to unconditionally copy all the base addresses to the generated +function. + +Test cases are modified to reflect this change. Arrays which are global +variables do not occur in the struct passed to the subfunction anymore. A test +case for base address copy-in is added in copy_in_array.{c,ll}. + +Committed with slight modifications + +Contributed by: Armin Groesslinger +------------------------------------------------------------------------ +r167214 | grosser | 2012-11-01 13:34:48 +0800 (Thu, 01 Nov 2012) | 10 lines + +CodeGen: Add scop-parameters to the OpenMP context + +In addition to the arrays and clast variables a SCoP statement may also refer to +values defined before the SCoP or to function arguments. Detect these values and +add them to the set of values passed to the function generated for OpenMP +parallel execution of a clast. + +Committed with additional test cases and some refactoring. + +Contributed by: Armin Groesslinger +------------------------------------------------------------------------ +r167213 | grosser | 2012-11-01 13:34:35 +0800 (Thu, 01 Nov 2012) | 9 lines + +Codegen: Copy and restore the ValueMap and ClastVars explicitly + +When generating OpenMP or GPGPU code the original ValueMap and ClastVars must be +kept. We already recovered the original ClastVars by reverting the changes, but +we did not keep the content of the ValueMap. This patch keeps now an explicit +copy of both maps and restores them after generating OpenMP or GPGPU code. + +This is an adapted version of a patch contributed by: +Armin Groesslinger +------------------------------------------------------------------------ +r166670 | chandlerc | 2012-10-25 16:43:18 +0800 (Thu, 25 Oct 2012) | 4 lines + +Another speculative commit to try to fix Polly's build. This is more delta than +I like to make w/o being able to build, but I don't have the dependencies to +build and test polly. I'll revert if the build bots don't like it. + +------------------------------------------------------------------------ +r166668 | chandlerc | 2012-10-25 15:42:03 +0800 (Thu, 25 Oct 2012) | 2 lines + +Another fix for a build-bot reported API mismatch. + +------------------------------------------------------------------------ +r166666 | chandlerc | 2012-10-25 15:25:56 +0800 (Thu, 25 Oct 2012) | 2 lines + +Try to revive the Polly builders after this LLVM API change. + +------------------------------------------------------------------------ +r166403 | grosser | 2012-10-22 05:48:21 +0800 (Mon, 22 Oct 2012) | 5 lines + +autoconf/cmake: Always require isl code generation. + +This change ensures that isl is only detected if it includes code generation +support. This allows us to remove a lot of conditional compilation and also +avoids missing test cases in case the feature is not available. +------------------------------------------------------------------------ +r166402 | grosser | 2012-10-22 05:08:29 +0800 (Mon, 22 Oct 2012) | 12 lines + +cmake: Use suffix for shared modules instead of the one for shared libraries + +On Linux there is no difference between shared modules and shared libaries, both +are '.so' files. However, on darwin only shared modules are '.so' files. Shared +libraries have the '.dynlib' suffix. + +Fix test cases on darwin by expecting a shared module suffix for Polly instead +of a shared library suffix. + +This fixes PR14135 + +Reported by: Jack Howarth +------------------------------------------------------------------------ +r166397 | grosser | 2012-10-22 02:31:27 +0800 (Mon, 22 Oct 2012) | 1 line + +RegisterPasses: Remove unreachable default case in switch +------------------------------------------------------------------------ +r166396 | grosser | 2012-10-22 01:33:00 +0800 (Mon, 22 Oct 2012) | 3 lines + +www: Correct command line that loads polly into dragonegg + +Reported by: Jack Howarth +------------------------------------------------------------------------ +r166394 | grosser | 2012-10-21 23:51:49 +0800 (Sun, 21 Oct 2012) | 3 lines + +Introduce a separate file for CMake macros + +Contributed by: Sameer Sahasrabuddhe +------------------------------------------------------------------------ +r166021 | grosser | 2012-10-16 15:29:19 +0800 (Tue, 16 Oct 2012) | 7 lines + +isl scheduler: Do not fail when returning an empty band list + +The bug was within isl. To fix it, we simply update the isl version that +is used by Polly. We still have some changes within Polly to be able to +write a proper test case. + +Reported-by: Sameer Sahasrabuddhe +------------------------------------------------------------------------ +r166020 | grosser | 2012-10-16 15:29:13 +0800 (Tue, 16 Oct 2012) | 5 lines + +isl-codegen: Support '<' and '>' + +Previously isl always generated '<=' or '>='. However, in many cases '<' or '>' +leads to simpler code. This commit updates isl and adds the relevant code +generation support to Polly. +------------------------------------------------------------------------ +r165789 | grosser | 2012-10-12 15:44:38 +0800 (Fri, 12 Oct 2012) | 1 line + +www: Clarify that GMP is LGPL licensed +------------------------------------------------------------------------ +r165481 | sameerds | 2012-10-09 12:59:42 +0800 (Tue, 09 Oct 2012) | 2 lines + +Trivial change to the README, mainly to test commit access. + +------------------------------------------------------------------------ +r165408 | mvillmow | 2012-10-09 01:26:19 +0800 (Tue, 09 Oct 2012) | 1 line + +Move TargetData to DataLayout to fix build breakage caused by LLVM r16540 +------------------------------------------------------------------------ +r165387 | grosser | 2012-10-08 16:56:52 +0800 (Mon, 08 Oct 2012) | 3 lines + +Rename TargetData -> DataLayout + +Contributed by: Sameer Sahasrabuddhe +------------------------------------------------------------------------ +r165379 | grosser | 2012-10-08 01:43:23 +0800 (Mon, 08 Oct 2012) | 10 lines + +ScopLib: Support negated access functions. + +Scoplib only supports access functions, but not the more generic +access relations. This commit now also supports access functions +that where not directly expresses as A[sub] with sub = i + 5b, +but with A[sub] with -sub = -i + (-5b). + +Test case to come. + +Contributed by: Dustin Feld +------------------------------------------------------------------------ +r165378 | grosser | 2012-10-08 01:43:18 +0800 (Mon, 08 Oct 2012) | 1 line + +Update the 'News' section on the Polly page +------------------------------------------------------------------------ +r165037 | grosser | 2012-10-03 03:50:43 +0800 (Wed, 03 Oct 2012) | 6 lines + +Add a new isl based code generation + +This pass implements a new code generator that uses the code generation +algorithm included in isl. + +For the moment the new code generation is limited to sequential code. +------------------------------------------------------------------------ +r165036 | grosser | 2012-10-03 03:50:38 +0800 (Wed, 03 Oct 2012) | 1 line + +Add an ast pretty printer pass based on the isl code generator +------------------------------------------------------------------------ +r165035 | grosser | 2012-10-03 03:50:30 +0800 (Wed, 03 Oct 2012) | 1 line + +Update isl to get the new code generation +------------------------------------------------------------------------ +r165034 | grosser | 2012-10-03 03:50:22 +0800 (Wed, 03 Oct 2012) | 1 line + +Detect the isl code generation feature correctly +------------------------------------------------------------------------ +r164376 | grosser | 2012-09-22 00:24:13 +0800 (Sat, 22 Sep 2012) | 4 lines + +Bailout if libpluto finds no schedule + +Older versions of libpluto crashed, if no schedule was found. Recent +versions return NULL. We detect this and keep the original schedule. +------------------------------------------------------------------------ +r163619 | grosser | 2012-09-11 22:03:19 +0800 (Tue, 11 Sep 2012) | 6 lines + +Add test cases for multi-dimensional variable lengths arrays + +At the moment we can handle such arrays only by conservatively assuming that +each access to such an array may touch any element in the array. It would be +great if we could improve Polly/LLVM at some point, such that we can +recover the multi-dimensionality of the accesses. +------------------------------------------------------------------------ +r163618 | grosser | 2012-09-11 21:50:21 +0800 (Tue, 11 Sep 2012) | 5 lines + +ScopInfo: Align parameters when using -polly-allow-nonaffine + +This ensures that the isl sets/maps we operate on have the same parameter +dimensions. Operations on objects with different parameter dimensions are not +allow and trigger assertions. +------------------------------------------------------------------------ +r163472 | grosser | 2012-09-08 22:00:37 +0800 (Sat, 08 Sep 2012) | 1 line + +SCEVValidator: Add debug output that gives the reason for invalid expressions +------------------------------------------------------------------------ +r163471 | grosser | 2012-09-08 22:00:32 +0800 (Sat, 08 Sep 2012) | 3 lines + +Remove dead code + +This code has been replaced by the SCEVValidator a while ago. +------------------------------------------------------------------------ +r163466 | grosser | 2012-09-08 16:31:55 +0800 (Sat, 08 Sep 2012) | 3 lines + +ScopGraphPrinter: Escape error message + +Otherwise a '"' in the error message, yields an invalid .dot file. +------------------------------------------------------------------------ +r163130 | grosser | 2012-09-04 16:19:12 +0800 (Tue, 04 Sep 2012) | 7 lines + +Add dependency to intrinsics_gen + +The IndVarSimplify pass in Polly uses the intrinsics header. We need to ensure +that the header is generated, before we use it. This patch fixes the problem +for the cmake build (it did not show up in the autoconf one). + +Contributed by: Sameer Sahasrabuddhe +------------------------------------------------------------------------ +r163108 | grosser | 2012-09-03 15:42:40 +0800 (Mon, 03 Sep 2012) | 5 lines + +Update isl to a newer version + +This fixes some undefined behavior in isl. + +Reported by: Sameer Sahasrabuddhe +------------------------------------------------------------------------ +r162901 | grosser | 2012-08-30 19:49:38 +0800 (Thu, 30 Aug 2012) | 10 lines + +Pocc: Fix some bugs in the PoCC optimizer pass + +This includes: + - The isl_id of the domain of the scattering must be copied from the original + domain + - Remove outdated references to a 'FinalRead' statement + - Print of the Pocc output, if -debug is provided. + - Add line breaks to some error messages. + +Reported and Debugged by: Dustin Feld +------------------------------------------------------------------------ +r162900 | grosser | 2012-08-30 19:49:31 +0800 (Thu, 30 Aug 2012) | 1 line + +Pluto: Print pluto input in debugging mode +------------------------------------------------------------------------ +r162662 | grosser | 2012-08-27 16:44:15 +0800 (Mon, 27 Aug 2012) | 4 lines + +Dependences: Print dependences in -analyze output + +The dependency printing was accidentally removed in during a previous +restructuring. +------------------------------------------------------------------------ +r162555 | grosser | 2012-08-24 21:56:56 +0800 (Fri, 24 Aug 2012) | 1 line + +PoCC: Simplify condition +------------------------------------------------------------------------ +r162554 | grosser | 2012-08-24 21:54:40 +0800 (Fri, 24 Aug 2012) | 1 line + +Sort includes +------------------------------------------------------------------------ +r162553 | grosser | 2012-08-24 21:54:36 +0800 (Fri, 24 Aug 2012) | 1 line + +PoCC: Adapt to earlier vectorizer changes +------------------------------------------------------------------------ +r162275 | grosser | 2012-08-21 20:29:10 +0800 (Tue, 21 Aug 2012) | 7 lines + +autoconf: Only define GPGPU_CODEGEN, if that feature is requested + +Before we defined GPGPU_CODEGEN to '0', which does not disable the relevant code +as we just check if that value is defined at all. We now follow the cmake +approach and only define GPGPU_CODEGEN, if the feature should be enabled. + +Reported by: Sebastian Pop +------------------------------------------------------------------------ +r161930 | grosser | 2012-08-15 13:50:24 +0800 (Wed, 15 Aug 2012) | 1 line + +Remove executable bits from html files +------------------------------------------------------------------------ +r161928 | grosser | 2012-08-15 13:02:25 +0800 (Wed, 15 Aug 2012) | 9 lines + +www documentation for using Polly with dragonegg. + +Added a file that explains how to load Polly in dragonegg. +Also fixed a typo in the document for clang. + +Committed with a typo fix and a change to make this website available from +the documentation section. + +Contributed by: Sameer Sahasrabuddhe +------------------------------------------------------------------------ +r161239 | grosser | 2012-08-03 20:50:07 +0800 (Fri, 03 Aug 2012) | 19 lines + +Add preliminary implementation for GPGPU code generation. + +Translate the selected parallel loop body into a ptx string and run it with the +cuda driver API. We limit this preliminary implementation to target the +following special test cases: + + - Support only 2-dimensional parallel loops with or without only one innermost + non-parallel loop. + - Support write memory access to only one array in a SCoP. + +The patch was committed with smaller changes to the build system: + +There is now a flag to enable gpu code generation explictly. This was required +as we need the llvm.codegen() patch applied on the llvm sources, to compile this +feature correctly. Also, enabling gpu code generation does not require cuda. +This requirement was removed to allow 'make polly-test' runs, even without an +installed cuda runtime. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r161235 | grosser | 2012-08-03 16:11:24 +0800 (Fri, 03 Aug 2012) | 6 lines + +Remove 'using namespace llvm' from header file + +This fixes a conflict between polly::createIndVarSimplifyPass() and +llvm::createIndVarSimplifyPass(), which causes problems on windows. + +Reported by: Michael Kruse +------------------------------------------------------------------------ +r161160 | grosser | 2012-08-02 16:16:40 +0800 (Thu, 02 Aug 2012) | 3 lines + +Update llvm.codegen() patch for CodeGen.cpp changes in r159694. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r161158 | grosser | 2012-08-02 15:47:37 +0800 (Thu, 02 Aug 2012) | 1 line + +Add missing dependency to cmake system +------------------------------------------------------------------------ +r161157 | grosser | 2012-08-02 15:47:26 +0800 (Thu, 02 Aug 2012) | 1 line + +Add support for libpluto as the scheduling optimizer. +------------------------------------------------------------------------ +r161105 | ether | 2012-08-01 16:46:11 +0800 (Wed, 01 Aug 2012) | 6 lines + +IndependentBLocks: Do not visit the same instruction twice when moving the + operand tree. + +This patch fix Bug 13491, and the original "FIXME" in IndependentBlocks.cpp. + +Patched by Kevin Fan. +------------------------------------------------------------------------ +r160677 | grosser | 2012-07-25 00:58:57 +0800 (Wed, 25 Jul 2012) | 4 lines + +Create a new directory before running the polly script + +Otherwise the script spams the home directory and, in case there are folders +of previous attempts lying around, it may fail in some unexpected way. +------------------------------------------------------------------------ +r160261 | grosser | 2012-07-16 18:57:32 +0800 (Mon, 16 Jul 2012) | 9 lines + +Allow cast instructions within scops + +Cast instruction do not have side effects and can consequently be part of a +scop. We special cased them earlier, as they may be problematic within array +subscripts or loop bounds. However, the scalar evolution validator already +checks for them such that there is no need to also check the instructions within +the basic blocks. Checking them is actually overly conservative as the precence +of casts may invalidate a scop, even though scalar evolution is not influenced +by it. +------------------------------------------------------------------------ +r160165 | grosser | 2012-07-13 15:44:56 +0800 (Fri, 13 Jul 2012) | 9 lines + +Revert "Add preliminary implementation for GPGPU code generation." + +I did not take into account, that this patch fails to compile without the +llvm.codegen patch applied. This breaks buildbots. + +I revert this until we found a solution to commit this without buildbots +complaining. + +This reverts commit cb43ab80e94434e780a66be3b9a6ad466822fe33. +------------------------------------------------------------------------ +r160164 | grosser | 2012-07-13 15:21:00 +0800 (Fri, 13 Jul 2012) | 10 lines + +Add preliminary implementation for GPGPU code generation. + +Translate the selected parallel loop body into a ptx string and run it +with cuda driver API. We limit this preliminary implementation to +target the following special test cases: + - Support only 2-dimensional parallel loops with or without only one + innermost non-parallel loop. + - Support write memory access to only one array in a SCoP. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r159815 | grosser | 2012-07-06 18:40:15 +0800 (Fri, 06 Jul 2012) | 3 lines + +Update libGPURuntime to be dual licensed under MIT and UIUC license. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r159808 | ether | 2012-07-06 14:47:03 +0800 (Fri, 06 Jul 2012) | 2 lines + +Add an Instruction member to MemoryAccess Class. + Patched by TangKK . +------------------------------------------------------------------------ +r159735 | ether | 2012-07-05 16:55:31 +0800 (Thu, 05 Jul 2012) | 2 lines + +Add stringFromIslObj support for various isl_objs. + Patched by JunQi. +------------------------------------------------------------------------ +r159734 | ether | 2012-07-05 16:42:39 +0800 (Thu, 05 Jul 2012) | 1 line + +Refactor: Use generic internal function template in GICHelper.cpp to avoid duplication. +------------------------------------------------------------------------ +r159725 | grosser | 2012-07-05 05:45:03 +0800 (Thu, 05 Jul 2012) | 3 lines + +Replace CUDA data types with Polly's GPGPU data types. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r159650 | grosser | 2012-07-03 16:18:34 +0800 (Tue, 03 Jul 2012) | 1 line + +codegen.intrinsic: Update testcase to work with NVPTX backend +------------------------------------------------------------------------ +r159649 | grosser | 2012-07-03 16:18:31 +0800 (Tue, 03 Jul 2012) | 3 lines + +Update to Polly for LLVM r159614 which changes Passes.cpp. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r159507 | grosser | 2012-07-01 21:47:50 +0800 (Sun, 01 Jul 2012) | 3 lines + +Update to Polly for LLVM r159383 which changes SelectionDAGBuilder.cpp. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r159423 | chandlerc | 2012-06-29 20:39:49 +0800 (Fri, 29 Jun 2012) | 2 lines + +Speculative update to Polly for LLVM r159421 which moved IRBuilder.h. + +------------------------------------------------------------------------ +r158987 | grosser | 2012-06-22 18:59:36 +0800 (Fri, 22 Jun 2012) | 1 line + +Add TempScop::isWrite() function. +------------------------------------------------------------------------ +r158306 | grosser | 2012-06-11 18:25:12 +0800 (Mon, 11 Jun 2012) | 1 line + +Add some tests for the independent blocks pass. +------------------------------------------------------------------------ +r158304 | grosser | 2012-06-11 17:25:01 +0800 (Mon, 11 Jun 2012) | 3 lines + +Add the runtime library for GPGPU code generation. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r158081 | grosser | 2012-06-07 00:33:15 +0800 (Thu, 07 Jun 2012) | 1 line + +Fix some coding convention problems. +------------------------------------------------------------------------ +r158064 | grosser | 2012-06-06 20:16:10 +0800 (Wed, 06 Jun 2012) | 5 lines + +Detect the cuda library available. + +We will use the cuda library for the upcoming automatic GPGPU code generation. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r158015 | grosser | 2012-06-06 03:31:08 +0800 (Wed, 06 Jun 2012) | 15 lines + +CLooG: Do not take into account the context + +CLooG and the CLooG based code generation does not yet correctly derive the +types of the expressions, but just uses i64 for everything. This is incorrect, +but works normally pretty well. However, the recent change of adding parameter +bounds to the context made CLooG generate expressions that contain a lot of very +large integers that possibly don't fit into an i64. This broke the code +generation for several benchmarks. + +To get the CLooG based code generation working again, we just don't take into +account any constraints in the context. This brings us back to the theoretical +incorrect, but in practice generally correct code. + +The next step will be the isl based code generation. Here we will derive +automatically correct types. +------------------------------------------------------------------------ +r157690 | grosser | 2012-05-30 21:54:02 +0800 (Wed, 30 May 2012) | 1 line + +www: Add GPGPU Code Generation Documentation. +------------------------------------------------------------------------ +r157689 | grosser | 2012-05-30 21:53:57 +0800 (Wed, 30 May 2012) | 5 lines + +Add llvm.codegen intrinsic patch file to polly/utils. + +The "llvm.codegen" intrinsic patch is a patch to LLVM, which is used +to generate code for embedded LLVM-IR strings. In Polly, we use it +to generate ptx assembly text for GPGPU code generation. +------------------------------------------------------------------------ +r157607 | grosser | 2012-05-29 17:29:44 +0800 (Tue, 29 May 2012) | 5 lines + +ScopInfo: Store ScopStmt pointer in the domain + +Store a pointer to each ScopStmt in the isl_id associated with the space of its +domain. This will later allow us to recover the statement during code +generation with isl. +------------------------------------------------------------------------ +r157606 | grosser | 2012-05-29 17:11:59 +0800 (Tue, 29 May 2012) | 3 lines + +Mark the increments of the generated induction variables 'NSW' + +In general, all code that we produce is NSW. +------------------------------------------------------------------------ +r157605 | grosser | 2012-05-29 17:11:54 +0800 (Tue, 29 May 2012) | 3 lines + +Move executeScopConditionally() into its own file + +We will reuse this function for the isl code generator. +------------------------------------------------------------------------ +r157604 | grosser | 2012-05-29 17:11:46 +0800 (Tue, 29 May 2012) | 1 line + +Move CLooG.h into include/polly/CodeGen/ +------------------------------------------------------------------------ +r157246 | grosser | 2012-05-22 18:47:31 +0800 (Tue, 22 May 2012) | 3 lines + +ScheduleOptimizer: Simplify some code + +We now use isl_map_equate, which makes the code a lot simpler. +------------------------------------------------------------------------ +r157245 | grosser | 2012-05-22 18:47:27 +0800 (Tue, 22 May 2012) | 5 lines + +ScopInfo: Add parameter bounds to context + +Derive the maximal and minimal values of a parameter from the type it has. Add +this information to the scop context. This information is needed, to derive +optimal types during code generation. +------------------------------------------------------------------------ +r157244 | grosser | 2012-05-22 18:47:21 +0800 (Tue, 22 May 2012) | 1 line + +Replace some asserts with llvm_unreachable +------------------------------------------------------------------------ +r157243 | grosser | 2012-05-22 18:47:17 +0800 (Tue, 22 May 2012) | 5 lines + +ScopInfo: SCEVUnknowns are always parameters + +There is no need for special code to handle SCEVUnknowns. SCEVUnkowns are always +parameters and will be handled by the generic parameter handling code in +visit(). +------------------------------------------------------------------------ +r157242 | grosser | 2012-05-22 16:46:07 +0800 (Tue, 22 May 2012) | 3 lines + +Move isParallelFor into CodeGeneration + +This removes another include of CLooG header files. +------------------------------------------------------------------------ +r156326 | spop | 2012-05-08 05:27:11 +0800 (Tue, 08 May 2012) | 1 line + +make registerPollyPreoptPasses static +------------------------------------------------------------------------ +r156325 | spop | 2012-05-08 05:27:09 +0800 (Tue, 08 May 2012) | 1 line + +make registerPollyPasses static, remove param +------------------------------------------------------------------------ +r156306 | spop | 2012-05-08 00:35:11 +0800 (Tue, 08 May 2012) | 1 line + +add some more missing ifdef CLOOG_FOUND +------------------------------------------------------------------------ +r156305 | spop | 2012-05-08 00:20:07 +0800 (Tue, 08 May 2012) | 1 line + +add a check for ISL codegen at configure time +------------------------------------------------------------------------ +r156256 | ether | 2012-05-06 18:22:57 +0800 (Sun, 06 May 2012) | 1 line + +WWW: Adapt the vectorize option change. +------------------------------------------------------------------------ +r156255 | ether | 2012-05-06 18:22:43 +0800 (Sun, 06 May 2012) | 1 line + +Regression tests: Adapt the vectorize option change. +------------------------------------------------------------------------ +r156254 | ether | 2012-05-06 18:22:19 +0800 (Sun, 06 May 2012) | 1 line + +Allow polly ask bb-vectorizer to vectorize the loop body. +------------------------------------------------------------------------ +r156210 | spop | 2012-05-05 05:36:08 +0800 (Sat, 05 May 2012) | 1 line + +fix typo +------------------------------------------------------------------------ +r156207 | chandlerc | 2012-05-05 05:24:27 +0800 (Sat, 05 May 2012) | 2 lines + +Try to fix the Polly build while I'm trying to get it to build at all locally. + +------------------------------------------------------------------------ +r156203 | chandlerc | 2012-05-05 04:57:29 +0800 (Sat, 05 May 2012) | 2 lines + +Update Polly to match the LLVM interface change in r156196. + +------------------------------------------------------------------------ +r156199 | spop | 2012-05-05 04:30:03 +0800 (Sat, 05 May 2012) | 1 line + +compile cloog code only when CLOOG_FOUND is set +------------------------------------------------------------------------ +r156184 | spop | 2012-05-05 02:15:57 +0800 (Sat, 05 May 2012) | 1 line + +move Cloog.cpp to CodeGen +------------------------------------------------------------------------ +r156171 | grosser | 2012-05-04 20:11:01 +0800 (Fri, 04 May 2012) | 3 lines + +Fix typo. + +Reported by: Andreas Simbuerger +------------------------------------------------------------------------ +r156170 | grosser | 2012-05-04 19:26:52 +0800 (Fri, 04 May 2012) | 1 line + +ScopDection: Improve status message for non-affine memory accesses. +------------------------------------------------------------------------ +r155863 | grosser | 2012-05-01 07:49:05 +0800 (Tue, 01 May 2012) | 3 lines + +Remove unused function + +Suggested by: Sebastian Pop +------------------------------------------------------------------------ +r155717 | grosser | 2012-04-28 00:36:14 +0800 (Sat, 28 Apr 2012) | 7 lines + +SCEV based code generation + +This is an incomplete implementation of the SCEV based code generation. +When finished it will remove the need for -indvars -enable-iv-rewrite. + +For the moment it is still disabled. Even though it passes 'make polly-test', +there are still loose ends especially in respect of OpenMP code generation. +------------------------------------------------------------------------ +r155636 | ether | 2012-04-26 21:55:33 +0800 (Thu, 26 Apr 2012) | 2 lines + +1. Add a header guard for RegisterPasses.h to prevent multiple inclusion. + 2. Include the helper function and the helper class in the RegisterPasses.h into the polly namespace. +------------------------------------------------------------------------ +r155634 | grosser | 2012-04-26 21:43:03 +0800 (Thu, 26 Apr 2012) | 1 line + +Further simplify parallelism test +------------------------------------------------------------------------ +r155548 | grosser | 2012-04-25 21:22:43 +0800 (Wed, 25 Apr 2012) | 1 line + +ScheduleOptimizer: Move functions into class +------------------------------------------------------------------------ +r155547 | ether | 2012-04-25 21:18:28 +0800 (Wed, 25 Apr 2012) | 1 line + +Refactor: Move the code generation related header files to include/polly/CodeGen. +------------------------------------------------------------------------ +r155546 | ether | 2012-04-25 21:16:49 +0800 (Wed, 25 Apr 2012) | 2 lines + +Refactor: Move the declaration of the BlockGenerator/VectorBlockGenerator + to standalone header and source files. +------------------------------------------------------------------------ +r155544 | ether | 2012-04-25 17:34:33 +0800 (Wed, 25 Apr 2012) | 3 lines + +ScopStmt: Provide a function to allow users look up the corresponding + memory access of a particular instruction, the function will return + null if no such memory access. +------------------------------------------------------------------------ +r155539 | ether | 2012-04-25 16:01:38 +0800 (Wed, 25 Apr 2012) | 2 lines + +Minor change: Replace convertInt in ScopInfo.cpp by utostr_32, which is + defined in StringExtras.h. +------------------------------------------------------------------------ +r155446 | grosser | 2012-04-25 00:12:34 +0800 (Wed, 25 Apr 2012) | 4 lines + +Simplify import/export command line flags. + +Instead of -polly-run-import-jscop and -polly-run-export-jscop, we just use +-polly-import and -polly-export. +------------------------------------------------------------------------ +r155445 | grosser | 2012-04-25 00:12:30 +0800 (Wed, 25 Apr 2012) | 4 lines + +Unify the optimizer selection. + +We now support -polly-optimizer=isl, -polly-optimizer=pocc and +-polly-optimizer=none. The option -polly-no-optimizer is gone. +------------------------------------------------------------------------ +r155438 | grosser | 2012-04-24 19:08:07 +0800 (Tue, 24 Apr 2012) | 1 line + +Make vector tests less sensible to codegen changes +------------------------------------------------------------------------ +r155349 | ether | 2012-04-23 21:03:56 +0800 (Mon, 23 Apr 2012) | 2 lines + +Refactor: Pass the argument 'IRBuilder' and 'AfterBlock' of function 'createLoop' by + reference, so that we do not need to type an extra '&' operator when calling the function. +------------------------------------------------------------------------ +r155348 | ether | 2012-04-23 21:03:43 +0800 (Mon, 23 Apr 2012) | 2 lines + +1. Add a header guard for LoopGenerators.h to prevent multiple inclusion. +2. Include the helper function and the helper class in the LoopGenerator.h into the polly namespace. +------------------------------------------------------------------------ +r155135 | grosser | 2012-04-20 00:38:16 +0800 (Fri, 20 Apr 2012) | 4 lines + +Dependences: Rework parallelism check + +After working and explaining this function to someone, I realized it could be +simplified and better documented. +------------------------------------------------------------------------ +r154952 | grosser | 2012-04-18 05:38:20 +0800 (Wed, 18 Apr 2012) | 1 line + +www: Update matmul example slightly. +------------------------------------------------------------------------ +r154808 | grosser | 2012-04-16 19:06:06 +0800 (Mon, 16 Apr 2012) | 1 line + +ScheduleOpt: Fix crash with -enable-polly-vector +------------------------------------------------------------------------ +r154586 | grosser | 2012-04-12 18:46:55 +0800 (Thu, 12 Apr 2012) | 5 lines + +CodeGen: Generate scalar code if vector instructions cannot be generated + +This fixes two crashes that appeared in case of: + - A load of a non vectorizable type (e.g. float**) + - An instruction that is not vectorizable (e.g. call) +------------------------------------------------------------------------ +r154487 | ether | 2012-04-11 15:43:24 +0800 (Wed, 11 Apr 2012) | 3 lines + +Revert "Make the "all" target depend on polly-test, so that users can run regression" + +This reverts commit 97bd8d50881000c11b65b0e033996ec5f57bcd15. +------------------------------------------------------------------------ +r154486 | ether | 2012-04-11 15:43:13 +0800 (Wed, 11 Apr 2012) | 3 lines + +Revert "Fix a bug introduced by r153739: We are not able to provide the correct" + +This reverts commit 2c6bdbf972ac966498489d30a33bfd252df9107d. +------------------------------------------------------------------------ +r154415 | grosser | 2012-04-11 02:12:19 +0800 (Wed, 11 Apr 2012) | 3 lines + +Fix typo + +Suggested by: Sebastian Pop +------------------------------------------------------------------------ +r154337 | grosser | 2012-04-10 03:46:05 +0800 (Tue, 10 Apr 2012) | 3 lines + +Fix typos. + +Pointed out by: Sebastian Pop +------------------------------------------------------------------------ +r154260 | ether | 2012-04-07 23:14:28 +0800 (Sat, 07 Apr 2012) | 2 lines + +Rewritten expandRegion to clarify the intention and improve + performance, patched by Johannes Doerfert . +------------------------------------------------------------------------ +r154259 | ether | 2012-04-07 20:29:27 +0800 (Sat, 07 Apr 2012) | 1 line + +ScopDetection: Add some comments to function "expandRegion". +------------------------------------------------------------------------ +r154258 | ether | 2012-04-07 20:29:17 +0800 (Sat, 07 Apr 2012) | 2 lines + +Speed up SCoP detection time by checking the exit of the region first, + patched by Johannes Doerfert . +------------------------------------------------------------------------ +r154251 | grosser | 2012-04-07 14:16:08 +0800 (Sat, 07 Apr 2012) | 7 lines + +CodeGen: Allow Polly to do 'grouped unrolling', but no vector generation. + +Grouped unrolling means that we unroll a loop such that the different instances +of a certain statement are scheduled right after each other, but we do +not generate any vector code. The idea here is that we can schedule the +bb vectorizer right afterwards and use it heuristics to decide when +vectorization should be performed. +------------------------------------------------------------------------ +r154162 | ether | 2012-04-06 11:56:27 +0800 (Fri, 06 Apr 2012) | 6 lines + +Fix a bug introduced by r153739: We are not able to provide the correct + dependent list for target polly-test, hence making "all" from the top + of llvm build directory will cause the target "polly-test" being built + before its dependencing target built. + +Patched by Sebastian Pop +------------------------------------------------------------------------ +r153954 | grosser | 2012-04-03 20:37:14 +0800 (Tue, 03 Apr 2012) | 1 line + +CodeGen: Remove unused declaration +------------------------------------------------------------------------ +r153952 | grosser | 2012-04-03 20:24:32 +0800 (Tue, 03 Apr 2012) | 12 lines + +CodeGen: Recreate old ivs with the original type + +To avoid overflows we still use a larger type (i64) while calculating the value +of the old ivs. However, we truncate the result to the type of the old iv when +providing it to the new code. + +A corresponding test case is added to the polly test suite. Also, a failing test +case is fixed. + +This fixes PR12311. + +Contributed by: Tsingray Liu +------------------------------------------------------------------------ +r153948 | ether | 2012-04-03 17:15:52 +0800 (Tue, 03 Apr 2012) | 1 line + +www: Fix typo, replace "LD_LBIRARY_PATH" by "LD_LIBRARY_PATH" in get_started. +------------------------------------------------------------------------ +r153936 | ether | 2012-04-03 14:29:27 +0800 (Tue, 03 Apr 2012) | 1 line + +www: Append path instead overwrite path when exporting the path of pocc. +------------------------------------------------------------------------ +r153934 | ether | 2012-04-03 12:39:47 +0800 (Tue, 03 Apr 2012) | 2 lines + +www: Fix typo in the setting LD_LBIRARY_PATH command, as pointed out by + Dmitry N. Mikushin. +------------------------------------------------------------------------ +r153871 | grosser | 2012-04-02 20:26:13 +0800 (Mon, 02 Apr 2012) | 1 line + +CodeGen: Some style improvements +------------------------------------------------------------------------ +r153840 | grosser | 2012-04-02 00:55:30 +0800 (Mon, 02 Apr 2012) | 1 line + +CodeGen: Remove unused variable +------------------------------------------------------------------------ +r153839 | grosser | 2012-04-02 00:49:48 +0800 (Mon, 02 Apr 2012) | 1 line + +Remove unneeded alias analysis +------------------------------------------------------------------------ +r153838 | grosser | 2012-04-02 00:49:45 +0800 (Mon, 02 Apr 2012) | 11 lines + +CodeGen: Allow function parameters to be rewritten in getNewValue() + +When deriving new values for the statements of a SCoP, we assumed that parameter +values are constant within the SCoP and consquently do not need to be rewritten. +For OpenMP code generation this assumption is wrong, as such values are not +available in the OpenMP subfunction and consequently also may need to be +rewritten. + +Committed with some changes. + +Contributed-By: Johannes Doerfert +------------------------------------------------------------------------ +r153739 | ether | 2012-03-30 17:27:16 +0800 (Fri, 30 Mar 2012) | 3 lines + +Make the "all" target depend on polly-test, so that users can run regression + tests by simply typing "make -C tools/polly/test", like llvm's regression + tests. +------------------------------------------------------------------------ +r153738 | ether | 2012-03-30 17:27:07 +0800 (Fri, 30 Mar 2012) | 1 line + +Autoconf build: Try to update LLVMPolly.so before running regression tests +------------------------------------------------------------------------ +r153736 | ether | 2012-03-30 16:46:18 +0800 (Fri, 30 Mar 2012) | 2 lines + +Move the CodeGeneration.cpp to the CodeGen folder and update the build system. + Patched by Tsingray. +------------------------------------------------------------------------ +r153734 | ether | 2012-03-30 16:18:19 +0800 (Fri, 30 Mar 2012) | 2 lines + +Get started guide: Suggest users to append the parent directory of cloog + libraries to LD_LIBRARY_PATH. +------------------------------------------------------------------------ +r153664 | grosser | 2012-03-30 01:53:54 +0800 (Fri, 30 Mar 2012) | 1 line + +www: Add more missing features to the TODO list +------------------------------------------------------------------------ +r153647 | grosser | 2012-03-29 21:10:34 +0800 (Thu, 29 Mar 2012) | 6 lines + +www: Update TODO list + +- Link to several new bug reports that describe problems in more detail +- Add some more items +- Remove owners for inactive projects. This just blocks other people +- Rename 'middle part' to 'optimizer' +------------------------------------------------------------------------ +r153646 | grosser | 2012-03-29 21:10:30 +0800 (Thu, 29 Mar 2012) | 1 line + +www: Link to console view with only polly buildbots +------------------------------------------------------------------------ +r153645 | grosser | 2012-03-29 21:10:26 +0800 (Thu, 29 Mar 2012) | 1 line + +CodeGeneration: Proberly build the dominator tree +------------------------------------------------------------------------ +r153644 | ether | 2012-03-29 21:10:10 +0800 (Thu, 29 Mar 2012) | 1 line + +Use python script to silence the expected testcase fails on 32bit platform. +------------------------------------------------------------------------ +r153642 | ether | 2012-03-29 20:36:52 +0800 (Thu, 29 Mar 2012) | 3 lines + +Regession testing: Substitut POLLY_LIB_DIR, which is introduced by commit + r152924, by $(LibDir). Because we assume polly built by autoconf is always + in llvm tree. +------------------------------------------------------------------------ +r153503 | ether | 2012-03-27 15:56:07 +0800 (Tue, 27 Mar 2012) | 3 lines + +Out of tree build support: Set TARGET_TRIPLE from the result of "llvm-config --host-target" + instead of loading the "LLVMConfig.cmake" which is only installed when + llvm configured by cmake. +------------------------------------------------------------------------ +r153440 | ether | 2012-03-26 23:16:48 +0800 (Mon, 26 Mar 2012) | 1 line + +Don't fail the lli testcases on 32bit platform. +------------------------------------------------------------------------ +r153439 | ether | 2012-03-26 23:16:29 +0800 (Mon, 26 Mar 2012) | 1 line + +Out-of-tree build: Load the configuration of the installed llvm. +------------------------------------------------------------------------ +r153331 | grosser | 2012-03-23 20:20:36 +0800 (Fri, 23 Mar 2012) | 1 line + +CodeGen: Remove the need for setIVS +------------------------------------------------------------------------ +r153330 | grosser | 2012-03-23 20:20:32 +0800 (Fri, 23 Mar 2012) | 1 line + +CodeGen: Simplify Variable Names +------------------------------------------------------------------------ +r153325 | grosser | 2012-03-23 18:35:18 +0800 (Fri, 23 Mar 2012) | 5 lines + +CodeGen: Extract the LLVM-IR generaction of scalar and OpenMP loops. + +We create a new file LoopGenerators that provides utility classes for the +generation of OpenMP parallel and scalar loops. This means we move a lot +of the OpenMP generation out of the Polly specific code generator. +------------------------------------------------------------------------ +r153321 | grosser | 2012-03-23 16:24:10 +0800 (Fri, 23 Mar 2012) | 3 lines + +CodeGen: Change some variables to uppercase + +No functional changes intended. +------------------------------------------------------------------------ +r153320 | grosser | 2012-03-23 16:24:04 +0800 (Fri, 23 Mar 2012) | 3 lines + +test: Remove memaccess prefix + +The prefix is not needed, as all test cases are already in a separate folder. +------------------------------------------------------------------------ +r153319 | grosser | 2012-03-23 16:21:22 +0800 (Fri, 23 Mar 2012) | 8 lines + +CodeGen: Full support for isl_pw expressions in modified access functions. + +This also adds support for modifiable write accesses (until now only read +accesses where supported). We currently do not derive an exact type for the +expression, but assume that i64 is good enough. This will be improved in future +patches. + +Contributed by: Yabin Hu +------------------------------------------------------------------------ +r153318 | grosser | 2012-03-23 16:02:19 +0800 (Fri, 23 Mar 2012) | 5 lines + +IndVarSimplify: Disable simplifyIVUsers + +This functionality is not available in LLVM trunk and breaks the compilation of +Polly. This patch fixes the compilation, but may not be enough to recover all +functionality. +------------------------------------------------------------------------ +r153317 | grosser | 2012-03-23 16:02:15 +0800 (Fri, 23 Mar 2012) | 3 lines + +IndVarSimplify: Adapt to changes in LLVM trunk + +Contributed-By: Andrew Trick +------------------------------------------------------------------------ +r153316 | grosser | 2012-03-23 16:02:05 +0800 (Fri, 23 Mar 2012) | 1 line + +IndVarSimplify: Proberly initialize the pass. +------------------------------------------------------------------------ +r152936 | grosser | 2012-03-17 02:45:10 +0800 (Sat, 17 Mar 2012) | 1 line + +ScheduleOptimizer: Remove forgotten debug output +------------------------------------------------------------------------ +r152933 | grosser | 2012-03-17 01:17:16 +0800 (Sat, 17 Mar 2012) | 9 lines + +Do not fail if a command line argument is given more than once + +For boolean flags in Polly there is no problem if they are given more than once. +Hence, we can allow it to not fail for build systems that (acciently) add flags +several times. + +This fixes: PR12278 + +Reported by: Sebastian Pop +------------------------------------------------------------------------ +r152928 | grosser | 2012-03-17 00:36:47 +0800 (Sat, 17 Mar 2012) | 8 lines + +Don't allow pointer types in affine expressions + +We currently do not support pointer types in affine expressions. Hence, we +disallow in the SCoP detection. Later we may decide to add support for them. + +This fixes PR12277 + +Reported-By: Sebastian Pop +------------------------------------------------------------------------ +r152925 | ether | 2012-03-16 22:34:27 +0800 (Fri, 16 Mar 2012) | 1 line + +Off-tree build support: Also check the existence of the "not" utility. +------------------------------------------------------------------------ +r152924 | ether | 2012-03-16 22:34:20 +0800 (Fri, 16 Mar 2012) | 1 line + +Off-tree build support: Set the path of Polly's library correctly. +------------------------------------------------------------------------ +r152923 | ether | 2012-03-16 21:49:55 +0800 (Fri, 16 Mar 2012) | 3 lines + +Revert "Minor change: Use config.polly_obj_root to locate Polly's library," + +This reverts commit 7dd9b6327b54b08ece32a4607d5ac093b518b79a. +------------------------------------------------------------------------ +r152921 | ether | 2012-03-16 21:24:42 +0800 (Fri, 16 Mar 2012) | 1 line + +Off-tree build support: Warn the user if FileCheck cannot be found. +------------------------------------------------------------------------ +r152920 | ether | 2012-03-16 21:24:34 +0800 (Fri, 16 Mar 2012) | 2 lines + +Minor change: Use config.polly_obj_root to locate Polly's library, + so lit find Polly's library in off-tree build. +------------------------------------------------------------------------ +r152917 | grosser | 2012-03-16 19:51:41 +0800 (Fri, 16 Mar 2012) | 4 lines + +ScheduleOptimizer: Do not get dependences, if we do not calculate a schedule + +This solves the 'isl_ctx freed, but some objects still reference it' problem +reported in PR12276. +------------------------------------------------------------------------ +r152913 | grosser | 2012-03-16 18:16:28 +0800 (Fri, 16 Mar 2012) | 6 lines + +SCEVValidator: Ensure that parameters are recorded correctly + +This also fixes UMax where we did not correctly keep track of the parameters. +Fixes PR12275. + +Reported-By: Sebastian Pop +------------------------------------------------------------------------ +r152912 | grosser | 2012-03-16 18:12:37 +0800 (Fri, 16 Mar 2012) | 1 line + +ScevValidator: Add printer for ValidatorResult +------------------------------------------------------------------------ +r152910 | ether | 2012-03-16 17:04:09 +0800 (Fri, 16 Mar 2012) | 3 lines + +Polly-test: Add a cmake option "POLLY_TEST_DISABLE_BAR". We can enable + this option in the configure step of Polly's builder to get more readable + output from the stdio log. +------------------------------------------------------------------------ +r152909 | ether | 2012-03-16 16:31:24 +0800 (Fri, 16 Mar 2012) | 1 line + +More AddUsersIfInteresting related fix. +------------------------------------------------------------------------ +r152908 | ether | 2012-03-16 16:26:12 +0800 (Fri, 16 Mar 2012) | 1 line + +IndVarSimplify: Adpat to IVUsers::AddUsersIfInteresting change. +------------------------------------------------------------------------ +r152800 | grosser | 2012-03-15 21:55:38 +0800 (Thu, 15 Mar 2012) | 1 line + +www: Fix german special characters +------------------------------------------------------------------------ +r152799 | grosser | 2012-03-15 21:54:12 +0800 (Thu, 15 Mar 2012) | 1 line + +www: Add another GPGPU publication +------------------------------------------------------------------------ +r152795 | raghesh | 2012-03-15 19:40:05 +0800 (Thu, 15 Mar 2012) | 5 lines + +Memaccess: Updating Documentation + +Adding documentation for changes in coefficients of induction +variables. + +------------------------------------------------------------------------ +r152793 | grosser | 2012-03-15 17:34:58 +0800 (Thu, 15 Mar 2012) | 1 line + +CodeGen: Call isl_set_copy() within the loop +------------------------------------------------------------------------ +r152792 | grosser | 2012-03-15 17:34:55 +0800 (Thu, 15 Mar 2012) | 1 line + +CodeGen: Start variables with uppercase letters +------------------------------------------------------------------------ +r152791 | grosser | 2012-03-15 17:34:52 +0800 (Thu, 15 Mar 2012) | 1 line + +CodeGen: Get analyses from the Pass instance +------------------------------------------------------------------------ +r152790 | grosser | 2012-03-15 17:34:48 +0800 (Thu, 15 Mar 2012) | 1 line + +CodeGen: Introduce helper function to get pointer to int +------------------------------------------------------------------------ +r152612 | raghesh | 2012-03-13 13:51:44 +0800 (Tue, 13 Mar 2012) | 6 lines + +Memaccess: Removing unwanted code + +When the code is moved to IslGenerator class there is no use for +IslPwAffUserInfo. + + +------------------------------------------------------------------------ +r152319 | grosser | 2012-03-08 23:21:51 +0800 (Thu, 08 Mar 2012) | 10 lines + +Remove FinalRead + +The FinalRead statement represented a virtual read that is executed after the +SCoP. It was used when we verified the correctness of a schedule by checking if +it yields the same FLOW dependences as the original code. This is only works, if +we have a final read that reads all memory at the end of the SCoP. +We now switched to just checking if a schedule does not introduce negative +dependences and also consider WAW WAR dependences. This restricts the schedules +a little bit more, but we do not have any optimizer that would calculate a more +complex schedule. Hence, for now final reads are obsolete. +------------------------------------------------------------------------ +r152318 | grosser | 2012-03-08 23:21:42 +0800 (Thu, 08 Mar 2012) | 1 line + +Dependences: Fix typo +------------------------------------------------------------------------ +r152311 | grosser | 2012-03-08 20:02:59 +0800 (Thu, 08 Mar 2012) | 1 line + +www: Really fix it +------------------------------------------------------------------------ +r152310 | grosser | 2012-03-08 20:02:10 +0800 (Thu, 08 Mar 2012) | 1 line + +www: Fix link to image +------------------------------------------------------------------------ +r152309 | grosser | 2012-03-08 19:59:43 +0800 (Thu, 08 Mar 2012) | 1 line + +www: Move the Polly architecture to the documentation +------------------------------------------------------------------------ +r152308 | grosser | 2012-03-08 19:55:27 +0800 (Thu, 08 Mar 2012) | 1 line + +www: Point to the memaccess documentation +------------------------------------------------------------------------ +r152307 | grosser | 2012-03-08 19:45:49 +0800 (Thu, 08 Mar 2012) | 1 line + +www: Simplify bugs text +------------------------------------------------------------------------ +r152306 | grosser | 2012-03-08 19:37:39 +0800 (Thu, 08 Mar 2012) | 1 line + +www: Merge Examples with Documentation section +------------------------------------------------------------------------ +r152305 | grosser | 2012-03-08 19:31:54 +0800 (Thu, 08 Mar 2012) | 1 line + +www: Update todo page +------------------------------------------------------------------------ +r152238 | grosser | 2012-03-08 01:42:49 +0800 (Thu, 08 Mar 2012) | 1 line + +Dependences: Simplify isParallelDimension +------------------------------------------------------------------------ +r152237 | grosser | 2012-03-08 01:42:45 +0800 (Thu, 08 Mar 2012) | 1 line + +Dependences: Restructure and Document code +------------------------------------------------------------------------ +r152236 | grosser | 2012-03-08 01:42:39 +0800 (Thu, 08 Mar 2012) | 1 line + +Dependences: Prettify the header slightly +------------------------------------------------------------------------ +r152235 | grosser | 2012-03-08 01:42:36 +0800 (Thu, 08 Mar 2012) | 1 line + +Dependences: Remove unused no_source information +------------------------------------------------------------------------ +r152230 | grosser | 2012-03-08 00:10:40 +0800 (Thu, 08 Mar 2012) | 5 lines + +Dependences: Simplify the check if a new scattering is valid. + +We now just check if the new scattering would create non-positive dependences. +This is a lot faster than recalculating dependences (which is especially slow +on tiled code). +------------------------------------------------------------------------ +r152229 | grosser | 2012-03-07 22:30:54 +0800 (Wed, 07 Mar 2012) | 1 line + +www: Fix some command lines in the examples +------------------------------------------------------------------------ +r152109 | grosser | 2012-03-06 15:38:57 +0800 (Tue, 06 Mar 2012) | 3 lines + +CodeGen: Fix typo 'form' -> 'from' + +Suggested by: Sebastian Pop +------------------------------------------------------------------------ +r151917 | grosser | 2012-03-02 23:20:39 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Document and beautify the parts of the BlockGenerators +------------------------------------------------------------------------ +r151916 | grosser | 2012-03-02 23:20:35 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Pass the scalar maps properly +------------------------------------------------------------------------ +r151915 | grosser | 2012-03-02 23:20:31 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Prettify +------------------------------------------------------------------------ +r151914 | grosser | 2012-03-02 23:20:28 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Style +------------------------------------------------------------------------ +r151913 | grosser | 2012-03-02 23:20:24 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Move domain into the VectorBlockGenerator +------------------------------------------------------------------------ +r151912 | grosser | 2012-03-02 23:20:21 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Simplify the generation of a splat +------------------------------------------------------------------------ +r151911 | grosser | 2012-03-02 23:20:17 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Prettify function +------------------------------------------------------------------------ +r151907 | grosser | 2012-03-02 19:27:28 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Create separate VectorBlockGenerator +------------------------------------------------------------------------ +r151906 | grosser | 2012-03-02 19:27:25 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Extract code generation for isl types into its own class +------------------------------------------------------------------------ +r151905 | grosser | 2012-03-02 19:27:21 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Remove unneeded member variable +------------------------------------------------------------------------ +r151904 | grosser | 2012-03-02 19:27:18 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Extract code into the new function copyVectorInstruction +------------------------------------------------------------------------ +r151903 | grosser | 2012-03-02 19:27:15 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Sink loop to iterate vector lanes down into copyInstruction +------------------------------------------------------------------------ +r151902 | grosser | 2012-03-02 19:27:11 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGenerator: Rename functions to show they produce vector code +------------------------------------------------------------------------ +r151901 | grosser | 2012-03-02 19:27:08 +0800 (Fri, 02 Mar 2012) | 1 line + +Fix typo +------------------------------------------------------------------------ +r151900 | grosser | 2012-03-02 19:27:05 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: No need to forward the vector dimension +------------------------------------------------------------------------ +r151899 | grosser | 2012-03-02 19:27:02 +0800 (Fri, 02 Mar 2012) | 3 lines + +CodeGen: Store the vector width in the block generator + +This allows us to remove a lot of redundant parameters. +------------------------------------------------------------------------ +r151898 | grosser | 2012-03-02 19:26:59 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Remove dead code +------------------------------------------------------------------------ +r151897 | grosser | 2012-03-02 19:26:55 +0800 (Fri, 02 Mar 2012) | 1 line + +Codegen: Add Pass as a member variable of BlockGenerator +------------------------------------------------------------------------ +r151896 | grosser | 2012-03-02 19:26:52 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Simplify and Prettify code +------------------------------------------------------------------------ +r151895 | grosser | 2012-03-02 19:26:49 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Hide the private implementation of the block generator +------------------------------------------------------------------------ +r151894 | grosser | 2012-03-02 19:26:46 +0800 (Fri, 02 Mar 2012) | 1 line + +CodeGen: Start with uppercase letter +------------------------------------------------------------------------ +r151893 | grosser | 2012-03-02 19:26:42 +0800 (Fri, 02 Mar 2012) | 3 lines + +CodeGen: Only check once if a loop is parallel + +Suggested by: Sebastian Pop +------------------------------------------------------------------------ +r151810 | grosser | 2012-03-01 23:02:21 +0800 (Thu, 01 Mar 2012) | 3 lines + +www: Fix typo founded -> funded + +Found-By: Christian Lengauer +------------------------------------------------------------------------ +r150959 | grosser | 2012-02-20 22:03:56 +0800 (Mon, 20 Feb 2012) | 1 line + +www: Fix french special characters +------------------------------------------------------------------------ +r150955 | grosser | 2012-02-20 16:41:55 +0800 (Mon, 20 Feb 2012) | 1 line + +Add information, that Polly became a real LLVM project +------------------------------------------------------------------------ +r150954 | grosser | 2012-02-20 16:41:51 +0800 (Mon, 20 Feb 2012) | 1 line + +www: Update links polly.grosser.es -> polly.llvm.org +------------------------------------------------------------------------ +r150953 | grosser | 2012-02-20 16:41:47 +0800 (Mon, 20 Feb 2012) | 1 line + +ScheduleOpt: Add option to bound scheduling coefficients of dimensions. +------------------------------------------------------------------------ +r150952 | grosser | 2012-02-20 16:41:44 +0800 (Mon, 20 Feb 2012) | 3 lines + +Update isl + +This version of isl, contains some recently committed scheduler patches. +------------------------------------------------------------------------ +r150951 | grosser | 2012-02-20 16:41:21 +0800 (Mon, 20 Feb 2012) | 1 line + +ScheduleOptimizer: Dump the calculated schedule in debug mode +------------------------------------------------------------------------ +r150950 | grosser | 2012-02-20 16:41:15 +0800 (Mon, 20 Feb 2012) | 1 line + +ScheduleOpt: Add option to bound constant term coefficients +------------------------------------------------------------------------ +r150691 | grosser | 2012-02-16 22:13:19 +0800 (Thu, 16 Feb 2012) | 4 lines + +Revert "CodeGeneration: Implement ceild/floord exactly as CLooG does" + +I think I did not get the implementation right. As the current implementation +works well, we will just stick with it for now. +------------------------------------------------------------------------ +r150676 | grosser | 2012-02-16 17:59:34 +0800 (Thu, 16 Feb 2012) | 1 line + +www: Add 'pet' paper to the publications +------------------------------------------------------------------------ +r150675 | grosser | 2012-02-16 17:56:21 +0800 (Thu, 16 Feb 2012) | 1 line + +CodeGen: Code following a clast_guard comes after the merge block +------------------------------------------------------------------------ +r150674 | grosser | 2012-02-16 17:56:17 +0800 (Thu, 16 Feb 2012) | 1 line + +RegisterPasses: Allow to print the CFG right after polly +------------------------------------------------------------------------ +r150673 | grosser | 2012-02-16 17:56:14 +0800 (Thu, 16 Feb 2012) | 1 line + +CodeGeneration: Implement ceild/floord exactly as CLooG does +------------------------------------------------------------------------ +r150672 | grosser | 2012-02-16 17:56:10 +0800 (Thu, 16 Feb 2012) | 1 line + +CodeGen: Simplify code slightly +------------------------------------------------------------------------ +r150671 | grosser | 2012-02-16 17:56:07 +0800 (Thu, 16 Feb 2012) | 1 line + +RegisterPasses: Add -polly-run-export-cloog option +------------------------------------------------------------------------ +r150577 | grosser | 2012-02-15 17:58:53 +0800 (Wed, 15 Feb 2012) | 3 lines + +CodeGen: Update the BasicBlock pointer correctly when creating 'polly.split...' + +Problem reported by: Ryan Taylor +------------------------------------------------------------------------ +r150576 | grosser | 2012-02-15 17:58:50 +0800 (Wed, 15 Feb 2012) | 1 line + +CodeGen: Retain the old BB names within the original SCoP +------------------------------------------------------------------------ +r150575 | grosser | 2012-02-15 17:58:46 +0800 (Wed, 15 Feb 2012) | 1 line + +CodeGen: Name stmt bbs 'polly.stmt.' + OriginalName +------------------------------------------------------------------------ +r150574 | grosser | 2012-02-15 17:58:42 +0800 (Wed, 15 Feb 2012) | 1 line + +ScheduleOpt: Only get RAW dependences if we asked for raw +------------------------------------------------------------------------ +r150484 | grosser | 2012-02-14 22:02:48 +0800 (Tue, 14 Feb 2012) | 4 lines + +ScheduleOpt: Allow to configure for which dependences to optimize + +We can either optimize for RAW dependences or for all dependences. +For the moment, I do not see a big difference here. +------------------------------------------------------------------------ +r150483 | grosser | 2012-02-14 22:02:44 +0800 (Tue, 14 Feb 2012) | 5 lines + +CodeGen: Get dependences for validity and proximity separately + +This change itself should not change functionality, but it will make it easier +to support use different dependence kinds in for validity and proximity +constraints. +------------------------------------------------------------------------ +r150482 | grosser | 2012-02-14 22:02:40 +0800 (Tue, 14 Feb 2012) | 1 line + +ScopInfo: Add Scop::getDomains() +------------------------------------------------------------------------ +r150481 | grosser | 2012-02-14 22:02:33 +0800 (Tue, 14 Feb 2012) | 5 lines + +Copy IndVarSimplify pass from LLVM to Polly + +This allows us to enable -enable-iv-rewrite by default and releases LLVM from +the burdon to keep that feature. This is an intermediate step. We plan to soon +remove the need for rewritten induction variables entirely. +------------------------------------------------------------------------ +r150480 | grosser | 2012-02-14 22:02:27 +0800 (Tue, 14 Feb 2012) | 7 lines + +Recommit "CodeGen: Maintain a valid CFG during code generation" + +When I first tried to commit this patch, the builder pointed after generation +of a loop still into the loop body. This means that code that was supposed to +be generated after the loop was generated right into the loop body. We fixed +this by pointing the builder to the BB after the loop, as soon as code +generation of the loop body itself is finished. +------------------------------------------------------------------------ +r150431 | grosser | 2012-02-14 07:31:43 +0800 (Tue, 14 Feb 2012) | 3 lines + +Revert "CodeGen: Maintain a valid CFG during code generation" + +This commit contained some bugs. Revert it until I get around to fix them. +------------------------------------------------------------------------ +r150430 | grosser | 2012-02-14 07:31:39 +0800 (Tue, 14 Feb 2012) | 1 line + +ScheduleOptimizer: Change vars to start with uppercase letter +------------------------------------------------------------------------ +r150377 | grosser | 2012-02-13 20:29:43 +0800 (Mon, 13 Feb 2012) | 1 line + +tests: Replace . by %s +------------------------------------------------------------------------ +r150376 | grosser | 2012-02-13 20:29:34 +0800 (Mon, 13 Feb 2012) | 1 line + +CodeGen: Remove unused variable. +------------------------------------------------------------------------ +r150339 | grosser | 2012-02-12 20:09:53 +0800 (Sun, 12 Feb 2012) | 7 lines + +CodeGen: Maintain a valid CFG during code generation + +Before this change we built the CFG such that it was only valid after code was +fully generated. During code generation itself, it was often incomplete. After +this change always maintain a valid CFG. This will later allow us to use the +SCEVExpander during code generation. This is the first step to get rid of the +independent blocks pass. +------------------------------------------------------------------------ +r150338 | grosser | 2012-02-12 20:09:49 +0800 (Sun, 12 Feb 2012) | 1 line + +CodeGen: Remove unused instruction +------------------------------------------------------------------------ +r150337 | grosser | 2012-02-12 20:09:46 +0800 (Sun, 12 Feb 2012) | 1 line + +CodeGen: Always name merge block +------------------------------------------------------------------------ +r150336 | grosser | 2012-02-12 20:09:41 +0800 (Sun, 12 Feb 2012) | 1 line + +CodeGen: Start variable names with uppercase letter. +------------------------------------------------------------------------ +r150335 | grosser | 2012-02-12 20:09:37 +0800 (Sun, 12 Feb 2012) | 1 line + +Codegen: Give split and merge basic blocks better names +------------------------------------------------------------------------ +r150334 | grosser | 2012-02-12 20:09:32 +0800 (Sun, 12 Feb 2012) | 1 line + +CodeGen: Further improve style +------------------------------------------------------------------------ +r150333 | grosser | 2012-02-12 20:09:27 +0800 (Sun, 12 Feb 2012) | 3 lines + +CodeGen: Move generation of OpenMP out of the way + +We also fix some style issues. This change contains no functional change. +------------------------------------------------------------------------ +r149871 | grosser | 2012-02-06 22:53:51 +0800 (Mon, 06 Feb 2012) | 1 line + +RegisterPasses: Make sure to always execute the SCoPInfo pass +------------------------------------------------------------------------ +r149503 | grosser | 2012-02-01 22:23:36 +0800 (Wed, 01 Feb 2012) | 1 line + +ScopInfo: Simplify some isl code +------------------------------------------------------------------------ +r149502 | grosser | 2012-02-01 22:23:33 +0800 (Wed, 01 Feb 2012) | 1 line + +CodeGeneration: Rephrase comment slightly +------------------------------------------------------------------------ +r149501 | grosser | 2012-02-01 22:23:29 +0800 (Wed, 01 Feb 2012) | 1 line + +CodeGeneration: Order includes alphabetically +------------------------------------------------------------------------ +r149456 | grosser | 2012-02-01 08:08:10 +0800 (Wed, 01 Feb 2012) | 3 lines + +www: More typos + +Pointed out by Chad Rosier +------------------------------------------------------------------------ +r149415 | grosser | 2012-02-01 04:24:21 +0800 (Wed, 01 Feb 2012) | 3 lines + +www: Add missing -mllvm to documentation + +Found by Ryan Taylor +------------------------------------------------------------------------ +r149410 | grosser | 2012-02-01 03:54:50 +0800 (Wed, 01 Feb 2012) | 3 lines + +www: Spelling fixes + +Reported by Sebastian Pop +------------------------------------------------------------------------ +r149386 | grosser | 2012-01-31 22:00:27 +0800 (Tue, 31 Jan 2012) | 12 lines + +Add a sceleton for a polyhedral dead code elimination. + +Such a dead code elimination can remove redundant stores to arrays. It can also +eliminate calculations where the results are stored to memory but where they are +overwritten before ever being read. It may also fix bugs like: +http://llvm.org/bugs/show_bug.cgi?id=5117 + +This commit just adds a sceleton without any functionality. + +If anybody is interested to learn about polyhedral optimizations this would be +a good task. Well definined, self contained and pretty simple. Ping me if you +want to start and you need some pointers to get going. +------------------------------------------------------------------------ +r149383 | grosser | 2012-01-31 21:26:29 +0800 (Tue, 31 Jan 2012) | 1 line + +Schedule: Sort includes and remove useless ones +------------------------------------------------------------------------ +r149374 | grosser | 2012-01-31 17:13:12 +0800 (Tue, 31 Jan 2012) | 1 line + +www: Add news about the improved isl scheduling support +------------------------------------------------------------------------ +r149373 | grosser | 2012-01-31 16:50:23 +0800 (Tue, 31 Jan 2012) | 1 line + +www: Remove PoCC from the prerequisites +------------------------------------------------------------------------ +r149372 | grosser | 2012-01-31 16:50:19 +0800 (Tue, 31 Jan 2012) | 5 lines + +polly.sh: Do not automatically install scoplib either. + +It is only needed for PoCC. We may update our openscop support which is +expected to be wider used. If this is the case we could automatically build +openscop. +------------------------------------------------------------------------ +r149371 | grosser | 2012-01-31 16:50:16 +0800 (Tue, 31 Jan 2012) | 1 line + +www: Move PoCC to the end of the installation section +------------------------------------------------------------------------ +r149370 | grosser | 2012-01-31 16:50:12 +0800 (Tue, 31 Jan 2012) | 5 lines + +polly.sh: Do not build PoCC automatically + +As we now have a scheduler that works, I do not believe a lot of people need +PoCC right ahead. People who want to do an in depth investigation of the +different schedulers can install it as well manually. +------------------------------------------------------------------------ +r149290 | grosser | 2012-01-31 06:46:22 +0800 (Tue, 31 Jan 2012) | 1 line + +Remove leftover constant +------------------------------------------------------------------------ +r149288 | grosser | 2012-01-31 06:44:05 +0800 (Tue, 31 Jan 2012) | 6 lines + +Scheduling: Limiting the constant term is not necessary any more + +Due to our gist simplifications, limiting the constant term does not seem to +be necessary any more. + +Pointed out by Sven Verdoolaege +------------------------------------------------------------------------ +r149287 | grosser | 2012-01-31 06:43:56 +0800 (Tue, 31 Jan 2012) | 3 lines + +Typo: Maxize -> Mazimize + +Found by Sebastian Pop. +------------------------------------------------------------------------ +r149267 | grosser | 2012-01-31 03:38:58 +0800 (Tue, 31 Jan 2012) | 6 lines + +Scheduling: Set fusion strategy to minimal + +This has shown better results for 2mm, 3mm and a couple of other benchmarks. + +After this we show consistenly better results as PoCC with maxfuse. We need +to see if PoCC can also give better results with another fusion strategy. +------------------------------------------------------------------------ +r149266 | grosser | 2012-01-31 03:38:54 +0800 (Tue, 31 Jan 2012) | 5 lines + +Scheduling: Add option to disable schedule_maximise_band_depth + +maximise_band_depth does not seem to have any effect for now, but it may help to +increase the amount of tileable loops. We expose the flag to be able to analyze +its effects when looking into individual benchmarks. +------------------------------------------------------------------------ +r149265 | grosser | 2012-01-31 03:38:50 +0800 (Tue, 31 Jan 2012) | 1 line + +Scheduler: Allow to select the fusion strategy +------------------------------------------------------------------------ +r149264 | grosser | 2012-01-31 03:38:47 +0800 (Tue, 31 Jan 2012) | 4 lines + +Scheduling: Use original schedule if we cannot find a new one + +After this we can now compile all polybench 2.0 kernels without any compiler +crash. +------------------------------------------------------------------------ +r149263 | grosser | 2012-01-31 03:38:43 +0800 (Tue, 31 Jan 2012) | 15 lines + +Scheduler: Simplify dependences by default (only isl) + +This speeds up the scheduler by orders of magnitude and in addition yields often +to a better schedule. + +With this we can compile all polybench kernels with less than 5x compile time +overhead. In general the overhead is even less than 2-3x. This is still with +running a lot of redundant passes and no compile time tuning at all. There are +several obvious areas where we can improve here further. + +There are also two test cases where we cannot find a schedule any more (cholesky +and another). I will look into them later on. + +With this we have a very solid base line from which we can start to optimize +further. +------------------------------------------------------------------------ +r149262 | grosser | 2012-01-31 03:38:40 +0800 (Tue, 31 Jan 2012) | 3 lines + +Use isl version: 3c66541593a6bf3b5a3d35d31567abe6c9e5a04b + +This allows us to set the fusion strategy and to gist-simplify union_maps. +------------------------------------------------------------------------ +r149261 | grosser | 2012-01-31 03:38:36 +0800 (Tue, 31 Jan 2012) | 1 line + +Dependences: Coalesce the dependences before returning them. +------------------------------------------------------------------------ +r149240 | grosser | 2012-01-30 17:07:50 +0800 (Mon, 30 Jan 2012) | 1 line + +RegisterPass: Expose functions to register Polly passes +------------------------------------------------------------------------ +r149239 | grosser | 2012-01-30 17:07:45 +0800 (Mon, 30 Jan 2012) | 1 line + +Disable some clang warnings in imported JSON code. +------------------------------------------------------------------------ +r149073 | grosser | 2012-01-27 03:53:01 +0800 (Fri, 27 Jan 2012) | 3 lines + +Remove unneeded default case + +This silences a clang warning. +------------------------------------------------------------------------ +r148814 | grosser | 2012-01-25 00:42:32 +0800 (Wed, 25 Jan 2012) | 1 line + +CodeGen: Separate declaration and definition of ClastStmtCodeGen +------------------------------------------------------------------------ +r148813 | grosser | 2012-01-25 00:42:28 +0800 (Wed, 25 Jan 2012) | 1 line + +CodeGen: Separate declaration and definition of ClastExpCodeGen +------------------------------------------------------------------------ +r148812 | grosser | 2012-01-25 00:42:25 +0800 (Wed, 25 Jan 2012) | 1 line + +CodeGen: Use getNullValue to simplify some code +------------------------------------------------------------------------ +r148811 | grosser | 2012-01-25 00:42:21 +0800 (Wed, 25 Jan 2012) | 1 line + +CodeGen: Separate declaration and definitions of BlockGenerator +------------------------------------------------------------------------ +r148810 | grosser | 2012-01-25 00:42:16 +0800 (Wed, 25 Jan 2012) | 1 line + +ScopInfo: Add isStrideX to unify stride checking +------------------------------------------------------------------------ +r148620 | grosser | 2012-01-21 10:38:27 +0800 (Sat, 21 Jan 2012) | 1 line + +Dependences: Simplify code +------------------------------------------------------------------------ +r148328 | grosser | 2012-01-18 04:39:11 +0800 (Wed, 18 Jan 2012) | 1 line + +ScopInfo: Further style improvements +------------------------------------------------------------------------ +r148327 | grosser | 2012-01-18 04:34:27 +0800 (Wed, 18 Jan 2012) | 1 line + +ScopInfo: Simplify some code II +------------------------------------------------------------------------ +r148326 | grosser | 2012-01-18 04:34:23 +0800 (Wed, 18 Jan 2012) | 1 line + +ScopInfo: Simplify some code +------------------------------------------------------------------------ +r148307 | grosser | 2012-01-17 22:44:35 +0800 (Tue, 17 Jan 2012) | 1 line + +www: Move automatic polly installation to a more prominent place +------------------------------------------------------------------------ +r148306 | grosser | 2012-01-17 22:37:45 +0800 (Tue, 17 Jan 2012) | 1 line + +www: Fix clang path in polly.sh script +------------------------------------------------------------------------ +r148248 | grosser | 2012-01-17 02:50:43 +0800 (Tue, 17 Jan 2012) | 1 line + +Fix clang svn address +------------------------------------------------------------------------ +r148238 | grosser | 2012-01-16 23:19:19 +0800 (Mon, 16 Jan 2012) | 1 line + +Describe how to optionally build the matching clang version. +------------------------------------------------------------------------ +r148100 | raghesh | 2012-01-13 14:02:13 +0800 (Fri, 13 Jan 2012) | 3 lines + +Memaccess: Removing some unwanted code + + +------------------------------------------------------------------------ +r147543 | spop | 2012-01-05 04:11:18 +0800 (Thu, 05 Jan 2012) | 1 line + +add polly.sh script +------------------------------------------------------------------------ +r147444 | grosser | 2012-01-03 18:10:05 +0800 (Tue, 03 Jan 2012) | 1 line + +www: Papers about iterative compilation and non static control +------------------------------------------------------------------------ +r147443 | grosser | 2012-01-03 18:00:55 +0800 (Tue, 03 Jan 2012) | 1 line + +Add Udays PhD thesis +------------------------------------------------------------------------ +r147442 | grosser | 2012-01-03 17:50:29 +0800 (Tue, 03 Jan 2012) | 4 lines + +Update publications + +- Add the LLVM Developer Meeting 2012 talk +- Add papers used within Polly and papers interesting to read in general +------------------------------------------------------------------------ +r147395 | chapuni | 2012-01-01 16:16:56 +0800 (Sun, 01 Jan 2012) | 1 line + +Happy new year 2012! +------------------------------------------------------------------------ +r147305 | raghesh | 2011-12-28 10:48:26 +0800 (Wed, 28 Dec 2011) | 7 lines + +Memaccess: Using isl_map_dim_max + +Use isl_map_dim_max to extract the details of the changed +access relation. Only constant access functions are supported +now. + + +------------------------------------------------------------------------ +r146972 | grosser | 2011-12-20 18:43:14 +0800 (Tue, 20 Dec 2011) | 7 lines + +Support non-affine access functions in Polly. + +In case we can not analyze an access function, we do not discard the SCoP, but +assume conservatively that all memory accesses that can be derived from our base +pointer may be accessed. + +Patch provided by: Marcello Maggioni +------------------------------------------------------------------------ +r146727 | grosser | 2011-12-16 16:27:42 +0800 (Fri, 16 Dec 2011) | 1 line + +Adapt to move of isSafeToSpeculativelyExecute into another header. +------------------------------------------------------------------------ +r146560 | grosser | 2011-12-14 20:21:31 +0800 (Wed, 14 Dec 2011) | 8 lines + +Allow to run the Polly preopt passes with -O0 + +To extract a preoptimized LLVM-IR file from a C-file run: + +clang -Xclang -load -Xclang LLVMPolly.so -O0 -mllvm -polly file.c -S -emit-llvm + +On the generated file you can directly run passes such as: +'opt -view-scops file.s' +------------------------------------------------------------------------ +r146559 | grosser | 2011-12-14 20:21:27 +0800 (Wed, 14 Dec 2011) | 1 line + +www: Enable mp4 version of the developer meeting talk +------------------------------------------------------------------------ +r146557 | grosser | 2011-12-14 16:58:43 +0800 (Wed, 14 Dec 2011) | 13 lines + +Scheduler: Try to maximize the band depth + +Previously the scheduler was splitting bands at the level at which it detected +that the splitting of the band is necessary. This may introduce an additional +level of bands, that can be avoided by backtracking and splitting on a higher +level. Additional splits reduce the number of loops that can be tiled, such that +avoiding splits and maximizing the band depth seems preferable. + +As a first data point we looked at 2mm and 3mm from the polybench test suite. +For both maximizing the tilable bands results in a significant (5-10x) +performance improvement. + +This patch enables the isl scheduler option to maximize the band depth. +------------------------------------------------------------------------ +r146556 | grosser | 2011-12-14 16:58:39 +0800 (Wed, 14 Dec 2011) | 20 lines + +Scheduler: Set maximal constant term + +If larger coefficients appear as part of the input dependences, the schedule +calculation can take a very long time. We observed that the main overhead in +this calculation is due to optimizing the constant coefficients. They are +misused to increase locality by merging several unrelated dimensions into a +single dimension. This unwanted optimization increases the complexity of the +generated code and furthermore slows it down. + +We use a new isl scheduler option to bound the values in the constant dimension +by a user defined value (20 in our case). If the right value is choosen, costly +overoptimization is prevented. + +This solution works, but requires a specific (here almost randomly choosen) +value by which the constants are bound. For the moment, this is our best +solution, but we hope to to find a more generic one later on. + +After these patch the extremly long compile time for simple kernels like 2mm or +3mm is reduced to a reasonable amount of time (Not more than a couple of seconds +even in debug mode). +------------------------------------------------------------------------ +r146555 | grosser | 2011-12-14 16:58:36 +0800 (Wed, 14 Dec 2011) | 3 lines + +Update isl + +This updates bringes new options for the isl scheduler. +------------------------------------------------------------------------ +r146487 | grosser | 2011-12-13 23:09:09 +0800 (Tue, 13 Dec 2011) | 1 line + +www: Add forgotten files +------------------------------------------------------------------------ +r146486 | grosser | 2011-12-13 23:07:00 +0800 (Tue, 13 Dec 2011) | 1 line + +www: Add LLVM Developer Meeting Video (webm only) +------------------------------------------------------------------------ +r146485 | grosser | 2011-12-13 22:53:25 +0800 (Tue, 13 Dec 2011) | 1 line + +www: Improve styling of news section +------------------------------------------------------------------------ +r146484 | grosser | 2011-12-13 22:53:20 +0800 (Tue, 13 Dec 2011) | 1 line + +www: Rephrase the introduction to Polly +------------------------------------------------------------------------ +r146373 | grosser | 2011-12-12 22:52:31 +0800 (Mon, 12 Dec 2011) | 1 line + +Upgrade to CLooG 0.17.0 +------------------------------------------------------------------------ +r146279 | d0k | 2011-12-10 05:34:43 +0800 (Sat, 10 Dec 2011) | 1 line + +Update after LLVM API change. +------------------------------------------------------------------------ +r146255 | raghesh | 2011-12-09 22:27:17 +0800 (Fri, 09 Dec 2011) | 3 lines + +Memacess: Some style changes + + +------------------------------------------------------------------------ +r146149 | grosser | 2011-12-08 21:02:58 +0800 (Thu, 08 Dec 2011) | 1 line + +ScheduleOptimizer: Do not tile bands with just one dimension +------------------------------------------------------------------------ +r146033 | grosser | 2011-12-07 19:03:48 +0800 (Wed, 07 Dec 2011) | 4 lines + +ClooG: Make sure ambigous schedules do not introduce complicated code + +Cloog continued to split the domains even after the scattering. This lead to +complicated code. +------------------------------------------------------------------------ +r146028 | grosser | 2011-12-07 15:42:57 +0800 (Wed, 07 Dec 2011) | 4 lines + +ScheduleOptimizer: Rewrite getPrevectorMap to use isl_pw_aff + +This increases the readablity. This also adds some comments that explain +what this function does. +------------------------------------------------------------------------ +r146027 | grosser | 2011-12-07 15:42:51 +0800 (Wed, 07 Dec 2011) | 1 line + +Make isl abort when an error is encountered +------------------------------------------------------------------------ +r145933 | grosser | 2011-12-06 18:48:32 +0800 (Tue, 06 Dec 2011) | 1 line + +Update isl. +------------------------------------------------------------------------ +r145932 | grosser | 2011-12-06 18:48:27 +0800 (Tue, 06 Dec 2011) | 1 line + +CodeGen: Style improvements. +------------------------------------------------------------------------ +r145790 | grosser | 2011-12-04 18:44:14 +0800 (Sun, 04 Dec 2011) | 5 lines + +Cloog: Include header file for pipe/open/close + +We forgot to include the unistd.h header file that defines the +functions mentioned above. This was not a problem with gnu C++ library, +however it did not work for libc++. +------------------------------------------------------------------------ +r145402 | grosser | 2011-11-29 22:51:05 +0800 (Tue, 29 Nov 2011) | 4 lines + +test: Switch to new atomic instructions + +This fixes the test with recent versions of LLVM that do not support +the old atomic instructions any more. +------------------------------------------------------------------------ +r145401 | grosser | 2011-11-29 22:50:52 +0800 (Tue, 29 Nov 2011) | 3 lines + +Add utils/jscop2cloog.py + +This tool takes a jscop file and translates it into a cloog input file. +------------------------------------------------------------------------ +r145400 | grosser | 2011-11-29 22:50:47 +0800 (Tue, 29 Nov 2011) | 1 line + +test: Add more dependences to cmake build +------------------------------------------------------------------------ +r145076 | grosser | 2011-11-23 03:40:38 +0800 (Wed, 23 Nov 2011) | 3 lines + +test: Do not hardcode '.so' as library suffix + +Contributed by: Marcello Maggioni +------------------------------------------------------------------------ +r145075 | grosser | 2011-11-23 03:40:34 +0800 (Wed, 23 Nov 2011) | 1 line + +www: Document how to run 'make polly-test' for autoconf build +------------------------------------------------------------------------ +r145074 | grosser | 2011-11-23 03:40:31 +0800 (Wed, 23 Nov 2011) | 4 lines + +autoconf: Change order of linking files + +This fixes (or hides) the problem of symbols not being available in the +autoconf build. +------------------------------------------------------------------------ +r145073 | grosser | 2011-11-23 03:40:28 +0800 (Wed, 23 Nov 2011) | 1 line + +OpenScop: Remove use of getNameStr() +------------------------------------------------------------------------ +r145072 | grosser | 2011-11-23 03:40:24 +0800 (Wed, 23 Nov 2011) | 1 line + +cmake: Create libPollyExchange as in the autoconf build +------------------------------------------------------------------------ +r145071 | grosser | 2011-11-23 03:40:19 +0800 (Wed, 23 Nov 2011) | 4 lines + +Register Passes: Use -polly-optimizer=(isl|pocc) to switch optimizers + +This replaces the old option -polly-use-pocc. Also call the passes uniformly +-polly-opt-pocc and -polly-opt-isl. +------------------------------------------------------------------------ +r144917 | grosser | 2011-11-18 03:10:48 +0800 (Fri, 18 Nov 2011) | 14 lines + +RegisterPass: Disable Polly by default + +We disable Polly by default and add a new option '-polly' that enables Polly. +This allows us to create an the alias + +$ alias clang clang -Xclang -load -Xclang LLVMPolly.so + +which loads Polly always into clang. It can now be enabled by running: + +$ clang -O3 -mllvm -polly file.c + +To enable it by default an alias pollycc can be create + +$ alias pollycc clang -O3 -mllvm -polly +------------------------------------------------------------------------ +r144909 | grosser | 2011-11-17 22:52:36 +0800 (Thu, 17 Nov 2011) | 4 lines + +Do not use getNameStr() anymore. + +Instead we switch to the recommended getName(). This fixes compilation with +recent versions of LLVM. +------------------------------------------------------------------------ +r144908 | grosser | 2011-11-17 20:56:23 +0800 (Thu, 17 Nov 2011) | 1 line + +autoconf: Specify that pollyanalysis depends on pollysupport +------------------------------------------------------------------------ +r144907 | grosser | 2011-11-17 20:56:21 +0800 (Thu, 17 Nov 2011) | 1 line + +SCEVValidator: Fix coding standards in ValidatorResult +------------------------------------------------------------------------ +r144906 | grosser | 2011-11-17 20:56:19 +0800 (Thu, 17 Nov 2011) | 1 line + +SCEVValidator: Make ValidatorResult a class and enforce the use of wproper accessors +------------------------------------------------------------------------ +r144905 | grosser | 2011-11-17 20:56:17 +0800 (Thu, 17 Nov 2011) | 3 lines + +SCEVValidator: Document SCEVType and ValidatorResult + +Suggested by Sebastian Pop. +------------------------------------------------------------------------ +r144904 | grosser | 2011-11-17 20:56:14 +0800 (Thu, 17 Nov 2011) | 3 lines + +SCEVValidator: Restructure the logic of visitAddRecExpr + +Suggested by Sebastian Pop. +------------------------------------------------------------------------ +r144903 | grosser | 2011-11-17 20:56:12 +0800 (Thu, 17 Nov 2011) | 1 line + +SCEVValidator: Fix typo +------------------------------------------------------------------------ +r144902 | grosser | 2011-11-17 20:56:10 +0800 (Thu, 17 Nov 2011) | 3 lines + +Fix placement of the '*' that marks a pointer + +Suggested by Sebastian Pop. +------------------------------------------------------------------------ +r144901 | grosser | 2011-11-17 20:56:06 +0800 (Thu, 17 Nov 2011) | 3 lines + +RegisterPasses: Avoid double negation + +Fix suggested by Sebastian Pop. +------------------------------------------------------------------------ +r144900 | grosser | 2011-11-17 20:56:04 +0800 (Thu, 17 Nov 2011) | 1 line + +ScheduleOptimizer: Start with an empty union_map and add elements +------------------------------------------------------------------------ +r144899 | grosser | 2011-11-17 20:56:03 +0800 (Thu, 17 Nov 2011) | 5 lines + +ScheduleOptimizer: Some style changes + +- Use uppercase letters according to the LLVM coding style +- Rename functions to not include 'tiledSchedule', but just Schedule. This + is more correct as tiling might be disabled. +------------------------------------------------------------------------ +r144898 | grosser | 2011-11-17 20:56:00 +0800 (Thu, 17 Nov 2011) | 3 lines + +ScheduleOptimizer: Use early exit + +Style fix, noted by Sebastian Pop. +------------------------------------------------------------------------ +r144643 | grosser | 2011-11-15 19:39:02 +0800 (Tue, 15 Nov 2011) | 1 line + +ScopLib: Fix export/import after parameters are now tagged with isl_ids. +------------------------------------------------------------------------ +r144642 | grosser | 2011-11-15 19:38:59 +0800 (Tue, 15 Nov 2011) | 7 lines + +JSONImporter: Fix parameter ids when importing new access functions + +The new isl_id support for parmeters created problems when importing new +access functions. Even though the parameters had the same names, +they were mapped to different ids and where therefore incompatible. +We copy the ids now from the old parameter dimensions. This fixes the +problem. +------------------------------------------------------------------------ +r144641 | grosser | 2011-11-15 19:38:55 +0800 (Tue, 15 Nov 2011) | 5 lines + +ScopInfo: Use names of simple parameters to name the isl parameter dimensions. + +Parameters can be complex SCEV expressions, but they can also be single scalar +values. If a parameters is such a simple scalar value and the value is named, +use this name to name the isl parameter dimensions. +------------------------------------------------------------------------ +r144640 | grosser | 2011-11-15 19:38:47 +0800 (Tue, 15 Nov 2011) | 1 line + +Cloog: Copy parameter names from isl data structures +------------------------------------------------------------------------ +r144639 | grosser | 2011-11-15 19:38:44 +0800 (Tue, 15 Nov 2011) | 1 line + +JScop: Allow to update the context +------------------------------------------------------------------------ +r144638 | grosser | 2011-11-15 19:38:36 +0800 (Tue, 15 Nov 2011) | 1 line + +Make JScop export/reimport accessible from clang +------------------------------------------------------------------------ +r144289 | grosser | 2011-11-10 22:01:53 +0800 (Thu, 10 Nov 2011) | 1 line + +www: Remove link to LLVM for upper left corner. This confused a lot of people +------------------------------------------------------------------------ +r144288 | grosser | 2011-11-10 22:00:04 +0800 (Thu, 10 Nov 2011) | 1 line + +www: Add some news about Polly +------------------------------------------------------------------------ +r144287 | grosser | 2011-11-10 22:00:00 +0800 (Thu, 10 Nov 2011) | 1 line + +www: Highlight command line flags +------------------------------------------------------------------------ +r144286 | grosser | 2011-11-10 21:21:43 +0800 (Thu, 10 Nov 2011) | 15 lines + +ScopDetection: Do not verify Aliasing + +This does not work reliable and is probably not needed. I accidentally changed +this in this recent commit: + +commit a0bcd63c6ffa81616cf8c6663a87588803f7d91c +Author: grosser +Date: Thu Nov 10 12:47:21 2011 +0000 + + ScopDetect: Use INVALID macro to fail in case of aliasing + + This simplifies the code and also makes the error message available to the + graphviz scop viewer. + + git-svn-id: https://llvm.org/svn/llvm-project/polly/trunk@144284 +------------------------------------------------------------------------ +r144285 | grosser | 2011-11-10 20:47:26 +0800 (Thu, 10 Nov 2011) | 1 line + +ScopDetection: Add flag to ignore possible aliasing +------------------------------------------------------------------------ +r144284 | grosser | 2011-11-10 20:47:21 +0800 (Thu, 10 Nov 2011) | 4 lines + +ScopDetect: Use INVALID macro to fail in case of aliasing + +This simplifies the code and also makes the error message available to +the graphviz scop viewer. +------------------------------------------------------------------------ +r144283 | grosser | 2011-11-10 20:45:15 +0800 (Thu, 10 Nov 2011) | 1 line + +ScopDetect: Clean the last failure message properly +------------------------------------------------------------------------ +r144282 | grosser | 2011-11-10 20:45:11 +0800 (Thu, 10 Nov 2011) | 1 line + +ScopDetection: Improve formatting of error message and simplify some code +------------------------------------------------------------------------ +r144281 | grosser | 2011-11-10 20:45:07 +0800 (Thu, 10 Nov 2011) | 1 line + +Add a workaround to fix SCoPs rejected because of 'region not simple' +------------------------------------------------------------------------ +r144280 | grosser | 2011-11-10 20:45:03 +0800 (Thu, 10 Nov 2011) | 3 lines + +Reuse the old BaseAddress checking in SCEVValidator to make sure that no base +address is part of the access function. Also remove unused special cases that +were necessery when the base address was still contained in the access function +------------------------------------------------------------------------ +r144279 | grosser | 2011-11-10 20:44:55 +0800 (Thu, 10 Nov 2011) | 1 line + +Use getBasePtr in TempScop/ScopInfo +------------------------------------------------------------------------ +r144278 | grosser | 2011-11-10 20:44:50 +0800 (Thu, 10 Nov 2011) | 6 lines + +ScopDetect: Use getPointerBase to get the base pointer + +Previously we allowed in access functions only a single SCEVUnknown, which later +became the base address. We now use getPointerBase() to derive the base address +and all remaining unknowns are handled as parameters. This allows us to handle +cases like A[b+c]; +------------------------------------------------------------------------ +r144233 | grosser | 2011-11-10 06:35:19 +0800 (Thu, 10 Nov 2011) | 1 line + +Remove unused function declaration +------------------------------------------------------------------------ +r144232 | grosser | 2011-11-10 06:35:15 +0800 (Thu, 10 Nov 2011) | 1 line + +Remove unused parameters from TempScop +------------------------------------------------------------------------ +r144231 | grosser | 2011-11-10 06:35:09 +0800 (Thu, 10 Nov 2011) | 4 lines + +TempScop: Rename SCEVAffFunc to IRAccess + +The SCEVAffFunc is now only used to express memory accesses. Give it a proper +name and rework the class such that this is obvious. +------------------------------------------------------------------------ +r144230 | grosser | 2011-11-10 06:35:05 +0800 (Thu, 10 Nov 2011) | 4 lines + +Further remove now invalid SCEVAffFunc features. + +This also removes the construction of MayAliasSets that became invalid when +removing the use of SCEVAffFunc. +------------------------------------------------------------------------ +r144229 | grosser | 2011-11-10 06:35:00 +0800 (Thu, 10 Nov 2011) | 4 lines + +Remove AffineSCEVIterator + +We do not use it anymore. It was replaced by SCEVVisitors like the +SCEVValidator. +------------------------------------------------------------------------ +r144228 | grosser | 2011-11-10 06:34:53 +0800 (Thu, 10 Nov 2011) | 4 lines + +Do not check memory accesses additionally with isValidAffineFunction + +This check was necessary because of the use AffineSCEVIterator in TempScopInfo. +As we removed this use recently it is not necessary any more. +------------------------------------------------------------------------ +r144227 | grosser | 2011-11-10 06:34:48 +0800 (Thu, 10 Nov 2011) | 1 line + +Remove more unused stuff from SCEVAffFunc +------------------------------------------------------------------------ +r144226 | grosser | 2011-11-10 06:34:44 +0800 (Thu, 10 Nov 2011) | 1 line + +Remove SCEVAffFunc from polly::Comparison +------------------------------------------------------------------------ +r144224 | grosser | 2011-11-10 06:34:39 +0800 (Thu, 10 Nov 2011) | 1 line + +Remove unused code from SCEVAffFunc constructor +------------------------------------------------------------------------ +r144223 | grosser | 2011-11-10 06:34:34 +0800 (Thu, 10 Nov 2011) | 1 line + +Remove more of SCEVAffineFunc +------------------------------------------------------------------------ +r144222 | grosser | 2011-11-10 06:34:28 +0800 (Thu, 10 Nov 2011) | 1 line + +ScopInfo: Use getParamsInAffineExpr to get the BaseAddress +------------------------------------------------------------------------ +r144221 | grosser | 2011-11-10 06:34:24 +0800 (Thu, 10 Nov 2011) | 1 line + +TempScop: Remove more of the buildAffineFunction +------------------------------------------------------------------------ +r144220 | grosser | 2011-11-10 06:34:18 +0800 (Thu, 10 Nov 2011) | 1 line + +TempScopInfo: Remove unneeded construction of SCEVAffFunc +------------------------------------------------------------------------ +r144192 | grosser | 2011-11-10 01:44:03 +0800 (Thu, 10 Nov 2011) | 1 line + +www: Fix install location of cloog in the installation guide. +------------------------------------------------------------------------ +r144087 | grosser | 2011-11-08 23:41:28 +0800 (Tue, 08 Nov 2011) | 7 lines + +Detect Parameters directly on the SCEV. + +Instead of using TempScop to find parameters, we detect them directly +on the SCEV. This allows us to remove the TempScop parameter detection +in a subsequent commit. + +This fixes a bug reported by Marcello Maggioni +------------------------------------------------------------------------ +r144086 | grosser | 2011-11-08 23:41:19 +0800 (Tue, 08 Nov 2011) | 1 line + +Remove const +------------------------------------------------------------------------ +r144085 | grosser | 2011-11-08 23:41:13 +0800 (Tue, 08 Nov 2011) | 6 lines + +ScopInfo: Don't add common parameters during realignment to the context. + +Previously we built a context that contained already all parameter dimensions +from the start. We now build a context without any parameter dimensions and +extend the context as needed. All parameter dimensions are added during final +realignment. +------------------------------------------------------------------------ +r144084 | grosser | 2011-11-08 23:41:08 +0800 (Tue, 08 Nov 2011) | 1 line + +ScopInfo: Realign parameters after the scop is built +------------------------------------------------------------------------ +r144083 | grosser | 2011-11-08 23:41:03 +0800 (Tue, 08 Nov 2011) | 1 line + +Use a map to store the dimension of the the parameters +------------------------------------------------------------------------ +r143961 | grosser | 2011-11-07 20:58:59 +0800 (Mon, 07 Nov 2011) | 1 line + +ScopInfo: Extract function getIdForParam() +------------------------------------------------------------------------ +r143960 | grosser | 2011-11-07 20:58:54 +0800 (Mon, 07 Nov 2011) | 1 line + +SCEVValidator: Move into own file +------------------------------------------------------------------------ +r143959 | grosser | 2011-11-07 20:58:46 +0800 (Mon, 07 Nov 2011) | 9 lines + +ScopDetection: Introduce methods to check attributes of ValidatorResult + +This simplifies e.g: + +if (Op.type == SCEVType::INT || Op.type == SCEVType::PARAM) + + to + +if (Op.isConstant()) +------------------------------------------------------------------------ +r143958 | grosser | 2011-11-07 20:58:41 +0800 (Mon, 07 Nov 2011) | 1 line + +ScopDetection: Add ValidatorResult class +------------------------------------------------------------------------ +r143692 | grosser | 2011-11-04 18:08:08 +0800 (Fri, 04 Nov 2011) | 3 lines + +ScopDetection: Small fixes and improvements for the SCEVValidator + +These fixes were part of a code audit of the SCEVValidator. +------------------------------------------------------------------------ +r143691 | grosser | 2011-11-04 18:08:03 +0800 (Fri, 04 Nov 2011) | 3 lines + +ScopInfo: Add two new asserts. + +They show a bug recently reported by Marcello Maggioni +------------------------------------------------------------------------ +r143654 | grosser | 2011-11-04 05:03:18 +0800 (Fri, 04 Nov 2011) | 5 lines + +ScopDetection: Use SCEVValidator for memory accesses. + +We currently run the old memory access checker in parallel, as we would +otherwise fail in TempScop because of currently unsupported functions. We will +remove the old memory access checker as soon as TempScop is fixed. +------------------------------------------------------------------------ +r143653 | grosser | 2011-11-04 05:03:14 +0800 (Fri, 04 Nov 2011) | 1 line + +ScopDetection: Use SCEVValidator for conditions +------------------------------------------------------------------------ +r143652 | grosser | 2011-11-04 05:03:10 +0800 (Fri, 04 Nov 2011) | 1 line + +TempScop: Remove unused SCEVAffFunc constructor +------------------------------------------------------------------------ +r143651 | grosser | 2011-11-04 05:03:06 +0800 (Fri, 04 Nov 2011) | 1 line + +TempScop: Remove has_signed (was unused) +------------------------------------------------------------------------ +r143650 | grosser | 2011-11-04 05:03:01 +0800 (Fri, 04 Nov 2011) | 1 line + +ScopDetection: A parameter cannot appear inside a SCoP. +------------------------------------------------------------------------ +r143576 | grosser | 2011-11-03 05:40:08 +0800 (Thu, 03 Nov 2011) | 7 lines + +ScopDetection: Add new SCEV Validator + +The SCEV Validator is used to check if the bound of a loop can be translated +into a polyhedral constraint. The new validator is more general as the check +used previously and e.g. allows bounds like 'smax 1, %a'. At the moment, we +only allow signed comparisons. Also, the new validator is only used to verify +loop bounds. Memory accesses are still handled by the old validator. +------------------------------------------------------------------------ +r143575 | grosser | 2011-11-03 05:37:51 +0800 (Thu, 03 Nov 2011) | 3 lines + +TempScop: Remove SCEVAffFunc from LoopBoundInfo + +This is not needed anymore -> Reduce impact of SCEVAffFunc. +------------------------------------------------------------------------ +r143574 | grosser | 2011-11-03 05:37:06 +0800 (Thu, 03 Nov 2011) | 3 lines + +TempScopInfo: Print the original SCEV instead of using SCEVAffFunc + +This is reducing the impact of SCEVAffFunc +------------------------------------------------------------------------ +r143025 | raghesh | 2011-10-26 20:25:49 +0800 (Wed, 26 Oct 2011) | 3 lines + +www: Change in cloog installation procedure + + +------------------------------------------------------------------------ +r143008 | grosser | 2011-10-26 10:14:40 +0800 (Wed, 26 Oct 2011) | 3 lines + +Add forgotten -Xclang option + +Reported by: yabin.hwu@gmail.com +------------------------------------------------------------------------ +r143007 | grosser | 2011-10-26 10:09:11 +0800 (Wed, 26 Oct 2011) | 1 line + +www: reformat warning +------------------------------------------------------------------------ +r143005 | grosser | 2011-10-26 09:27:53 +0800 (Wed, 26 Oct 2011) | 1 line + +www: Emphasize clang/LLVM/Polly need to be in sync +------------------------------------------------------------------------ +r143004 | grosser | 2011-10-26 09:27:49 +0800 (Wed, 26 Oct 2011) | 1 line + +ScopInfo: Print SCEV and not the pointer to it +------------------------------------------------------------------------ +r142777 | grosser | 2011-10-24 04:59:49 +0800 (Mon, 24 Oct 2011) | 4 lines + +PoCC: Fix bugs when executing PoCC + +These are remainders of the switch to the newer isl version. At the point of +switching I did not test with PoCC support. I should have done. ;-) +------------------------------------------------------------------------ +r142776 | grosser | 2011-10-24 04:59:47 +0800 (Mon, 24 Oct 2011) | 5 lines + +Remove pollycc + +The recommanded and supported way to use Polly is to load it into clang. +Documentation for this is available on the website under +http://polly.grosser.es/example_load_Polly_into_clang.html +------------------------------------------------------------------------ +r142775 | grosser | 2011-10-24 04:59:44 +0800 (Mon, 24 Oct 2011) | 3 lines + +Only have a single option to disable tiling for both isl and Pocc optimzer + +This also documents the new option on the website. +------------------------------------------------------------------------ +r142774 | grosser | 2011-10-24 04:59:40 +0800 (Mon, 24 Oct 2011) | 3 lines + +Enable prevectorization with -enable-polly-vector. + +This removes the separate prevector options for the Pluto and isl scheduler. +------------------------------------------------------------------------ +r142773 | grosser | 2011-10-24 04:59:35 +0800 (Mon, 24 Oct 2011) | 1 line + +Add an option to run the PoCC optimizer +------------------------------------------------------------------------ +r142772 | grosser | 2011-10-24 04:59:32 +0800 (Mon, 24 Oct 2011) | 3 lines + +Allow to disable the schedule optimizer + +The option -polly-no-optimizer disables the scheduling optimizer. +------------------------------------------------------------------------ +r142771 | grosser | 2011-10-24 04:59:29 +0800 (Mon, 24 Oct 2011) | 1 line + +Rename -enable-schedule-prevector to -polly-prevector +------------------------------------------------------------------------ +r142770 | grosser | 2011-10-24 04:59:26 +0800 (Mon, 24 Oct 2011) | 1 line + +ScheduleOptimizer: Allow to disable tiling +------------------------------------------------------------------------ +r142769 | grosser | 2011-10-24 04:59:24 +0800 (Mon, 24 Oct 2011) | 1 line + +ScopLib: Fix memory issues +------------------------------------------------------------------------ +r142768 | grosser | 2011-10-24 04:59:20 +0800 (Mon, 24 Oct 2011) | 1 line + +ScopInfo: Remove unneeded code +------------------------------------------------------------------------ +r142767 | grosser | 2011-10-24 04:59:17 +0800 (Mon, 24 Oct 2011) | 1 line + +Fix compilation of Polly with scoplib support +------------------------------------------------------------------------ +r142766 | grosser | 2011-10-24 04:59:14 +0800 (Mon, 24 Oct 2011) | 3 lines + +Rename -enable-polly-viewer to -polly-run-viewer + +Similar changes for polly-only-viewer, polly-printer and polly-only-printer. +------------------------------------------------------------------------ +r142765 | grosser | 2011-10-24 04:59:11 +0800 (Mon, 24 Oct 2011) | 1 line + +RegisterPasses: Allow to disable code generation. +------------------------------------------------------------------------ +r142750 | grosser | 2011-10-23 19:17:06 +0800 (Sun, 23 Oct 2011) | 4 lines + +ScopDetection: Allow to limit the scop detection to a single function + +-polly-detect-only= allows to limit the scop detection to +a single function. +------------------------------------------------------------------------ +r142749 | grosser | 2011-10-23 19:03:06 +0800 (Sun, 23 Oct 2011) | 1 line + +Fix buildbot link +------------------------------------------------------------------------ +r142748 | grosser | 2011-10-23 19:01:07 +0800 (Sun, 23 Oct 2011) | 1 line + +Link to the new LLVM buildbots +------------------------------------------------------------------------ +r142747 | grosser | 2011-10-23 18:57:53 +0800 (Sun, 23 Oct 2011) | 1 line + +www: Describe how to load Polly into clang +------------------------------------------------------------------------ +r142746 | grosser | 2011-10-23 18:57:49 +0800 (Sun, 23 Oct 2011) | 1 line + +www: Move example into its own section (making room for another one) +------------------------------------------------------------------------ +r142745 | grosser | 2011-10-23 18:57:44 +0800 (Sun, 23 Oct 2011) | 1 line + +Add CloogInfo debug output. +------------------------------------------------------------------------ +r142744 | grosser | 2011-10-23 18:39:40 +0800 (Sun, 23 Oct 2011) | 1 line + +Update to isl 0.08 +------------------------------------------------------------------------ +r142184 | grosser | 2011-10-17 16:32:36 +0800 (Mon, 17 Oct 2011) | 3 lines + +ScopInfo: Fix ctx->ref != 0 problem + +Reported by: Yabin Hu +------------------------------------------------------------------------ +r141461 | grosser | 2011-10-08 08:49:30 +0800 (Sat, 08 Oct 2011) | 1 line + +ScopDetection: Improve error messages and add another INVALID case. +------------------------------------------------------------------------ +r141459 | grosser | 2011-10-08 08:35:17 +0800 (Sat, 08 Oct 2011) | 1 line + +ScopInfo: Proporly free the local space +------------------------------------------------------------------------ +r141458 | grosser | 2011-10-08 08:30:55 +0800 (Sat, 08 Oct 2011) | 1 line + +Show the reason a region is not a SCoP in the DOT graphs. +------------------------------------------------------------------------ +r141457 | grosser | 2011-10-08 08:30:48 +0800 (Sat, 08 Oct 2011) | 1 line + +ScopDetection: Unify the handling of invalid SCoPs +------------------------------------------------------------------------ +r141456 | grosser | 2011-10-08 08:30:44 +0800 (Sat, 08 Oct 2011) | 1 line + +Add flags to run the Polly Printers/Viewers +------------------------------------------------------------------------ +r141455 | grosser | 2011-10-08 08:30:40 +0800 (Sat, 08 Oct 2011) | 1 line + +Initialize the passes early and properly. +------------------------------------------------------------------------ +r141361 | grosser | 2011-10-07 16:46:57 +0800 (Fri, 07 Oct 2011) | 6 lines + +ScopInfo: Some cleanups + +- Use __isl_give and __isl_take +- Convert variables to start with Uppercase letter +- Only assign the 'domain' after it is fully constructed +- Only name it after it is fully constructed +------------------------------------------------------------------------ +r141359 | grosser | 2011-10-07 15:20:43 +0800 (Fri, 07 Oct 2011) | 4 lines + +Switch to the most recent version of ISL. + +This switch is not for any new features, but to test have Polly tested with +the upcoming isl 0.8. +------------------------------------------------------------------------ +r141325 | grosser | 2011-10-07 06:32:58 +0800 (Fri, 07 Oct 2011) | 1 line + +ScopInfo: Simplify the construction of the iteration domain. +------------------------------------------------------------------------ +r141303 | grosser | 2011-10-07 02:49:37 +0800 (Fri, 07 Oct 2011) | 1 line + +Change location of our buildbot +------------------------------------------------------------------------ +r141275 | grosser | 2011-10-06 14:53:17 +0800 (Thu, 06 Oct 2011) | 3 lines + +Address Sebastians comments + +This also adds some other cleanups I performed on my way. +------------------------------------------------------------------------ +r141257 | grosser | 2011-10-06 08:04:11 +0800 (Thu, 06 Oct 2011) | 5 lines + +ScopInfo: Only give away a copy of the access relation. + +Also take the chance and rename access functions to access relations. This is +because we do not only allow plain functions to describe an access, but we +can have any access relation that can be described with linear constraints. +------------------------------------------------------------------------ +r141256 | grosser | 2011-10-06 08:04:05 +0800 (Thu, 06 Oct 2011) | 1 line + +ScopInfo: Only give away a copy of the schedule. +------------------------------------------------------------------------ +r141255 | grosser | 2011-10-06 08:03:59 +0800 (Thu, 06 Oct 2011) | 1 line + +ScopInfo: Only give away a copy of the Context +------------------------------------------------------------------------ +r141254 | grosser | 2011-10-06 08:03:54 +0800 (Thu, 06 Oct 2011) | 1 line + +ScopInfo: Get the isl_ctx always with getIslCtx() +------------------------------------------------------------------------ +r141253 | grosser | 2011-10-06 08:03:48 +0800 (Thu, 06 Oct 2011) | 1 line + +ScopInfo: Use separate function to build context +------------------------------------------------------------------------ +r141252 | grosser | 2011-10-06 08:03:42 +0800 (Thu, 06 Oct 2011) | 3 lines + +Export the parameter space directly from the SCoP. + +Use this to simplify some code. +------------------------------------------------------------------------ +r141251 | grosser | 2011-10-06 08:03:35 +0800 (Thu, 06 Oct 2011) | 5 lines + +Adapt to introduction of isl_space + +Polly should now be compiled with CLooG 0c252c88946b27b7b61a1a8d8fd7f94d2461dbfd +and isl 56b7d238929980e62218525b4b3be121af386edf. The most convenient way to +update is utils/checkout_cloog.sh. +------------------------------------------------------------------------ +r141242 | grosser | 2011-10-06 07:11:17 +0800 (Thu, 06 Oct 2011) | 1 line + +checkout_cloog: Fix this script to run on our buildbot. +------------------------------------------------------------------------ +r141213 | grosser | 2011-10-06 05:11:30 +0800 (Thu, 06 Oct 2011) | 1 line + +Add forgotten " +------------------------------------------------------------------------ +r141212 | grosser | 2011-10-06 05:10:10 +0800 (Thu, 06 Oct 2011) | 5 lines + +Add a tool to checkout cloog/isl automatically with the correct versions. + +The tool is called checkout_cloog.sh. We also update the get_started +documentation to include this tool. An older unfinished tool called +'get_cloog.sh' is removed to avoid confusion. +------------------------------------------------------------------------ +r141070 | grosser | 2011-10-04 16:08:43 +0800 (Tue, 04 Oct 2011) | 1 line + +Point to our own buildbot until the official one is up again. +------------------------------------------------------------------------ +r141069 | grosser | 2011-10-04 15:53:21 +0800 (Tue, 04 Oct 2011) | 1 line + +Test: Convert to new exception handling +------------------------------------------------------------------------ +r141068 | grosser | 2011-10-04 14:56:36 +0800 (Tue, 04 Oct 2011) | 1 line + +Remove some empty lines +------------------------------------------------------------------------ +r141067 | grosser | 2011-10-04 14:55:03 +0800 (Tue, 04 Oct 2011) | 3 lines + +configure: Add gmp_inc when checking for CLooG + +Otherwise configure fails if gmp is installed in a non default location. +------------------------------------------------------------------------ +r139363 | grosser | 2011-09-09 19:02:10 +0800 (Fri, 09 Sep 2011) | 1 line + +Also force a fixed version of cloog +------------------------------------------------------------------------ +r139362 | grosser | 2011-09-09 17:08:09 +0800 (Fri, 09 Sep 2011) | 1 line + +Change installation instruction to use a fixed isl version +------------------------------------------------------------------------ +r139097 | grosser | 2011-09-04 19:45:52 +0800 (Sun, 04 Sep 2011) | 1 line + +CodeGen: Support for Cast Operations in vector code generation +------------------------------------------------------------------------ +r139096 | grosser | 2011-09-04 19:45:45 +0800 (Sun, 04 Sep 2011) | 1 line + +CodeGen: Remove unused code +------------------------------------------------------------------------ +r139095 | grosser | 2011-09-04 19:45:41 +0800 (Sun, 04 Sep 2011) | 1 line + +CodeGen: Better separate scalar and vector code generation. +------------------------------------------------------------------------ +r139094 | grosser | 2011-09-04 19:45:34 +0800 (Sun, 04 Sep 2011) | 1 line + +CodeGeneration: Simplify code, fix style. +------------------------------------------------------------------------ +r139093 | grosser | 2011-09-04 19:45:29 +0800 (Sun, 04 Sep 2011) | 1 line + +CodeGen: Split large function in smaller ones. +------------------------------------------------------------------------ +r139092 | grosser | 2011-09-04 19:45:22 +0800 (Sun, 04 Sep 2011) | 6 lines + +CodeGen: Improve naming of copied basic blocks + +It may happen that we generate the code of a basic block from the original +scop is code generated several times. The new naming scheme reduces confusing +that earlier appeared as the version numbers of the new basic blocks could +have been interpreted as part of the name of the original basic block. +------------------------------------------------------------------------ +r138555 | grosser | 2011-08-25 16:40:59 +0800 (Thu, 25 Aug 2011) | 5 lines + +Fix crashes due to unaligned parameters + +Due to the recent introduction of isl_id, parameters need now always to be +aligned. This was not yet taken care of in the code path of vectorization and +dependence analysis. +------------------------------------------------------------------------ +r138554 | grosser | 2011-08-25 16:40:52 +0800 (Thu, 25 Aug 2011) | 1 line + +ScheduleOptimizer: Fix another memleak +------------------------------------------------------------------------ +r138428 | grosser | 2011-08-24 15:33:05 +0800 (Wed, 24 Aug 2011) | 1 line + +RegisterPasses: Rework comments slightly +------------------------------------------------------------------------ +r138402 | grosser | 2011-08-24 06:35:38 +0800 (Wed, 24 Aug 2011) | 14 lines + +Register Polly passes automatically + +Polly adds, after it is loaded into opt or clang, its passes to the default set +of -O3 passes. This means optimizing a program with clang and Polly becomes as +simple as executing. + +clang -Xclang -load -Xclang lib/LLVMPolly.so -O3 program.c + +The same should work for dragonegg powered gfortran, g++, ... or any other tool +that uses the PassManagerBuilder. + +Warning: Even though using Polly became with this commit extremly easy, Polly + is still Pre-Alpha Quality. This means in most cases it will rather + destroy the world than doing anything positive. ;-) +------------------------------------------------------------------------ +r138401 | grosser | 2011-08-24 06:35:23 +0800 (Wed, 24 Aug 2011) | 1 line + +ScheduleOptimizer: Fix another memory leak +------------------------------------------------------------------------ +r138400 | grosser | 2011-08-24 06:35:08 +0800 (Wed, 24 Aug 2011) | 1 line + +Add some forgotten passes to LinkAllPasses +------------------------------------------------------------------------ +r138326 | grosser | 2011-08-23 20:31:17 +0800 (Tue, 23 Aug 2011) | 1 line + +Add information about polyhedral phone call. +------------------------------------------------------------------------ +r138325 | grosser | 2011-08-23 20:31:14 +0800 (Tue, 23 Aug 2011) | 3 lines + +ScheduleOptimizer: Fix some memory errors. + +This fixes reference counting if the schedule optimizer is used. +------------------------------------------------------------------------ +r138219 | grosser | 2011-08-21 22:57:58 +0800 (Sun, 21 Aug 2011) | 8 lines + +Temporarily remove reduction support and interchange pass + +I am planning to eliminate the TempScopInfo pass. To simplify this I remove +some features that may later be added to the ScopInfo pass. + +The interchange pass is currently strongly tested and furthermore ment to be +replaced by the general scheduling optimizer. Reductions itself can later +be added easily. +------------------------------------------------------------------------ +r138204 | grosser | 2011-08-20 19:11:25 +0800 (Sat, 20 Aug 2011) | 6 lines + +Free isl_ctx and fix several memory leaks + +Because of me not understanding the LLVM pass structure well, I did not find a +good way to allocate isl_ctx and to free it later without getting issues with +reference counting. I now found this place, such that we can free isl_ctx. This +patch also fixes the memory leaks that were ignored beforehand. +------------------------------------------------------------------------ +r138203 | grosser | 2011-08-20 19:11:18 +0800 (Sat, 20 Aug 2011) | 1 line + +GICHelper: Fix memory leaks, as we forgot to free some strings. +------------------------------------------------------------------------ +r138202 | grosser | 2011-08-20 19:11:14 +0800 (Sat, 20 Aug 2011) | 1 line + +Move common code into the function it belongs to +------------------------------------------------------------------------ +r138155 | grosser | 2011-08-20 08:03:28 +0800 (Sat, 20 Aug 2011) | 1 line + +ScopInfo/Dependences: Use parameter ids everywhere +------------------------------------------------------------------------ +r138147 | grosser | 2011-08-20 07:34:28 +0800 (Sat, 20 Aug 2011) | 3 lines + +ScopInfo: Construct the accessrelations with isl_pw_aff + +This simplifies the code quite a bit. +------------------------------------------------------------------------ +r137932 | grosser | 2011-08-18 15:51:40 +0800 (Thu, 18 Aug 2011) | 8 lines + +ScopInfo: Remove adhoc comparision of affine expressions + +Until today, we compared two affine expressions by defining two maps describing +them, creating an union of those maps, adding constraints that do the comparison +and projecting out unneeded dimensions. + +This was simplified to using the isl_pw_aff representation of the affine +expressions and using the relevant isl functions to compare them. +------------------------------------------------------------------------ +r137931 | grosser | 2011-08-18 15:51:37 +0800 (Thu, 18 Aug 2011) | 4 lines + +ScopInfo: Create all isl data structures with dimension ids + +At the moment, we still remove the ids after all data structures are created, +as later passes do not yet support ids. This limitation will be removed later. +------------------------------------------------------------------------ +r137930 | grosser | 2011-08-18 14:31:50 +0800 (Thu, 18 Aug 2011) | 5 lines + +ScopInfo: Build isl_pw_aff directly from SCEV. + +Do not use AffFunc to derive the affine expressions, but use isl_pw_aff to +analyze the original SCEV directly. This will allow several simplifications in +follow up patches, with the final goal of removing AffFunc completely. +------------------------------------------------------------------------ +r137929 | grosser | 2011-08-18 14:31:46 +0800 (Thu, 18 Aug 2011) | 1 line + +ScopInfo: Simplify code +------------------------------------------------------------------------ +r137928 | grosser | 2011-08-18 14:31:43 +0800 (Thu, 18 Aug 2011) | 1 line + +TempSCoP: Store SCEV a SCEVAffFunc was derived from +------------------------------------------------------------------------ +r137927 | grosser | 2011-08-18 14:29:25 +0800 (Thu, 18 Aug 2011) | 1 line + +TempScopInfo: Improve formatiing +------------------------------------------------------------------------ +r137607 | raghesh | 2011-08-15 17:37:46 +0800 (Mon, 15 Aug 2011) | 3 lines + +www: Updating memaccess Documentation + + +------------------------------------------------------------------------ +r137603 | raghesh | 2011-08-15 10:33:39 +0800 (Mon, 15 Aug 2011) | 6 lines + +Memaccess: Code generation for constant access function change + +Support for generating code for an access function change which is +a constant is added. + + +------------------------------------------------------------------------ +r137304 | raghesh | 2011-08-11 16:44:56 +0800 (Thu, 11 Aug 2011) | 3 lines + +Removing some trailing whitespaces + + +------------------------------------------------------------------------ +r137043 | raghesh | 2011-08-08 16:34:16 +0800 (Mon, 08 Aug 2011) | 3 lines + +Memaccess: Some style changes + + +------------------------------------------------------------------------ +r136789 | raghesh | 2011-08-04 01:02:50 +0800 (Thu, 04 Aug 2011) | 7 lines + +Memaccess: Codegeneration for a simple access function change + +Code is generated for a simple access function change imported +from JSCOP file. An access of A[i] is changed to A[0]. The code +for A[0] is generated directly without refering to isl function calls. + + +------------------------------------------------------------------------ +r136774 | raghesh | 2011-08-03 21:47:59 +0800 (Wed, 03 Aug 2011) | 6 lines + +Memaccess: Display Changed Access Relation + +The changed access relations imported from JSCOP file is shown +as output of -analyze pass. + + +------------------------------------------------------------------------ +r136750 | grosser | 2011-08-03 08:12:11 +0800 (Wed, 03 Aug 2011) | 2 lines + +ScopInfo: Do not use >"< in statement names. +Signed-off-by: Tobias Grosser +------------------------------------------------------------------------ +r136749 | grosser | 2011-08-03 08:09:49 +0800 (Wed, 03 Aug 2011) | 3 lines + +Dependences: Fix memory corruption. + +Signed-off-by: Tobias Grosser +------------------------------------------------------------------------ +r136685 | grosser | 2011-08-02 15:22:05 +0800 (Tue, 02 Aug 2011) | 3 lines + +Add a vect target to the polly testsuite + +Contributed by: Sebastian Pop +------------------------------------------------------------------------ +r136657 | grosser | 2011-08-02 06:39:00 +0800 (Tue, 02 Aug 2011) | 3 lines + +Fix two compiler warnings + +One of them actually pointed to an invalid condition in an assert. +------------------------------------------------------------------------ +r135641 | raghesh | 2011-07-21 08:08:23 +0800 (Thu, 21 Jul 2011) | 3 lines + +www: Memory Access Documentation Update + + +------------------------------------------------------------------------ +r135428 | grosser | 2011-07-19 05:27:42 +0800 (Tue, 19 Jul 2011) | 3 lines + +www: Fix typo + +Reported by: Chad Rosier +------------------------------------------------------------------------ +r135421 | grosser | 2011-07-19 04:34:41 +0800 (Tue, 19 Jul 2011) | 1 line + +www: Mention new Polly Builder in News +------------------------------------------------------------------------ +r135387 | grosser | 2011-07-18 19:00:13 +0800 (Mon, 18 Jul 2011) | 1 line + +www: Add link to buildbot into main menu +------------------------------------------------------------------------ +r135385 | grosser | 2011-07-18 17:53:35 +0800 (Mon, 18 Jul 2011) | 1 line + +www: Buildbot set up +------------------------------------------------------------------------ +r135384 | grosser | 2011-07-18 17:53:32 +0800 (Mon, 18 Jul 2011) | 1 line + +Use llvm::*Type without const +------------------------------------------------------------------------ +r135345 | chapuni | 2011-07-16 21:30:03 +0800 (Sat, 16 Jul 2011) | 1 line + +(Test commit for polly) +------------------------------------------------------------------------ +r135340 | raghesh | 2011-07-16 12:55:09 +0800 (Sat, 16 Jul 2011) | 6 lines + +Memaccess: Bugfix-Reading of JSCoP file fails + +While iterating through the memory accesses in JSCOP file +the inner loop index was not initialized to zero. + + +------------------------------------------------------------------------ +r135321 | grosser | 2011-07-16 06:54:41 +0800 (Sat, 16 Jul 2011) | 6 lines + +CodeGeneration: Adjust call to CreateCall. + +Needed to avoid compile error after the patch "Convert CallInst and +InvokeInst APIs to use ArrayRef. + +Contributed by: Sebastian Pop +------------------------------------------------------------------------ +r134991 | raghesh | 2011-07-13 01:14:03 +0800 (Wed, 13 Jul 2011) | 6 lines + +MemAccess: Reading Change in Access Function + +This patch reads the change in access functions from +imported JSCOP file. A test case is also added. + + +------------------------------------------------------------------------ +r134981 | grosser | 2011-07-12 20:43:00 +0800 (Tue, 12 Jul 2011) | 1 line + +www: Fix typo +------------------------------------------------------------------------ +r134980 | grosser | 2011-07-12 20:42:54 +0800 (Tue, 12 Jul 2011) | 4 lines + +Adapt to LLVM type system changes + +Remove constness of Types and do not name the structures generated in the OpenMP +code. +------------------------------------------------------------------------ +r134786 | raghesh | 2011-07-09 11:10:22 +0800 (Sat, 09 Jul 2011) | 6 lines + +Fix for broken build + +isl/map.h is included in OpenScopExporter.cpp and +OpenScopImporter.cpp + + +------------------------------------------------------------------------ +r134513 | grosser | 2011-07-07 02:05:05 +0800 (Thu, 07 Jul 2011) | 1 line + +ScopLib: Add missing include +------------------------------------------------------------------------ +r134512 | grosser | 2011-07-07 02:04:59 +0800 (Thu, 07 Jul 2011) | 1 line + +pollycc: Fix error message if PoCC/Pluto are not available +------------------------------------------------------------------------ +r134448 | grosser | 2011-07-06 06:15:53 +0800 (Wed, 06 Jul 2011) | 4 lines + +ScheduleOpt: Fix some bugs + +isl changed a function name, we did not properly initialize some variables +and we freed an isl_ctx object. +------------------------------------------------------------------------ +r134435 | grosser | 2011-07-06 03:13:41 +0800 (Wed, 06 Jul 2011) | 1 line + +www/memaccess: Fix forgotten typo +------------------------------------------------------------------------ +r134434 | grosser | 2011-07-06 03:13:31 +0800 (Wed, 06 Jul 2011) | 4 lines + +CodeGen: Adapt to change of PHI operand storage + +Commit 133435 "Change how PHINodes store their operands" broke Polly. Fix this +breakage by adapting to the changes in the commit. +------------------------------------------------------------------------ +r134432 | grosser | 2011-07-06 03:13:21 +0800 (Wed, 06 Jul 2011) | 4 lines + +test: Do not pipe the .ll file into opt + +The construct '< %s' complicates debugging with gdb --args as the content of +%s is interpreted as gdb input. +------------------------------------------------------------------------ +r134429 | raghesh | 2011-07-06 02:51:34 +0800 (Wed, 06 Jul 2011) | 6 lines + +www: Updating memaccess documentation + +This is a complete rewrite to memaccess.html file. This removed +some unwanted html tags. + + +------------------------------------------------------------------------ +r134400 | grosser | 2011-07-05 07:18:17 +0800 (Tue, 05 Jul 2011) | 4 lines + +test: Remove redundant function definition + +The latest version of LLVM fails, if a function is defined twice in an LLVM +bitcode file. +------------------------------------------------------------------------ +r134187 | grosser | 2011-07-01 04:29:20 +0800 (Fri, 01 Jul 2011) | 4 lines + +ScheduleOpt: Prevectorize the innermost parallel loop + +Only prevectorize loops that are actually parallel and can +be vectorized. Take the innermost loop that is eligible. +------------------------------------------------------------------------ +r134186 | grosser | 2011-07-01 04:29:13 +0800 (Fri, 01 Jul 2011) | 4 lines + +ScheduleOpt: Add first version of prevectorization + +We just strip-mine the innermost dimension by the vector width. This does not +take into account if this dimension is parallel nor if it is constant. +------------------------------------------------------------------------ +r134181 | grosser | 2011-07-01 04:01:02 +0800 (Fri, 01 Jul 2011) | 10 lines + +ScheduleOpt: Use band forest to get the schedules + +isl introduced a new representation for the schedules it calculates. The new +representation uses a forest of bands and is closer to the structure of the +data as the old interface. Switch to the new interface, as it is nicer to use +and as the old interface will soon be removed from isl. + +WARNING: This commit needs a version of isl that is more recent that the one + included in CLooG. See: + http://polly.grosser.es/get_started.html#islTrunk +------------------------------------------------------------------------ +r134180 | grosser | 2011-07-01 03:50:04 +0800 (Fri, 01 Jul 2011) | 4 lines + +Buildsystem: Add -no-rtti + +Build Polly without run time type info (rtti), as otherwise Polly cannot be +loaded into a LLVM that is built without rtti. +------------------------------------------------------------------------ +r134179 | grosser | 2011-07-01 03:39:10 +0800 (Fri, 01 Jul 2011) | 3 lines + +CodeGeneration: Adapt to SCEVExpander change + +Reported-By: Sebastian Pop +------------------------------------------------------------------------ +r134158 | grosser | 2011-06-30 22:43:35 +0800 (Thu, 30 Jun 2011) | 1 line + +www: Fix typos. +------------------------------------------------------------------------ +r134156 | grosser | 2011-06-30 22:32:33 +0800 (Thu, 30 Jun 2011) | 1 line + +www/contributers: Add founding through Google Doctoral Fellowship +------------------------------------------------------------------------ +r134153 | grosser | 2011-06-30 22:07:35 +0800 (Thu, 30 Jun 2011) | 1 line + +www/get_started: Explain when PoCC is needed +------------------------------------------------------------------------ +r134152 | grosser | 2011-06-30 22:07:23 +0800 (Thu, 30 Jun 2011) | 4 lines + +www: How to use most recent version of isl + +In some cases it is necessary to use a version of isl that is more recent than +the one included with CLooG. Point out what is needed to get such a version. +------------------------------------------------------------------------ +r133354 | raghesh | 2011-06-19 01:17:16 +0800 (Sun, 19 Jun 2011) | 3 lines + +www: Adding webpage to track memory access transformation + + +------------------------------------------------------------------------ +r133353 | raghesh | 2011-06-19 01:09:33 +0800 (Sun, 19 Jun 2011) | 3 lines + +www: Adding link to memaccess.html + + +------------------------------------------------------------------------ +r132761 | grosser | 2011-06-09 06:46:40 +0800 (Thu, 09 Jun 2011) | 1 line + +www: Fix path to git repository. +------------------------------------------------------------------------ +r132755 | grosser | 2011-06-09 01:36:11 +0800 (Thu, 09 Jun 2011) | 1 line + +www: Allow file listing in directory of example files. +------------------------------------------------------------------------ +r132678 | grosser | 2011-06-06 23:50:09 +0800 (Mon, 06 Jun 2011) | 1 line + +www: Add website for the LLVM bugtracker use +------------------------------------------------------------------------ +r132120 | grosser | 2011-05-26 20:20:16 +0800 (Thu, 26 May 2011) | 1 line + +www: Enable SSI on the webserver. +------------------------------------------------------------------------ +r131964 | grosser | 2011-05-24 21:56:06 +0800 (Tue, 24 May 2011) | 3 lines + +www: Use absolute links + +Like this the menu can also be used in subdirectories. +------------------------------------------------------------------------ +r131963 | grosser | 2011-05-24 21:29:23 +0800 (Tue, 24 May 2011) | 1 line + +www: Add documentation.html +------------------------------------------------------------------------ +r131962 | grosser | 2011-05-24 21:15:01 +0800 (Tue, 24 May 2011) | 1 line + +www: Add a separarate documentation section. +------------------------------------------------------------------------ +r131960 | grosser | 2011-05-24 20:20:07 +0800 (Tue, 24 May 2011) | 5 lines + +ScheduleOptimizer: Declare functions static + +Functions that are currently only used in this file can be declared static. + +Suggested by: ether +------------------------------------------------------------------------ +r131959 | grosser | 2011-05-24 20:20:00 +0800 (Tue, 24 May 2011) | 3 lines + +www: Add two publications + +Tobias' diploma thesis and Raghesh's master thesis. +------------------------------------------------------------------------ +r131898 | grosser | 2011-05-23 23:23:36 +0800 (Mon, 23 May 2011) | 3 lines + +CodeGeneration: Use FIXME instead of XXX + +Cleanup suggested by ether. +------------------------------------------------------------------------ +r131361 | grosser | 2011-05-15 03:02:51 +0800 (Sun, 15 May 2011) | 1 line + +www: Colorize TODO status +------------------------------------------------------------------------ +r131360 | grosser | 2011-05-15 03:02:45 +0800 (Sun, 15 May 2011) | 1 line + +CodeGeneration: Cleanup getAnalysis/addPreserved +------------------------------------------------------------------------ +r131359 | grosser | 2011-05-15 03:02:39 +0800 (Sun, 15 May 2011) | 1 line + +CodeGeneration: Localize variables +------------------------------------------------------------------------ +r131358 | grosser | 2011-05-15 03:02:34 +0800 (Sun, 15 May 2011) | 3 lines + +CodeGeneration: Admit that we change the code. + +No need to pretend anymore that we do not update the LLVM-IR. +------------------------------------------------------------------------ +r131357 | grosser | 2011-05-15 03:02:29 +0800 (Sun, 15 May 2011) | 1 line + +Cloog: Export clast_root +------------------------------------------------------------------------ +r131356 | grosser | 2011-05-15 03:02:21 +0800 (Sun, 15 May 2011) | 4 lines + +CodeGeneration: No need to forget SCoP. + +As we do not delete the SCoP, there is no need to remove it from the SCoP +detection. +------------------------------------------------------------------------ +r131355 | grosser | 2011-05-15 03:02:12 +0800 (Sun, 15 May 2011) | 1 line + +CodeGeneration: We do not preserve the PostDominatorTree +------------------------------------------------------------------------ +r131354 | grosser | 2011-05-15 03:02:06 +0800 (Sun, 15 May 2011) | 4 lines + +ScheduleOptimizer: Add an isl based schedule optimizer + +The isl based routines implement a new interpretation of the Pluto algorithm +new interpretation. This patch requires a recent version of isl to be installed. +------------------------------------------------------------------------ +r131353 | grosser | 2011-05-15 03:01:55 +0800 (Sun, 15 May 2011) | 4 lines + +CodeGeneration: Remove -polly-codegen-only + +If we only want to optimize a single function, we should extract this function +into a separate .ll file. This simplifies the code. +------------------------------------------------------------------------ +r131352 | grosser | 2011-05-15 03:01:49 +0800 (Sun, 15 May 2011) | 4 lines + +CodeGeneration: Do not delete the old version of the Scop. + +Instead of deleting the old code, keep it on the side in an if-branch. It will +either be deleted by the dead code elimination or we can use it as fallback. +------------------------------------------------------------------------ +r131351 | grosser | 2011-05-15 03:01:37 +0800 (Sun, 15 May 2011) | 1 line + +CodeGeneration: Support only simple regions +------------------------------------------------------------------------ +r131307 | grosser | 2011-05-14 04:51:45 +0800 (Sat, 14 May 2011) | 1 line + +www: Update status of our move to the LLVM infrastructure +------------------------------------------------------------------------ +r131247 | grosser | 2011-05-13 05:36:27 +0800 (Fri, 13 May 2011) | 1 line + +www: Use german 'umlaut' in Simbuerger +------------------------------------------------------------------------ +r131246 | grosser | 2011-05-13 05:33:28 +0800 (Fri, 13 May 2011) | 1 line + +ScopDetection: Move implementation of function from header to .cpp file +------------------------------------------------------------------------ +r131010 | grosser | 2011-05-07 03:52:19 +0800 (Sat, 07 May 2011) | 5 lines + +ScopInfo: Do not return reference to member variable 'domain'. + +Instead of returning a pointer to the domain, we return a new copy of it. This +is safer, as we do not give access to internal objects. It is also not +expensive, as isl will just increment a reference counter. +------------------------------------------------------------------------ +r131009 | grosser | 2011-05-07 03:52:09 +0800 (Sat, 07 May 2011) | 1 line + +Dependences: Add interface to retrieve dependences. +------------------------------------------------------------------------ +r130975 | ether | 2011-05-06 10:38:20 +0800 (Fri, 06 May 2011) | 2 lines + +ScopDetection: Remember the functions generated by backend in a pointer set, so we + do not re-generate code for these functions. +------------------------------------------------------------------------ +r130752 | ether | 2011-05-03 21:46:58 +0800 (Tue, 03 May 2011) | 1 line + +Refactor: Move 'isParallelFor' from codegen backend to Dependences analysis, so other passes can also use it. +------------------------------------------------------------------------ +r130751 | grosser | 2011-05-03 17:40:40 +0800 (Tue, 03 May 2011) | 1 line + +www: Finish first draft of the matmul example +------------------------------------------------------------------------ +r130689 | grosser | 2011-05-02 15:48:29 +0800 (Mon, 02 May 2011) | 7 lines + +Add new website for Polly + +Use the content of the Polly wiki page[1] to create a new website. I do not yet +plan to officially promote this website, but it is already a solid base that we +can improve and peer review. + +[1] http://wiki.llvm.org/Polly +------------------------------------------------------------------------ +r130586 | ether | 2011-04-30 11:26:51 +0800 (Sat, 30 Apr 2011) | 1 line + +ScopInfo: Rememeber the induction variable and its parent loop at the same thime. +------------------------------------------------------------------------ +r130575 | ether | 2011-04-30 10:47:34 +0800 (Sat, 30 Apr 2011) | 1 line + +JSON: Do not use throw when exception is disabled. +------------------------------------------------------------------------ +r130574 | ether | 2011-04-30 10:30:58 +0800 (Sat, 30 Apr 2011) | 1 line + +JSON: Disable exception in JSON library, because exception is disable by by default. +------------------------------------------------------------------------ +r130484 | simbuerg | 2011-04-29 15:54:20 +0800 (Fri, 29 Apr 2011) | 2 lines + +Add e-mail to credits file. + +------------------------------------------------------------------------ +r130482 | ether | 2011-04-29 15:34:54 +0800 (Fri, 29 Apr 2011) | 1 line + +Partial support test polly for out of tree build. +------------------------------------------------------------------------ +r130481 | grosser | 2011-04-29 14:52:36 +0800 (Fri, 29 Apr 2011) | 1 line + +JSONExport: Some cleanups +------------------------------------------------------------------------ +r130480 | grosser | 2011-04-29 14:42:42 +0800 (Fri, 29 Apr 2011) | 1 line + +CREDITS: Replace LLVM with Polly +------------------------------------------------------------------------ +r130478 | grosser | 2011-04-29 14:29:20 +0800 (Fri, 29 Apr 2011) | 1 line + +Add a converter from jscop to iscc input +------------------------------------------------------------------------ +r130477 | grosser | 2011-04-29 14:27:09 +0800 (Fri, 29 Apr 2011) | 1 line + +JSONExporter: Remove unused variable +------------------------------------------------------------------------ +r130476 | grosser | 2011-04-29 14:27:02 +0800 (Fri, 29 Apr 2011) | 4 lines + +Add initial version of Polly + +This version is equivalent to commit ba26ebece8f5be84e9bd6315611d412af797147e +in the old git repository. +------------------------------------------------------------------------ +r130389 | asl | 2011-04-28 15:28:28 +0800 (Thu, 28 Apr 2011) | 2 lines + +Add BTT directory structure to polly + +------------------------------------------------------------------------ diff --git a/tools/polly/test/CMakeLists.txt b/tools/polly/test/CMakeLists.txt new file mode 100644 index 00000000000..72cecf4e387 --- /dev/null +++ b/tools/polly/test/CMakeLists.txt @@ -0,0 +1,69 @@ +set(POLLY_TEST_DIRECTORIES + "AffineIterator" + "ScopInfo" + "ScheduleOptimizer" + "CodeGen" + "Cloog" + "OpenMP" + "polybench" + "vect") + + +set(POLLY_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") +set(POLLY_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..") +set(LLVM_SHLIBEXT "${CMAKE_SHARED_LIBRARY_SUFFIX}") + +if (NOT DEFINED LLVM_MAIN_SRC_DIR) + # We are building polly out of tree, adjust the settings. + # FIXME: FileCheck is not available in llvm install directory at the moment. + set(LLVM_LIT ${LLVM_INSTALL_ROOT}/bin/llvm-lit) + set(POLLY_TEST_DEPS LLVMPolly) + + set(LLVM_BINARY_DIR "${LLVM_INSTALL_ROOT}") + set(LLVM_TOOLS_DIR "${LLVM_INSTALL_ROOT}/bin") + set(LLVM_LIBS_DIR "${LLVM_INSTALL_ROOT}/lib") +else (NOT DEFINED LLVM_MAIN_SRC_DIR) + set(LLVM_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit) + set(POLLY_TEST_DEPS opt lli LLVMPolly FileCheck not) + + set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}") + set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}/") + set(LLVM_LIBS_DIR "${LLVM_BINARY_DIR}/lib") +endif (NOT DEFINED LLVM_MAIN_SRC_DIR) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg) + +include(FindPythonInterp) +if(PYTHONINTERP_FOUND) + set(POLLY_TEST_EXTRA_ARGS) + if (MSVC OR XCODE) + set(POLLY_TEST_EXTRA_ARGS "--no-progress-bar") + endif() + + option(POLLY_TEST_USE_VG "Run Polly tests under Valgrind" OFF) + if(POLLY_TEST_USE_VG) + set(POLLY_TEST_EXTRA_ARGS ${POLLY_TEST_EXTRA_ARGS} "--vg") + endif () + + foreach(testdir ${POLLY_TEST_DIRECTORIES}) + add_custom_target(polly-test-${testdir} + COMMAND ${LLVM_LIT} + --param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + --param build_config=${CMAKE_CFG_INTDIR} + -sv ${POLLY_TEST_EXTRA_ARGS} + ${CMAKE_CURRENT_BINARY_DIR}/${testdir} + DEPENDS ${POLLY_TEST_DEPS} + COMMENT "Running Polly regression tests in ${testdir}") + endforeach() + + add_custom_target(polly-test + COMMAND ${LLVM_LIT} + --param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + --param build_config=${CMAKE_CFG_INTDIR} + -sv ${POLLY_TEST_EXTRA_ARGS} + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${POLLY_TEST_DEPS} + COMMENT "Running Polly regression tests") +endif() diff --git a/tools/polly/test/Cloog/ambigous_schedule.ll b/tools/polly/test/Cloog/ambigous_schedule.ll new file mode 100644 index 00000000000..436818929b3 --- /dev/null +++ b/tools/polly/test/Cloog/ambigous_schedule.ll @@ -0,0 +1,118 @@ +; RUN: opt %loadPolly %defaultOpts -polly-import-jscop-dir=%S -polly-import-jscop -polly-cloog -analyze %s | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@A = common global [100 x [100 x double]] zeroinitializer, align 16 +@B = common global [100 x [100 x double]] zeroinitializer, align 16 + +define void @ambigous_schedule() nounwind uwtable { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc6, %entry + %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ] + %cmp = icmp slt i32 %i.0, 100 + br i1 %cmp, label %for.body, label %for.end8 + +for.body: ; preds = %for.cond + br label %for.cond1 + +for.cond1: ; preds = %for.inc, %for.body + %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ] + %cmp2 = icmp slt i32 %j.0, 100 + br i1 %cmp2, label %for.body3, label %for.end + +for.body3: ; preds = %for.cond1 + %add = add nsw i32 %i.0, %j.0 + %conv = sitofp i32 %add to double + %idxprom = sext i32 %j.0 to i64 + %idxprom4 = sext i32 %i.0 to i64 + %arrayidx = getelementptr inbounds [100 x [100 x double]]* @A, i32 0, i64 %idxprom4 + %arrayidx5 = getelementptr inbounds [100 x double]* %arrayidx, i32 0, i64 %idxprom + store double %conv, double* %arrayidx5, align 8 + br label %for.inc + +for.inc: ; preds = %for.body3 + %inc = add nsw i32 %j.0, 1 + br label %for.cond1 + +for.end: ; preds = %for.cond1 + br label %for.inc6 + +for.inc6: ; preds = %for.end + %inc7 = add nsw i32 %i.0, 1 + br label %for.cond + +for.end8: ; preds = %for.cond + br label %for.cond10 + +for.cond10: ; preds = %for.inc28, %for.end8 + %i9.0 = phi i32 [ 0, %for.end8 ], [ %inc29, %for.inc28 ] + %cmp11 = icmp slt i32 %i9.0, 100 + br i1 %cmp11, label %for.body13, label %for.end30 + +for.body13: ; preds = %for.cond10 + br label %for.cond15 + +for.cond15: ; preds = %for.inc25, %for.body13 + %j14.0 = phi i32 [ 0, %for.body13 ], [ %inc26, %for.inc25 ] + %cmp16 = icmp slt i32 %j14.0, 100 + br i1 %cmp16, label %for.body18, label %for.end27 + +for.body18: ; preds = %for.cond15 + %add19 = add nsw i32 %i9.0, %j14.0 + %conv20 = sitofp i32 %add19 to double + %idxprom21 = sext i32 %j14.0 to i64 + %idxprom22 = sext i32 %i9.0 to i64 + %arrayidx23 = getelementptr inbounds [100 x [100 x double]]* @B, i32 0, i64 %idxprom22 + %arrayidx24 = getelementptr inbounds [100 x double]* %arrayidx23, i32 0, i64 %idxprom21 + store double %conv20, double* %arrayidx24, align 8 + br label %for.inc25 + +for.inc25: ; preds = %for.body18 + %inc26 = add nsw i32 %j14.0, 1 + br label %for.cond15 + +for.end27: ; preds = %for.cond15 + br label %for.inc28 + +for.inc28: ; preds = %for.end27 + %inc29 = add nsw i32 %i9.0, 1 + br label %for.cond10 + +for.end30: ; preds = %for.cond10 + ret void +} + +; CHECK: for (c2=0;c2<=99;c2++) { +; CHECK: for (c3=0;c3<=99;c3++) { +; CHECK: Stmt_for_body3(c2,c3); +; CHECK: Stmt_for_body18(c3,c2); +; CHECK: } +; CHECK: } + +; This check makes sure CLooG stops splitting for ambigious schedules as +; they may be generated by the isl/PoCC/Pluto schedule optimizers. +; +; Previously we created such code: +; +; for (c2=0;c2<=99;c2++) { +; for (c3=0;c3<=99;c3++) { +; if (c2 == c3) { +; Stmt_for_body3(c2,c2); +; Stmt_for_body18(c2,c2); +; } +; if (c2 <= c3-1) { +; Stmt_for_body3(c2,c3); +; } +; if (c2 <= c3-1) { +; Stmt_for_body18(c3,c2); +; } +; if (c2 >= c3+1) { +; Stmt_for_body18(c3,c2); +; } +; if (c2 >= c3+1) { +; Stmt_for_body3(c2,c3); +; } +; } +; } diff --git a/tools/polly/test/Cloog/ambigous_schedule___%for.cond---%for.end30.jscop b/tools/polly/test/Cloog/ambigous_schedule___%for.cond---%for.end30.jscop new file mode 100644 index 00000000000..ec9f89ccf8c --- /dev/null +++ b/tools/polly/test/Cloog/ambigous_schedule___%for.cond---%for.end30.jscop @@ -0,0 +1,28 @@ +{ + "context" : "{ : }", + "name" : "for.cond => for.end30", + "statements" : [ + { + "accesses" : [ + { + "kind" : "write", + "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[100i0 + i1] }" + } + ], + "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 99 }", + "name" : "Stmt_for_body3", + "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, i1, 0] }" + }, + { + "accesses" : [ + { + "kind" : "write", + "relation" : "{ Stmt_for_body18[i0, i1] -> MemRef_B[100i0 + i1] }" + } + ], + "domain" : "{ Stmt_for_body18[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 99 }", + "name" : "Stmt_for_body18", + "schedule" : "{ Stmt_for_body18[i0, i1] -> scattering[0, i1, i0, 0] }" + } + ] +} diff --git a/tools/polly/test/CodeGen/20100617.ll b/tools/polly/test/CodeGen/20100617.ll new file mode 100644 index 00000000000..99a34d7d8b4 --- /dev/null +++ b/tools/polly/test/CodeGen/20100617.ll @@ -0,0 +1,20 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen %s +; ModuleID = 'a' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @init_array() nounwind { +entry: + br label %for.cond + +for.cond: ; preds = %for.cond1, %entry + %indvar1 = phi i64 [ %indvar.next2, %for.cond1 ], [ 0, %entry ] ; [#uses=1] + br i1 false, label %for.cond1, label %for.end32 + +for.cond1: ; preds = %for.cond + %indvar.next2 = add i64 %indvar1, 1 ; [#uses=1] + br label %for.cond + +for.end32: ; preds = %for.cond + ret void +} diff --git a/tools/polly/test/CodeGen/20100622.ll b/tools/polly/test/CodeGen/20100622.ll new file mode 100644 index 00000000000..cf3df10d367 --- /dev/null +++ b/tools/polly/test/CodeGen/20100622.ll @@ -0,0 +1,44 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen %s +; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | not FileCheck %s + +; ModuleID = 'a' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i386-portbld-freebsd8.0" + +define void @MAIN__() nounwind { +entry: + br i1 undef, label %bb6.preheader, label %bb3 + +bb3: ; preds = %bb3, %entry + br i1 undef, label %bb6.preheader, label %bb3 + +bb6.preheader: ; preds = %bb3, %entry + br i1 undef, label %bb11, label %bb9.preheader + +bb9.preheader: ; preds = %bb6.preheader + br label %bb11 + +bb11: ; preds = %bb9.preheader, %bb6.preheader + br label %bb15 + +bb15: ; preds = %bb15, %bb11 + br i1 undef, label %bb26.loopexit, label %bb15 + +bb26.loopexit: ; preds = %bb15 + br i1 undef, label %bb31, label %bb29.preheader + +bb29.preheader: ; preds = %bb26.loopexit + br label %bb29 + +bb29: ; preds = %bb29, %bb29.preheader + %indvar47 = phi i32 [ 0, %bb29.preheader ], [ %indvar.next48, %bb29 ] ; [#uses=1] + %indvar.next48 = add i32 %indvar47, 1 ; [#uses=2] + %exitcond50 = icmp eq i32 %indvar.next48, undef ; [#uses=1] + br i1 %exitcond50, label %bb31, label %bb29 + +bb31: ; preds = %bb29, %bb26.loopexit + %errtot.3 = phi float [ undef, %bb26.loopexit ], [ undef, %bb29 ] ; [#uses=0] + ret void +} + +; CHECK: SCOP: diff --git a/tools/polly/test/CodeGen/20100707.ll b/tools/polly/test/CodeGen/20100707.ll new file mode 100644 index 00000000000..bcef23c70c7 --- /dev/null +++ b/tools/polly/test/CodeGen/20100707.ll @@ -0,0 +1,28 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen %s +; ModuleID = 'a' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @clause_SetSplitField(i32 %Length) nounwind inlinehint { +entry: + br i1 undef, label %bb1, label %bb6 + +bb1: ; preds = %entry + unreachable + +bb6: ; preds = %entry + %tmp = zext i32 %Length to i64 ; [#uses=1] + br label %bb8 + +bb7: ; preds = %bb8 + %indvar.next = add i64 %indvar, 1 ; [#uses=1] + br label %bb8 + +bb8: ; preds = %bb7, %bb6 + %indvar = phi i64 [ %indvar.next, %bb7 ], [ 0, %bb6 ] ; [#uses=2] + %exitcond = icmp ne i64 %indvar, %tmp ; [#uses=1] + br i1 %exitcond, label %bb7, label %return + +return: ; preds = %bb8 + ret void +} diff --git a/tools/polly/test/CodeGen/20100707_2.ll b/tools/polly/test/CodeGen/20100707_2.ll new file mode 100644 index 00000000000..96d8cbae7d1 --- /dev/null +++ b/tools/polly/test/CodeGen/20100707_2.ll @@ -0,0 +1,116 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen %s +; ModuleID = 'bugpoint-reduced-simplified.bc' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +@win193 = external global [4 x [36 x double]], align 32 ; <[4 x [36 x double]]*> [#uses=3] +@sb_sample = external global [2 x [2 x [18 x [32 x double]]]], align 32 ; <[2 x [2 x [18 x [32 x double]]]]*> [#uses=2] + +define void @mdct_sub48() nounwind { +entry: + br i1 undef, label %bb, label %bb54 + +bb: ; preds = %entry + br label %bb54 + +bb3: ; preds = %bb50 + br label %bb8 + +bb4: ; preds = %bb8 + br label %bb8 + +bb8: ; preds = %bb4, %bb3 + br i1 undef, label %bb4, label %bb9 + +bb9: ; preds = %bb8 + br label %bb48 + +bb25: ; preds = %bb48 + br i1 false, label %bb26, label %bb27 + +bb26: ; preds = %bb48, %bb25 + br label %bb37 + +bb27: ; preds = %bb25 + br i1 undef, label %bb32, label %bb35 + +bb32: ; preds = %bb27 + br label %bb37 + +bb34: ; preds = %bb35 + %0 = getelementptr inbounds [36 x double]* undef, i64 0, i64 0 ; [#uses=0] + %1 = getelementptr inbounds [18 x [32 x double]]* undef, i64 0, i64 0 ; <[32 x double]*> [#uses=1] + %2 = getelementptr inbounds [32 x double]* %1, i64 0, i64 0 ; [#uses=0] + %3 = getelementptr inbounds [36 x double]* undef, i64 0, i64 0 ; [#uses=0] + %4 = sub nsw i32 17, %k.4 ; [#uses=1] + %5 = getelementptr inbounds [2 x [2 x [18 x [32 x double]]]]* @sb_sample, i64 0, i64 0 ; <[2 x [18 x [32 x double]]]*> [#uses=1] + %6 = getelementptr inbounds [2 x [18 x [32 x double]]]* %5, i64 0, i64 0 ; <[18 x [32 x double]]*> [#uses=1] + %7 = sext i32 %4 to i64 ; [#uses=1] + %8 = getelementptr inbounds [18 x [32 x double]]* %6, i64 0, i64 %7 ; <[32 x double]*> [#uses=1] + %9 = getelementptr inbounds [32 x double]* %8, i64 0, i64 0 ; [#uses=1] + %10 = load double* %9, align 8 ; [#uses=0] + %11 = fsub double 0.000000e+00, undef ; [#uses=1] + %12 = getelementptr inbounds double* getelementptr inbounds ([4 x [36 x double]]* @win193, i64 0, i64 2, i64 4), i64 0 ; [#uses=1] + store double %11, double* %12, align 8 + %13 = add nsw i32 %k.4, 9 ; [#uses=1] + %14 = add nsw i32 %k.4, 18 ; [#uses=1] + %15 = getelementptr inbounds [4 x [36 x double]]* @win193, i64 0, i64 0 ; <[36 x double]*> [#uses=1] + %16 = sext i32 %14 to i64 ; [#uses=1] + %17 = getelementptr inbounds [36 x double]* %15, i64 0, i64 %16 ; [#uses=1] + %18 = load double* %17, align 8 ; [#uses=0] + %19 = sext i32 %k.4 to i64 ; [#uses=1] + %20 = getelementptr inbounds [18 x [32 x double]]* undef, i64 0, i64 %19 ; <[32 x double]*> [#uses=1] + %21 = sext i32 %band.2 to i64 ; [#uses=1] + %22 = getelementptr inbounds [32 x double]* %20, i64 0, i64 %21 ; [#uses=1] + %23 = load double* %22, align 8 ; [#uses=0] + %24 = sext i32 %39 to i64 ; [#uses=1] + %25 = getelementptr inbounds [4 x [36 x double]]* @win193, i64 0, i64 %24 ; <[36 x double]*> [#uses=1] + %26 = getelementptr inbounds [36 x double]* %25, i64 0, i64 0 ; [#uses=1] + %27 = load double* %26, align 8 ; [#uses=0] + %28 = sub nsw i32 17, %k.4 ; [#uses=1] + %29 = getelementptr inbounds [2 x [2 x [18 x [32 x double]]]]* @sb_sample, i64 0, i64 0 ; <[2 x [18 x [32 x double]]]*> [#uses=1] + %30 = getelementptr inbounds [2 x [18 x [32 x double]]]* %29, i64 0, i64 0 ; <[18 x [32 x double]]*> [#uses=1] + %31 = sext i32 %28 to i64 ; [#uses=1] + %32 = getelementptr inbounds [18 x [32 x double]]* %30, i64 0, i64 %31 ; <[32 x double]*> [#uses=1] + %33 = getelementptr inbounds [32 x double]* %32, i64 0, i64 0 ; [#uses=1] + %34 = load double* %33, align 8 ; [#uses=0] + %35 = sext i32 %13 to i64 ; [#uses=1] + %36 = getelementptr inbounds double* getelementptr inbounds ([4 x [36 x double]]* @win193, i64 0, i64 2, i64 4), i64 %35 ; [#uses=1] + store double 0.000000e+00, double* %36, align 8 + %37 = sub nsw i32 %k.4, 1 ; [#uses=1] + br label %bb35 + +bb35: ; preds = %bb34, %bb27 + %k.4 = phi i32 [ %37, %bb34 ], [ 8, %bb27 ] ; [#uses=6] + br i1 undef, label %bb34, label %bb36 + +bb36: ; preds = %bb35 + unreachable + +bb37: ; preds = %bb32, %bb26 + %38 = add nsw i32 %band.2, 1 ; [#uses=1] + br label %bb48 + +bb48: ; preds = %bb37, %bb9 + %band.2 = phi i32 [ %38, %bb37 ], [ 0, %bb9 ] ; [#uses=2] + %39 = load i32* null, align 8 ; [#uses=1] + br i1 undef, label %bb26, label %bb25 + +bb50: ; preds = %bb54 + br i1 undef, label %bb3, label %bb51 + +bb51: ; preds = %bb50 + br i1 undef, label %bb52, label %bb53 + +bb52: ; preds = %bb51 + unreachable + +bb53: ; preds = %bb51 + br label %bb54 + +bb54: ; preds = %bb53, %bb, %entry + br i1 undef, label %bb50, label %return + +return: ; preds = %bb54 + ret void +} diff --git a/tools/polly/test/CodeGen/20100708.ll b/tools/polly/test/CodeGen/20100708.ll new file mode 100644 index 00000000000..533d42a8cc0 --- /dev/null +++ b/tools/polly/test/CodeGen/20100708.ll @@ -0,0 +1,19 @@ +; RUN: opt %loadPolly %defaultOpts -polly-detect %s +; ModuleID = '/tmp/bug.ll' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define fastcc void @execute() nounwind { +entry: + br i1 undef, label %check_stack.exit456.thread, label %bb.i451.preheader + +bb.i451.preheader: ; preds = %bb116 + br label %bb.i451 + +bb.i451: ; preds = %bb.i451, %bb.i451.preheader + br label %bb.i451 + +check_stack.exit456.thread: ; preds = %bb116 + unreachable + +} diff --git a/tools/polly/test/CodeGen/20100708_2.ll b/tools/polly/test/CodeGen/20100708_2.ll new file mode 100644 index 00000000000..d03c54c344b --- /dev/null +++ b/tools/polly/test/CodeGen/20100708_2.ll @@ -0,0 +1,29 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen %s +; ModuleID = '/home/grosser/Projekte/polly/git/tools/polly/test/CodeGen/20100708_2.ll' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-pc-linux-gnu" + +define void @init_array() nounwind { +bb: + br label %bb1 + +bb1: ; preds = %bb4, %bb + br i1 undef, label %bb2, label %bb5 + +bb2: ; preds = %bb3, %bb1 + %indvar = phi i64 [ %indvar.next, %bb3 ], [ 0, %bb1 ] ; [#uses=1] + %tmp3 = trunc i64 undef to i32 ; [#uses=1] + br i1 false, label %bb3, label %bb4 + +bb3: ; preds = %bb2 + %tmp = srem i32 %tmp3, 1024 ; [#uses=0] + store double undef, double* undef + %indvar.next = add i64 %indvar, 1 ; [#uses=1] + br label %bb2 + +bb4: ; preds = %bb2 + br label %bb1 + +bb5: ; preds = %bb1 + ret void +} diff --git a/tools/polly/test/CodeGen/20100713.ll b/tools/polly/test/CodeGen/20100713.ll new file mode 100644 index 00000000000..4b78b7c9efb --- /dev/null +++ b/tools/polly/test/CodeGen/20100713.ll @@ -0,0 +1,35 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen %s +; ModuleID = 'bugpoint-reduced-simplified.bc' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @fft_float(i32 %NumSamples) nounwind { + br label %bb18 + +bb18: ; preds = %bb17 + br i1 false, label %bb19, label %bb22 + +bb19: ; preds = %bb18 + %a = uitofp i32 %NumSamples to double ; [#uses=1] + br label %bb21 + +bb20: ; preds = %bb21 + %1 = load float* undef, align 4 ; [#uses=0] + %2 = fpext float undef to double ; [#uses=1] + %3 = fdiv double %2, %a ; [#uses=0] + %indvar.next = add i64 %indvar, 1 ; [#uses=1] + br label %bb21 + +bb21: ; preds = %bb20, %bb19 + %indvar = phi i64 [ %indvar.next, %bb20 ], [ 0, %bb19 ] ; [#uses=1] + br i1 false, label %bb20, label %bb22.loopexit + +bb22.loopexit: ; preds = %bb21 + br label %bb22 + +bb22: ; preds = %bb22.loopexit, %bb18 + br label %return + +return: ; preds = %bb22 + ret void +} diff --git a/tools/polly/test/CodeGen/20100713_2.ll b/tools/polly/test/CodeGen/20100713_2.ll new file mode 100644 index 00000000000..9603c27e587 --- /dev/null +++ b/tools/polly/test/CodeGen/20100713_2.ll @@ -0,0 +1,35 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen %s +; ModuleID = 'bugpoint-reduced-simplified.bc' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define hidden void @luaD_callhook() nounwind { +entry: + br i1 undef, label %bb, label %return + +bb: ; preds = %entry + br i1 undef, label %bb1, label %return + +bb1: ; preds = %bb + %0 = sub nsw i64 undef, undef ; [#uses=1] + br i1 false, label %bb2, label %bb3 + +bb2: ; preds = %bb1 + br label %bb4 + +bb3: ; preds = %bb1 + br label %bb4 + +bb4: ; preds = %bb3, %bb2 + br i1 undef, label %bb5, label %bb6 + +bb5: ; preds = %bb4 + unreachable + +bb6: ; preds = %bb4 + %1 = getelementptr inbounds i8* undef, i64 %0 ; [#uses=0] + ret void + +return: ; preds = %bb, %entry + ret void +} diff --git a/tools/polly/test/CodeGen/20100717.ll b/tools/polly/test/CodeGen/20100717.ll new file mode 100644 index 00000000000..611ce29969f --- /dev/null +++ b/tools/polly/test/CodeGen/20100717.ll @@ -0,0 +1,40 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen -disable-output %s +; ModuleID = 'bugpoint-reduced-simplified.bc' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @matrixTranspose(double** %A) nounwind { +entry: + br label %bb4 + +bb: ; preds = %bb4 + %0 = add nsw i32 %i.0, 1 ; [#uses=1] + br label %bb2 + +bb1: ; preds = %bb2 + %1 = getelementptr inbounds double** %A, i64 0 ; [#uses=0] + %2 = getelementptr inbounds double** %A, i64 0 ; [#uses=0] + %3 = getelementptr inbounds double** %A, i64 0 ; [#uses=0] + %4 = sext i32 %j.0 to i64 ; [#uses=1] + %5 = getelementptr inbounds double** %A, i64 %4 ; [#uses=1] + %6 = load double** %5, align 8 ; [#uses=0] + %7 = add nsw i32 %j.0, 1 ; [#uses=1] + br label %bb2 + +bb2: ; preds = %bb1, %bb + %j.0 = phi i32 [ %0, %bb ], [ %7, %bb1 ] ; [#uses=3] + %8 = icmp sle i32 %j.0, 50 ; [#uses=1] + br i1 %8, label %bb1, label %bb3 + +bb3: ; preds = %bb2 + %9 = add nsw i32 %i.0, 1 ; [#uses=1] + br label %bb4 + +bb4: ; preds = %bb3, %entry + %i.0 = phi i32 [ 0, %entry ], [ %9, %bb3 ] ; [#uses=3] + %10 = icmp sle i32 %i.0, 50 ; [#uses=1] + br i1 %10, label %bb, label %return + +return: ; preds = %bb4 + ret void +} diff --git a/tools/polly/test/CodeGen/20100718-DomInfo-2.ll b/tools/polly/test/CodeGen/20100718-DomInfo-2.ll new file mode 100644 index 00000000000..b004013ef68 --- /dev/null +++ b/tools/polly/test/CodeGen/20100718-DomInfo-2.ll @@ -0,0 +1,36 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen -verify-dom-info -disable-output %s +; ModuleID = 'bugpoint-reduced-simplified.bc' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @getNonAffNeighbour() nounwind { +entry: + br i1 undef, label %bb, label %bb6 + +bb: ; preds = %entry + br i1 false, label %bb1, label %bb2 + +bb1: ; preds = %bb + br label %bb16 + +bb2: ; preds = %bb + br i1 false, label %bb3, label %bb4 + +bb3: ; preds = %bb2 + br label %bb16 + +bb4: ; preds = %bb2 + br label %bb16 + +bb6: ; preds = %entry + br i1 false, label %bb7, label %bb9 + +bb7: ; preds = %bb6 + br label %bb16 + +bb9: ; preds = %bb6 + br label %bb16 + +bb16: ; preds = %bb9, %bb7, %bb4, %bb3, %bb1 + ret void +} diff --git a/tools/polly/test/CodeGen/20100718-DomInfo.ll b/tools/polly/test/CodeGen/20100718-DomInfo.ll new file mode 100644 index 00000000000..db7682d06b7 --- /dev/null +++ b/tools/polly/test/CodeGen/20100718-DomInfo.ll @@ -0,0 +1,29 @@ +; RUN: opt %loadPolly %defaultOpts -polly-codegen -verify-dom-info -disable-output %s +; ModuleID = 'bugpoint-reduced-simplified.bc' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define void @intrapred_luma_16x16(i32 %predmode) nounwind { +entry: + switch i32 %predmode, label %bb81 [ + i32 0, label %bb25 + i32 1, label %bb26 + ] + +bb23: ; preds = %bb25 + %indvar.next95 = add i64 %indvar94, 1 ; [#uses=1] + br label %bb25 + +bb25: ; preds = %bb23, %entry + %indvar94 = phi i64 [ %indvar.next95, %bb23 ], [ 0, %entry ] ; [#uses=1] + br i1 false, label %bb23, label %return + +bb26: ; preds = %entry + ret void + +bb81: ; preds = %entry + ret void + +return: ; preds = %bb25 + ret void +} diff --git a/tools/polly/test/CodeGen/20100720-MultipleConditions.c b/tools/polly/test/CodeGen/20100720-MultipleConditions.c new file mode 100644 index 00000000000..15d6d56c0b5 --- /dev/null +++ b/tools/polly/test/CodeGen/20100720-MultipleConditions.c @@ -0,0 +1,23 @@ +int bar1(); +int bar2(); +int bar3(); +int k; +#define N 100 +int A[N]; + +int main() { + int i, j, z; + + __sync_synchronize(); + for (i = 0; i < N; i++) { + if (i < 50) + A[i] = 8; + if (i < 4) + A[i] = 9; + if (i < 3) + A[i] = 10; + } + __sync_synchronize(); + + return A[z]; +} diff --git a/tools/polly/test/CodeGen/20100720-MultipleConditions.ll b/tools/polly/test/CodeGen/20100720-MultipleConditions.ll new file mode 100644 index 00000000000..796f2919241 --- /dev/null +++ b/tools/polly/test/CodeGen/20100720-MultipleConditions.ll @@ -0,0 +1,73 @@ +; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s +; ModuleID = '20100720-MultipleConditions.s' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-pc-linux-gnu" + +@A = common global [100 x i32] zeroinitializer, align 16 ; <[100 x i32]*> [#uses=2] +@k = common global i32 0, align 4 ; [#uses=0] + +define i32 @main() nounwind { +;