1 diff --git a/.gitmodules b/.gitmodules
9 + url = https://github.com/periscop/openscop.git
12 + url = https://github.com/periscop/piplib.git
13 diff --git a/CMakeLists.txt b/CMakeLists.txt
15 index 0000000..a16d5e4
19 +cmake_minimum_required(VERSION 2.8)
22 +set(PACKAGE_VERSION "0.6.2")
23 +set(RELEASE "${PACKAGE_VERSION}")
25 +set(DEFINE_HAS_ISL_LIB "")
26 +set(top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
28 +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
31 +# User's settings - C Flags
33 +# set(release "TRUE")
34 + set(release "FALSE")
38 + set(CMAKE_C_FLAGS "-O3")
39 + # Debug # valgrind --show-reachable=yes --leak-check=full -v exe
41 + set(CMAKE_C_FLAGS "-O0 -g3")
44 +# User's settings - General C Flags
45 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -std=c99")
49 + find_package(Doxygen)
51 + configure_file("doc/Doxyfile.in" "Doxyfile")
54 + ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
55 + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
56 + COMMENT "Generating API documentation with Doxygen" VERBATIM
59 + message (STATUS "Doxygen not found :( API documentation can not be built")
62 +# Build documentation
65 + find_program(texi2pdf_exe texi2pdf)
69 + ${texi2pdf_exe} ${CMAKE_CURRENT_SOURCE_DIR}/doc/candl.texi --output=${CMAKE_CURRENT_BINARY_DIR}/candl.pdf
70 + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
71 + COMMENT "Generating documentation (pdf) (with texi2pdf)" VERBATIM
74 + message (STATUS "texi2pdf not found :( Documentation can not be built")
79 + find_package(osl REQUIRED)
82 + message(STATUS "---")
83 + find_library(gmp_LIB gmp)
85 + message (STATUS "Library gmp found =) ${gmp_LIB}")
88 + find_package(piplibMP REQUIRED)
90 + message(STATUS "Library gmp not found :(")
92 + find_package(piplib64 REQUIRED)
95 +# Include directories (to use #include <> instead of #include "")
97 + # include/candl/macros.h
98 + configure_file("include/candl/macros.h.in" "include/candl/macros.h")
99 + include_directories("${CMAKE_CURRENT_BINARY_DIR}/include")
101 + include_directories("./include")
105 + message(STATUS "---")
106 + message(STATUS "C compiler = ${CMAKE_C_COMPILER}")
108 + message(STATUS "Mode Release")
110 + message(STATUS "Mode Debug")
112 + message(STATUS "C flags = ${CMAKE_C_FLAGS}")
117 + message(STATUS "---")
125 + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/source/candl.c;" "" sources "${sources}") # with ;
126 + string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/source/candl.c" "" sources "${sources}") # without ;
134 + target_link_libraries(candl ${OSL_LIBRARY})
136 + target_link_libraries(candl ${PIPLIBMP_LIBRARY})
138 + target_link_libraries(candl ${PIPLIB64_LIBRARY})
140 + get_property(candl_lib_location TARGET candl PROPERTY LOCATION)
141 + message(STATUS "Add candl library (shared) ${candl_lib_location}")
149 + set_target_properties(candl_static PROPERTIES OUTPUT_NAME candl)
151 + target_link_libraries(candl_static ${PIPLIBMP_LIBRARY})
153 + target_link_libraries(candl_static ${PIPLIB64_LIBRARY})
155 + target_link_libraries(candl_static ${OSL_LIBRARY})
156 + get_property(candl_static_lib_location TARGET candl_static PROPERTY LOCATION)
157 + message(STATUS "Add candl library (static) ${candl_static_lib_location}")
160 +# Executables & tests
162 + message(STATUS "---") # candl
164 + message(STATUS "Add executable candl")
165 + add_executable(candl_exe "source/candl.c")
166 + set_target_properties(candl_exe PROPERTIES OUTPUT_NAME "candl")
167 + target_link_libraries(candl_exe candl_static ${OSL_LIBRARY})
169 + target_link_libraries(candl_exe candl_static ${gmp_LIB})
173 + find_program(bash_exe bash)
176 + message(STATUS "---")
186 + foreach(test ${tests_unitary})
187 + message(STATUS "Add Unitary test ${test}")
189 + "tests_unitary_${test}"
191 + "${CMAKE_CURRENT_SOURCE_DIR}/tests/checker.sh"
200 + tests_transformations_must_fail
201 + tests/transformations/must_fail/*.c
204 + foreach(test ${tests_transformations_must_fail})
205 + message(STATUS "Add Transformation must fail test ${test}")
207 + "tests_transformations_must_fail_${test}"
209 + "${CMAKE_CURRENT_SOURCE_DIR}/tests/checker.sh"
218 + tests_transformations_working
219 + tests/transformations/working/*.c
222 + foreach(test ${tests_transformations_working})
223 + message(STATUS "Add Transformation working test ${test}")
225 + "tests_transformations_working_${test}"
227 + "${CMAKE_CURRENT_SOURCE_DIR}/tests/checker.sh"
239 + install(TARGETS candl LIBRARY DESTINATION lib)
240 + install(TARGETS candl_static ARCHIVE DESTINATION lib)
241 + install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN "*.h")
242 + install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN "*.hpp")
243 + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/" DESTINATION include FILES_MATCHING PATTERN "*.h")
244 + install(FILES candl-config.cmake DESTINATION lib/candl)
245 + install(TARGETS candl_exe RUNTIME DESTINATION bin)
250 + message(STATUS "You can execute:")
251 + message(STATUS " make # To compile candl library & candl")
253 + message(STATUS " make test # To execute tests")
254 + message(STATUS " (with the first candl in the $PATH (?))")
256 + message(STATUS " make install # To install library, include and CMake module")
257 + message(STATUS " # If you need root access:")
258 + message(STATUS " # sudo make install")
259 + message(STATUS " # su -c \"make install\"")
261 + message(STATUS " make doxygen # To generate the Doxygen")
264 + message(STATUS " make doc # To generate the documentation")
267 + message(STATUS "---")
268 diff --git a/Makefile.am b/Makefile.am
269 index fefbf45..6839b4b 100644
274 # *****************************************************************************/
276 +#############################################################################
280 + OSL_LA = $(top_builddir)/osl/libosl.la
283 + MAYBE_PIPLIB = piplib
284 + PIPLIB_LA = $(top_builddir)/piplib/libpiplib$(BITS).la
287 +SUBDIRS = $(MAYBE_OSL) $(MAYBE_PIPLIB) doc tests
288 +DIST_SUBDIRS = $(MAYBE_OSL) $(MAYBE_PIPLIB) doc tests
289 +ACLOCAL_AMFLAGS = -I m4
291 +#############################################################################
293 +bin_PROGRAMS = candl
294 +lib_LTLIBRARIES = libcandl.la
296 #############################################################################
297 -SUBDIRS = doc source include tests
299 +pkginclude_HEADERS = \
300 + include/candl/candl.h \
301 + include/candl/dependence.h \
302 + include/candl/scop.h \
303 + include/candl/statement.h \
304 + include/candl/macros.h \
305 + include/candl/util.h \
306 + include/candl/ddv.h \
307 + include/candl/matrix.h \
308 + include/candl/options.h \
309 + include/candl/piplib.h \
310 + include/candl/piplib-wrapper.h \
311 + include/candl/violation.h
313 +DEFAULT_INCLUDES = -I.
314 +INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
315 +AM_CFLAGS = $(CFLAGS_WARN)
317 #############################################################################
318 -ACLOCAL_AMFLAGS = -I autoconf
320 -m4datadir = $(datadir)/aclocal
321 +EXTRA_DIST = COPYING.LESSER AUTHORS
323 +libcandl_la_LIBADD = @OSL_LIBS@ @PIPLIB_LIBS@ $(OSL_LA) $(PIPLIB_LA)
324 +libcandl_la_CPPFLAGS = @OSL_CPPFLAGS@ @PIPLIB_CPPFLAGS@ -g
325 +libcandl_la_LDFLAGS = @OSL_LDFLAGS@ @PIPLIB_LDFLAGS@
326 +libcandl_la_SOURCES = \
327 + source/dependence.c \
330 + source/statement.c \
332 + source/isl-wrapper.c \
335 + source/piplib-wrapper.c \
339 -EXTRA_DIST = COPYING.LESSER AUTHORS
340 +#############################################################################
343 - $(ac_aux_dir)/config.guess \
344 - $(ac_aux_dir)/config.sub \
345 - $(ac_aux_dir)/install-sh \
346 - $(ac_aux_dir)/ltmain.sh \
347 - $(ac_aux_dir)/missing \
348 - $(ac_aux_dir)/depcomp \
349 - $(ac_aux_dir)/texinfo.tex
350 +LDADD = @CANDL_LIBS@ @OSL_LIBS@ @PIPLIB_LIBS@
351 +candl_CPPFLAGS = @OSL_CPPFLAGS@ @PIPLIB_CPPFLAGS@ -g -Wall
352 +candl_LDFLAGS = #@OSL_LDFLAGS@ @PIPLIB_LDFLAGS@ # TO BE REMOVED
353 +candl_DEPENDENCIES = libcandl.la
354 +candl_SOURCES = source/candl.c
356 +#############################################################################
358 -MAINTAINERCLEANFILES = \
362 - source/stamp-h.in \
363 +MAINTAINERCLEANFILES = \
369 #############################################################################
372 (cd $(distdir) && mkdir -p $(ac_aux_dir))
373 for file in $(AUX_DIST); do \
374 cp $$file $(distdir)/$$file; \
376 #############################################################################
379 + $(MAKE) valcheck -C tests
380 diff --git a/README b/README
381 index 1b20de6..864d102 100644
388 -To install candl, PIPLib must be installed. Optionally, scoplib must
389 +To install candl, PIPLib must be installed. Optionally, OpenScop library must
390 be installed to enable SCoP support.
392 $> ./configure --with-piplib=/path/to/piplib/install --with-scoplib=/path/to/scoplib/install
393 @@ -15,6 +15,32 @@ $> make
397 +Alternatively, to use bunled PIPLib and OpenScop library, follow following command
400 +$> ./get_submodules.sh
404 +$> ./configure --with-piplib=bundled --with-scoplib=bundled
410 +Alternative: Install with CMake
411 +-------------------------------
415 +$> cmake .. # -DCMAKE_INSTALL_PREFIX="/your/install/directory"
418 +$> # make install # sudo make install # su -c "make install"
426 diff --git a/TODO b/TODO
428 index 0000000..74b6087
433 +- unchecked -commute
435 +- lastwriter not finished
436 + see the FIXME in the function candl_dep_compute_lastwriter
438 +- compilation error with ISL :
439 + To test it, in isl-wrapper change #ifdef CANDL_SUPPORTS_ISL to
440 + #ifndef CANDL_SUPPORTS_ISL
443 + source/isl-wrapper.c: In function ‘isl_constraint_read_from_matrix’:
444 + source/isl-wrapper.c:79: warning: passing argument 1 of ‘isl_equality_alloc’ from incompatible pointer type
445 + /home/jpoudroux/usr/include/isl/constraint.h:28: note: expected ‘struct isl_local_space *’ but argument is of type ‘struct isl_space *’
446 + source/isl-wrapper.c:81: warning: passing argument 1 of ‘isl_inequality_alloc’ from incompatible pointer type
447 + /home/jpoudroux/usr/include/isl/constraint.h:29: note: expected ‘struct isl_local_space *’ but argument is of type ‘struct isl_space *’
449 +- prunnning not finish (prunning.c: line 258 to 328)
450 + Uncomment the CANDL_COMPILE_PRUNNING in candl.h, or remove the ifdef in
453 +- change the type of the dependence/violation domain
454 + (at the end of candl_dependence_build_system and candl_matrix_violation)
455 + today it's : OSL_UNDEFINED
458 + the statements must be sorted to compute the statement label
459 + the problem is if the scop is reordered, the second transformed scop
460 + must be "aligned" with it (the first statement need to corresponds to the first
461 + statement of the second scop, but the scattering could be different)
463 + Functions of clay, which could return a non ordered scop :
464 + (they create new statements)
467 +- in pip_has_rational_point:
468 + -> FIXME (dependence.c:2243)
470 +- autocorrect not implemented yet
472 +- compilation warning with gmp :
473 + /usr/bin/ld: warning: libgmp.so.3, needed by /home/jpoudroux/usr/lib/libosl.so, may conflict with libgmp.so.10
475 +- autoreconf error in the piplib module
476 + -> piplib must be installed in /
478 + or execute these commands :
480 + $ echo "AM_PROG_CC_C_O" >>configure.in
481 + $ touch NEWS AUTHORS ChangeLog
485 + If you want to set piplib as "bundled", uncomment these lines in the
487 + 295: if test $with_piplib = bundled; then
488 + 296: AC_CONFIG_SUBDIRS(piplib)
491 diff --git a/autoconf/.gitignore b/autoconf/.gitignore
493 index 0000000..e69de29
494 diff --git a/autoconf/candl.m4 b/autoconf/candl.m4
495 deleted file mode 100644
496 index 2d1347e..0000000
497 --- a/autoconf/candl.m4
500 -AC_DEFUN([CANDL_ARG_LIBS_DEPENDENCIES],
502 -dnl Add $prefix to the library path (convenience).
503 - if test -e ${prefix}/include; then
504 - CPPFLAGS="${CPPFLAGS} -I${prefix}/include"
506 - if test -e ${prefix}/lib; then
507 - LDFLAGS="${LDFLAGS} -L${prefix}/lib"
509 -dnl Offer --with-piplib.
510 - AC_ARG_WITH(piplib,
511 - AC_HELP_STRING([--with-piplib=DIR],
512 - [DIR Location of PIPLib package]),
513 - [with_piplib=$withval;
514 - CPPFLAGS="${CPPFLAGS} -I$withval/include";
515 - LDFLAGS="${LDFLAGS} -L$withval/lib"
518 -dnl Check for piplib existence.
519 - AS_IF([test "x$with_piplib" != xno],
520 - [AC_SEARCH_LIBS([pip_solve], [piplib$BITS],
521 - [LIBS="-lpiplib$BITS $LIBS";
522 - AC_DEFINE([HAVE_LIBPIPLIB], [1], [Define if you have libpiplib$BITS])
524 - [if test "x$with_piplib" != xcheck; then
525 - AC_MSG_FAILURE([--with-piplib was given, but test for piplib failed])
529 -dnl Offer --with-scoplib.
530 - AC_ARG_WITH(scoplib,
531 - AC_HELP_STRING([--with-scoplib=DIR],
532 - [DIR Location of ScopLib package]),
533 - [with_scoplib=$withval;
534 - CPPFLAGS="${CPPFLAGS} -I$withval/include";
535 - LDFLAGS="${LDFLAGS} -L$withval/lib"
537 - [with_scoplib=check])
538 -dnl Check for scoplib existence.
539 - AS_IF([test "x$with_scoplib" != xno],
540 - [AC_SEARCH_LIBS([scoplib_scop_read], [scoplib],
541 - [LIBS="-lscoplib $LIBS";
542 - DEFINE_HAS_SCOPLIB_LIB="# define CANDL_SUPPORTS_SCOPLIB"
544 - [DEFINE_HAS_SCOPLIB_LIB=""
545 - if test "x$with_scoplib" != xcheck; then
546 - AC_MSG_FAILURE([Test for ScopLib failed. Use --with-scoplib to specify libscoplib path.])
550 -dnl Offer --with-gmp-prefix.
551 - AC_ARG_WITH(gmp-prefix,
552 - AC_HELP_STRING([--with-gmp-prefix=DIR],
553 - [DIR Location of GMP package (only headers are needed)]),
554 - [CPPFLAGS="${CPPFLAGS} -I$withval/include";
555 - LDFLAGS="${LDFLAGS} -L$withval/lib";
557 -dnl Offer --with-isl.
559 - AC_HELP_STRING([--with-isl=DIR],
560 - [DIR Location of Isl package]),
561 - [with_isl=$withval;
562 - CPPFLAGS="${CPPFLAGS} -I$withval/include";
563 - LDFLAGS="${LDFLAGS} -L$withval/lib"
566 -dnl Check for isl existence.
567 - AS_IF([test "x$with_isl" != xno],
568 - [AC_SEARCH_LIBS([isl_version], [isl],
569 - [LIBS="-lisl $LIBS";
570 - DEFINE_HAS_ISL_LIB="# define CANDL_SUPPORTS_ISL"
572 - [DEFINE_HAS_ISL_LIB=""
573 - if test "x$with_isl" != xcheck; then
574 - AC_MSG_FAILURE([Test for Isl failed. Use --with-isl to specify libisl path.])
581 #diff --git a/autogen.sh b/autogen.sh
582 #index b67de1f..c27fa40 100755
588 #-aclocal -I autoconf
589 #-libtoolize --force --copy
593 #+if test -f osl/autogen.sh; then
594 #+ (cd osl; ./autogen.sh)
596 #+if test -f piplib/autogen.sh; then
597 #+ (cd piplib; ./autogen.sh)
599 diff --git a/candl-config.cmake b/candl-config.cmake
601 index 0000000..c1047d0
603 +++ b/candl-config.cmake
605 +# Try to find the candl library
607 +# CANDL_FOUND - System has candl lib
608 +# CANDL_INCLUDE_DIR - The candl include directory
609 +# CANDL_LIBRARY - Library needed to use candl
612 +if (CANDL_INCLUDE_DIR AND CANDL_LIBRARY)
613 + # Already in cache, be silent
614 + set(CANDL_FIND_QUIETLY TRUE)
617 +find_path(CANDL_INCLUDE_DIR NAMES candl/candl.h)
618 +find_library(CANDL_LIBRARY NAMES candl)
620 +if (CANDL_LIBRARY AND CANDL_INCLUDE_DIR)
621 + message(STATUS "Library candl found =) ${CANDL_LIBRARY}")
623 + message(STATUS "Library candl not found =(")
626 +include(FindPackageHandleStandardArgs)
627 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(CANDL DEFAULT_MSG CANDL_INCLUDE_DIR CANDL_LIBRARY)
629 +mark_as_advanced(CANDL_INCLUDE_DIR CANDL_LIBRARY)
630 diff --git a/configure.ac b/configure.ac
632 index 0000000..03c9ce4
636 +dnl /**-------------------------------------------------------------------**
638 +dnl **-------------------------------------------------------------------**
639 +dnl ** configure.in **
640 +dnl **-------------------------------------------------------------------**
641 +dnl ** First version: september 8th 2003 **
642 +dnl **-------------------------------------------------------------------**/
644 +dnl /**************************************************************************
645 +dnl * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
646 +dnl ***************************************************************************
648 +dnl * Copyright (C) 2003-2008 Cedric Bastoul *
650 +dnl * This is free software; you can redistribute it and/or modify it under *
651 +dnl * the terms of the GNU General Public License as published by the Free *
652 +dnl * Software Foundation; either version 2 of the License, or (at your *
653 +dnl * option) any later version. *
655 +dnl * This software is distributed in the hope that it will be useful, but *
656 +dnl * WITHOUT ANY WARRANTY; without even the implied warranty of *
657 +dnl * MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
658 +dnl * General Public License for more details. *
660 +dnl * You should have received a copy of the GNU General Public License along *
661 +dnl * with software; if not, write to the Free Software Foundation, Inc., *
662 +dnl * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
664 +dnl * CAnDL, the Chunky Dependence Analyser *
665 +dnl * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
667 +dnl ***************************************************************************/
669 +m4_define([version_major], [0])
670 +m4_define([version_minor], [0])
671 +m4_define([version_revision], [1])
675 +dnl Fill here the @bug email adress.
676 +AC_INIT([candl], [0.6.2], [cedric.bastoul@inria.fr,pouchet@cse.ohio-state.edu])
678 +AC_CONFIG_SRCDIR([include/candl/candl.h])
680 +dnl Put as most as possible configuration files to an auxialiry
682 +AC_CONFIG_AUX_DIR(autoconf)
683 +AC_CONFIG_MACRO_DIR([m4])
685 +dnl Initialize automake. Here, a special tar version that enables
686 +dnl (very) long filenames.
687 +#AM_INIT_AUTOMAKE([1.9 tar-ustar no-define foreign dist-bzip2])
688 +AM_INIT_AUTOMAKE([foreign])
689 +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
693 +CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP
696 +dnl /**************************************************************************
698 +dnl **************************************************************************/
701 +dnl Checks for programs.
705 +AC_CHECK_PROG(CD, cd)
708 +AC_CHECK_PROGS(DOXYGEN,doxygen,doxygen)
711 +AC_SUBST(CFLAGS_WARN)
712 +AX_CFLAGS_WARN_ALL(CFLAGS_WARN)
714 +dnl Checks for typedefs, structures, and compiler characteristics.
718 +dnl Checks for header files.
720 +AC_CHECK_HEADERS([errno.h stddef.h stdlib.h string.h strings.h unistd.h])
722 +dnl Checks for library functions.
723 +AC_CHECK_FUNCS(strtol)
726 +dnl /**************************************************************************
727 +dnl * Option setting *
728 +dnl **************************************************************************/
730 +dnl /**************************************************************************
731 +dnl * Where is the OpenScop Library? *
732 +dnl **************************************************************************/
734 +AX_SUBMODULE(osl,system|build|bundled,system)
736 +AC_SUBST(OSL_CPPFLAGS)
737 +AC_SUBST(OSL_LDFLAGS)
741 + OSL_CPPFLAGS="-I$srcdir/osl/include -Iosl/include"
742 + OSL_LIBS="$srcdir/osl/libosl.la"
745 + OSL_CPPFLAGS="-I$osl_srcdir/include -I$with_osl_builddir/include"
746 + OSL_LIBS="$with_osl_builddir/libosl.la"
749 + if test "x$with_osl_prefix" != "x"; then
750 + OSL_CPPFLAGS="-I$with_osl_prefix/include"
752 + if test "x$with_osl_exec_prefix" != "x"; then
753 + OSL_LDFLAGS="-L$with_osl_exec_prefix/lib"
755 + OSL_LIBS="$with_osl_prefix/lib/libosl.la -losl"
757 +AM_CONDITIONAL(BUNDLED_OSL, test $with_osl = bundled)
763 +dnl Some default values cause I'm not sure whether autoconf set them, while
764 +dnl documentation says it does...
766 +gmp_include_package="yes"
767 +gmp_library_package="yes"
771 +dnl --with-gmp=gmp-path
773 + [ --with-gmp=DIR DIR where the gmp package is installed],
774 + [ echo "Package gmp : $withval" &&
775 + gmp_package=$withval &&
776 + GMP_INC=$gmp_package/include &&
777 + GMP_LIB=$gmp_package/lib &&
778 + CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
781 +AC_ARG_WITH(gmp-include,
782 + [ --with-gmp-include=DIR DIR where gmp.h is installed],
783 + [ echo "Package gmp-include : $withval" &&
784 + gmp_include_package=$withval &&
785 + GMP_INC=$gmp_include_package &&
786 + CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
789 +AC_ARG_WITH(gmp-library,
790 + [ --with-gmp-library=DIR DIR where the gmp library is installed],
791 + [ echo "Package gmp-library : $withval" &&
792 + gmp_library_package=$withval &&
793 + GMP_LIB=$gmp_library_package &&
794 + CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
797 +AC_ARG_ENABLE(int-version,
798 + [ --enable-int-version 'int' (32 bits) version is built],
799 + [ echo "Package int : $enableval" &&
801 + CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_LONG])
803 +AC_ARG_ENABLE(llint-version,
804 + [ --enable-llint-version 'long long int' (64 bits) version is built],
805 + [ echo "Package long long int : $enableval" &&
807 + CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_LONGLONG])
809 +AC_ARG_ENABLE(mp-version,
810 + [ --enable-mp-version 'MP' (multiple precision) version is built],
811 + [ echo "Package mp : $enableval" &&
813 + CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
816 +AC_ARG_ENABLE(piplib-hybrid,
817 + [ --enable-piplib-hybrid Link with piplib-hybrid],
818 + [ echo "Piplib-hybrid support : $enableval" &&
819 + if test "x$enableval" = "xyes"; then
820 + CPPFLAGS=-DCANDL_HAS_PIPLIB_HYBRID
824 +dnl /**************************************************************************
825 +dnl * Where is the PipLib Library? *
826 +dnl **************************************************************************/
828 +AX_SUBMODULE(piplib,system|build|bundled,system)
830 +AC_SUBST(PIPLIB_CPPFLAGS)
831 +AC_SUBST(PIPLIB_LDFLAGS)
832 +AC_SUBST(PIPLIB_LIBS)
833 +case "$with_piplib" in
835 + PIPLIB_CPPFLAGS="-I$srcdir/piplib/include -Ipiplib/include"
836 + PIPLIB_LIBS="$srcdir/piplib/libpiplib$BITS.la"
839 + PIPLIB_CPPFLAGS="-I$piplib_srcdir/include -I$with_piplib_builddir/include"
840 + PIPLIB_LIBS="$with_piplib_builddir/libpiplib$BITS.la"
843 + if test "x$with_piplib_prefix" != "x"; then
844 + PIPLIB_CPPFLAGS="-I$with_piplib_prefix/include"
846 + if test "x$with_piplib_exec_prefix" != "x"; then
847 + PIPLIB_LDFLAGS="-L$with_piplib_exec_prefix/lib"
849 + PIPLIB_LIBS="$with_piplib_prefix/lib/libpiplib$BITS.la -lpiplib$BITS"
851 +AM_CONDITIONAL(BUNDLED_PIPLIB, test $with_piplib = bundled)
855 +dnl /**************************************************************************
856 +dnl * Where is GMP? *
857 +dnl **************************************************************************/
860 +dnl Checking for gmp
861 +AC_MSG_CHECKING(whether gmp works)
862 +if test "$gmp_package" = "no"; then
863 + echo "GMP package not defined"
867 + if test "$NEED_MP" = "no"; then
868 + echo "Mode normal GMP"
869 + TO_BUILD="$TO_BUILD MP"
870 + AC_CHECK_HEADER(gmp.h,
871 + [AC_SEARCH_LIBS([__gmpz_init], [gmp],
872 + [LIBS="$LIBS -lgmp"],
873 + [echo "Can't find gmp library." &&
874 + echo "MP version will not be built." &&
876 + [echo "Can't find gmp headers." &&
877 + echo "MP version will not be built." &&
880 + dnl Default given by --with-X is "yes", --without-X is "no". We also
881 + dnl initialized manually all gmp_package* variables to "yes" (thus they are
882 + dnl supposed to be "yes" except if the user set them himself).
883 + if test "$gmp_package" != "yes" ; then
884 + echo "(GMP path has been set by user)"
885 + GMP_DIR=$gmp_package
886 + dnl Useful for AC_CHECK_X to find what we want.
887 + CPPFLAGS="-I$GMP_DIR/include $CPPFLAGS"
888 + LDFLAGS="-L$GMP_DIR/lib $LDFLAGS"
891 + if test "$gmp_include_package" != "yes" ; then
892 + CPPFLAGS="-I$GMP_INC $CPPFLAGS"
895 + if test "$gmp_library_package" != "yes" ; then
896 + LDFLAGS="-L$GMP_LIB $LDFLAGS"
899 + AC_CHECK_HEADER(gmp.h,
901 + [AC_MSG_ERROR(Can't find gmp headers.)])
902 + AC_SEARCH_LIBS([__gmpz_init], [gmp],
903 + [LIBS="$LIBS -lgmp"],
904 + [AC_MSG_ERROR(Can't find gmp library.)])
910 +dnl /**************************************************************************
911 +dnl * Substitutions *
912 +dnl **************************************************************************/
915 +dnl Substitutions to do.
917 +AC_SUBST(DEFINE_HAS_ISL_LIB)
918 +AC_SUBST(ac_aux_dir)
919 +AC_SUBST(abs_top_srcdir)
922 +dnl Configure Makefiles.
927 + include/candl/macros.h
928 + include/candl/piplib.h
931 + [test -z "$CONFIG_HEADERS" || echo timestamp > source/stamp-h.in])
933 +#if test $with_piplib = system; then
934 +# AC_CONFIG_SUBDIRS(piplib)
936 +if test $with_osl = bundled; then
937 + AC_CONFIG_SUBDIRS(osl)
940 +dnl forcing candl to use local libcandl.la
941 +dnl if --prefix is not specified
942 +CANDL_LIBS="$srcdir/libcandl.la -lcandl"
943 +AC_SUBST(CANDL_LIBS)
949 +echo " /*-----------------------------------------------*"
950 +echo " * Candl configuration is OK *"
951 +echo " *-----------------------------------------------*/"
952 +echo "It appears that your system is OK to start Candl compilation. You need"
953 +echo "now to type \"make\". Lastly type \"make install\" to install Candl on"
954 +echo "your system (log as root if necessary)."
956 diff --git a/configure.in b/configure.in
957 deleted file mode 100644
958 index f6cf7ad..0000000
962 -dnl /**-------------------------------------------------------------------**
964 -dnl **-------------------------------------------------------------------**
965 -dnl ** configure.in **
966 -dnl **-------------------------------------------------------------------**
967 -dnl ** First version: september 8th 2003 **
968 -dnl **-------------------------------------------------------------------**/
970 -dnl /**************************************************************************
971 -dnl * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
972 -dnl ***************************************************************************
974 -dnl * Copyright (C) 2003-2008 Cedric Bastoul *
976 -dnl * This is free software; you can redistribute it and/or modify it under *
977 -dnl * the terms of the GNU General Public License as published by the Free *
978 -dnl * Software Foundation; either version 2 of the License, or (at your *
979 -dnl * option) any later version. *
981 -dnl * This software is distributed in the hope that it will be useful, but *
982 -dnl * WITHOUT ANY WARRANTY; without even the implied warranty of *
983 -dnl * MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
984 -dnl * General Public License for more details. *
986 -dnl * You should have received a copy of the GNU General Public License along *
987 -dnl * with software; if not, write to the Free Software Foundation, Inc., *
988 -dnl * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
990 -dnl * CAnDL, the Chunky Dependence Analyser *
991 -dnl * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
993 -dnl ***************************************************************************/
997 -dnl Fill here the @bug email adress.
998 -AC_INIT([candl], [0.6.2], [cedric.bastoul@inria.fr,pouchet@cse.ohio-state.edu])
999 -dnl A common file, which serve as a test.
1000 -AC_CONFIG_SRCDIR([include/candl/program.h])
1001 -dnl Put as most as possible configuration files to an auxialiry
1003 -AC_CONFIG_AUX_DIR([autoconf])
1004 -dnl Initialize automake. Here, a special tar version that enables
1005 -dnl (very) long filenames.
1006 -AM_INIT_AUTOMAKE([1.9 tar-ustar no-define foreign dist-bzip2])
1009 -dnl default version
1011 -CPPFLAGS=-DLINEAR_VALUE_IS_LONGLONG
1014 -dnl /**************************************************************************
1016 -dnl **************************************************************************/
1019 -dnl Checks for programs.
1023 -AC_CHECK_PROG(CD, cd)
1025 -AC_CHECK_PROGS(DOXYGEN,doxygen,doxygen)
1027 -dnl Checks for typedefs, structures, and compiler characteristics.
1031 -dnl Checks for header files.
1033 -AC_CHECK_HEADERS([errno.h stddef.h stdlib.h string.h strings.h unistd.h])
1035 -dnl Checks for library functions.
1036 -AC_CHECK_FUNCS(strtol)
1039 -dnl /**************************************************************************
1040 -dnl * Option setting *
1041 -dnl **************************************************************************/
1043 -dnl Some default values cause I'm not sure whether autoconf set them, while
1044 -dnl documentation says it does...
1046 -gmp_include_package="yes"
1047 -gmp_library_package="yes"
1051 -dnl --with-gmp=gmp-path
1053 - [ --with-gmp=DIR DIR where the gmp package is installed],
1054 - [ echo "Package gmp : $withval" &&
1055 - gmp_package=$withval &&
1056 - GMP_INC=$gmp_package/include &&
1057 - GMP_LIB=$gmp_package/lib &&
1058 - CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
1061 -AC_ARG_WITH(gmp-include,
1062 - [ --with-gmp-include=DIR DIR where gmp.h is installed],
1063 - [ echo "Package gmp-include : $withval" &&
1064 - gmp_include_package=$withval &&
1065 - GMP_INC=$gmp_include_package &&
1066 - CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
1069 -AC_ARG_WITH(gmp-library,
1070 - [ --with-gmp-library=DIR DIR where the gmp library is installed],
1071 - [ echo "Package gmp-library : $withval" &&
1072 - gmp_library_package=$withval &&
1073 - GMP_LIB=$gmp_library_package &&
1074 - CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
1077 -AC_ARG_ENABLE(int-version,
1078 - [ --enable-int-version 'int' (32 bits) version is built],
1079 - [ echo "Package int : $enableval" &&
1081 - CPPFLAGS=-DLINEAR_VALUE_IS_LONG])
1083 -AC_ARG_ENABLE(llint-version,
1084 - [ --enable-llint-version 'long long int' (64 bits) version is built],
1085 - [ echo "Package long long int : $enableval" &&
1087 - CPPFLAGS=-DLINEAR_VALUE_IS_LONGLONG])
1089 -AC_ARG_ENABLE(mp-version,
1090 - [ --enable-mp-version 'MP' (multiple precision) version is built],
1091 - [ echo "Package mp : $enableval" &&
1093 - CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
1096 -AC_ARG_ENABLE(piplib-hybrid,
1097 - [ --enable-piplib-hybrid Link with piplib-hybrid],
1098 - [ echo "Piplib-hybrid support : $enableval" &&
1099 - if test "x$enableval" = "xyes"; then
1100 - CPPFLAGS=-DCANDL_HAS_PIPLIB_HYBRID
1104 -dnl /**************************************************************************
1105 -dnl * Where is GMP? *
1106 -dnl **************************************************************************/
1109 -dnl Checking for gmp
1110 -AC_MSG_CHECKING(whether gmp works)
1111 -if test "$gmp_package" = "no"; then
1112 - echo "GMP package not defined"
1116 - if test "$NEED_MP" = "no"; then
1117 - echo "Mode normal GMP"
1118 - TO_BUILD="$TO_BUILD MP"
1119 - AC_CHECK_HEADER(gmp.h,
1120 - [AC_SEARCH_LIBS([__gmpz_init], [gmp],
1121 - [LIBS="$LIBS -lgmp"],
1122 - [echo "Can't find gmp library." &&
1123 - echo "MP version will not be built." &&
1124 - TO_BUILD_MP=""])],
1125 - [echo "Can't find gmp headers." &&
1126 - echo "MP version will not be built." &&
1129 - dnl Default given by --with-X is "yes", --without-X is "no". We also
1130 - dnl initialized manually all gmp_package* variables to "yes" (thus they are
1131 - dnl supposed to be "yes" except if the user set them himself).
1133 - if test "$gmp_package" != "yes" ; then
1134 - echo "(GMP path has been set by user)"
1135 - GMP_DIR=$gmp_package
1136 - dnl Useful for AC_CHECK_X to find what we want.
1137 - CPPFLAGS="-I$GMP_DIR/include $CPPFLAGS"
1138 - LDFLAGS="-L$GMP_DIR/lib $LDFLAGS"
1141 - if test "$gmp_include_package" != "yes" ; then
1142 - CPPFLAGS="-I$GMP_INC $CPPFLAGS"
1145 - if test "$gmp_library_package" != "yes" ; then
1146 - LDFLAGS="-L$GMP_LIB $LDFLAGS"
1149 - AC_CHECK_HEADER(gmp.h,
1151 - [AC_MSG_ERROR(Can't find gmp headers.)])
1152 - AC_SEARCH_LIBS([__gmpz_init], [gmp],
1153 - [LIBS="$LIBS -lgmp"],
1154 - [AC_MSG_ERROR(Can't find gmp library.)])
1156 - AC_MSG_RESULT(yes)
1160 -CANDL_ARG_LIBS_DEPENDENCIES
1164 -dnl /**************************************************************************
1165 -dnl * Substitutions *
1166 -dnl **************************************************************************/
1169 -dnl Substitutions to do.
1171 -AC_SUBST(DEFINE_HAS_SCOPLIB_LIB)
1172 -AC_SUBST(DEFINE_HAS_ISL_LIB)
1173 -AC_SUBST(ac_aux_dir)
1175 -dnl Configure Makefiles.
1181 - include/candl/candl.h
1185 - [test -z "$CONFIG_HEADERS" || echo timestamp > source/stamp-h.in])
1189 -echo " /*-----------------------------------------------*"
1190 -echo " * Candl configuration is OK *"
1191 -echo " *-----------------------------------------------*/"
1192 -echo "It appears that your system is OK to start Candl compilation. You need"
1193 -echo "now to type \"make\". Lastly type \"make install\" to install Candl on"
1194 -echo "your system (log as root if necessary)."
1195 diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
1196 index e172bda..510d8f1 100644
1197 --- a/doc/Doxyfile.in
1198 +++ b/doc/Doxyfile.in
1199 @@ -478,7 +478,8 @@ WARN_LOGFILE =
1202 INPUT = @top_srcdir@/source \
1203 - @top_srcdir@/include/candl
1204 + @top_srcdir@/include/candl \
1205 + include/candl/macros.h
1207 # This tag can be used to specify the character encoding of the source files that
1208 # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
1209 diff --git a/get_submodules.sh b/get_submodules.sh
1210 new file mode 100755
1211 index 0000000..94842b6
1213 +++ b/get_submodules.sh
1217 +git submodule update
1218 +if test -f osl/autogen.sh; then
1219 + (cd osl; ./autogen.sh && ./configure)
1221 +if test -f piplib/autogen.sh; then
1222 + (cd piplib; ./autogen.sh && ./configure)
1224 diff --git a/include/Makefile.am b/include/Makefile.am
1225 deleted file mode 100644
1226 index ed48dcd..0000000
1227 --- a/include/Makefile.am
1231 -# /**-------------------------------------------------------------------**
1233 -# **-------------------------------------------------------------------**
1234 -# ** Makefile.am **
1235 -# **-------------------------------------------------------------------**
1236 -# ** First version: september 8th 2003 **
1237 -# **-------------------------------------------------------------------**/
1239 -#/*****************************************************************************
1240 -# * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
1241 -# *****************************************************************************
1243 -# * Copyright (C) 2003-2008 Cedric Bastoul *
1245 -# * This is free software; you can redistribute it and/or modify it under the *
1246 -# * terms of the GNU General Public License as published by the Free Software *
1247 -# * Foundation; either version 2 of the License, or (at your option) any *
1248 -# * later version. *
1250 -# * This software is distributed in the hope that it will be useful, but *
1251 -# * WITHOUT ANY WARRANTY; without even the implied warranty of *
1252 -# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
1253 -# * Public License for more details. *
1255 -# * You should have received a copy of the GNU General Public License along *
1256 -# * with software; if not, write to the Free Software Foundation, Inc., *
1257 -# * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
1259 -# * CAnDL, the Chunky Dependence Analyser *
1260 -# * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
1262 -# *****************************************************************************/
1265 -#############################################################################
1268 -#############################################################################
1269 -MAINTAINERCLEANFILES = Makefile.in
1271 -#############################################################################
1273 -pkginclude_HEADERS = \
1275 - candl/dependence.h \
1279 - candl/piplib-wrapper.h \
1282 - candl/statement.h \
1284 diff --git a/include/candl/candl.h b/include/candl/candl.h
1285 new file mode 100644
1286 index 0000000..926511f
1288 +++ b/include/candl/candl.h
1291 + /**------ ( ----------------------------------------------------------**
1293 + **----- / ) --------------------------------------------------------**
1294 + ** ( * ( candl.h **
1295 + **---- \#/ --------------------------------------------------------**
1296 + ** .-"#'-. First version: september 8th 2003 **
1297 + **--- |"-.-"| -------------------------------------------------------**
1300 + ******** | | *************************************************************
1301 + * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
1302 + ******************************************************************************
1304 + * Copyright (C) 2003-2008 Cedric Bastoul *
1306 + * This is free software; you can redistribute it and/or modify it under the *
1307 + * terms of the GNU Lesser General Public License as published by the Free *
1308 + * Software Foundation; either version 3 of the License, or (at your option) *
1309 + * any later version. *
1311 + * This software is distributed in the hope that it will be useful, but *
1312 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
1313 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
1314 + * for more details. *
1316 + * You should have received a copy of the GNU Lesser General Public License *
1317 + * along with software; if not, write to the Free Software Foundation, Inc., *
1318 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
1320 + * CAnDL, the Chunky Dependence Analyser *
1321 + * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
1323 + ******************************************************************************/
1328 +# include <candl/ddv.h>
1329 +# include <candl/dependence.h>
1330 +# include <candl/macros.h>
1331 +# include <candl/matrix.h>
1332 +# include <candl/options.h>
1333 +# include <candl/piplib-wrapper.h>
1334 +# include <candl/scop.h>
1335 +# include <candl/statement.h>
1336 +# include <candl/util.h>
1337 +# include <candl/violation.h>
1340 diff --git a/include/candl/candl.h.in b/include/candl/candl.h.in
1341 deleted file mode 100644
1342 index 187981e..0000000
1343 --- a/include/candl/candl.h.in
1347 - /**------ ( ----------------------------------------------------------**
1349 - **----- / ) --------------------------------------------------------**
1350 - ** ( * ( candl.h **
1351 - **---- \#/ --------------------------------------------------------**
1352 - ** .-"#'-. First version: september 8th 2003 **
1353 - **--- |"-.-"| -------------------------------------------------------**
1356 - ******** | | *************************************************************
1357 - * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
1358 - ******************************************************************************
1360 - * Copyright (C) 2003-2008 Cedric Bastoul *
1362 - * This is free software; you can redistribute it and/or modify it under the *
1363 - * terms of the GNU Lesser General Public License as published by the Free *
1364 - * Software Foundation; either version 3 of the License, or (at your option) *
1365 - * any later version. *
1367 - * This software is distributed in the hope that it will be useful, but *
1368 - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
1369 - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
1370 - * for more details. *
1372 - * You should have received a copy of the GNU Lesser General Public License *
1373 - * along with software; if not, write to the Free Software Foundation, Inc., *
1374 - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
1376 - * CAnDL, the Chunky Dependence Analyser *
1377 - * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
1379 - ******************************************************************************/
1382 -/******************************************************************************
1383 - * THIS FILE HAS BEEN AUTOMATICALLY GENERATED FROM candl.h.in BY configure *
1384 - ******************************************************************************/
1390 -# define CANDL_RELEASE "@PACKAGE_VERSION@"
1391 -# define CANDL_VERSION "@BITS@"
1392 -@DEFINE_HAS_SCOPLIB_LIB@
1393 -@DEFINE_HAS_ISL_LIB@
1396 -# include <piplib/piplib@BITS@.h>
1397 -# include <candl/options.h>
1398 -# include <candl/matrix.h>
1399 -# include <candl/statement.h>
1400 -# include <candl/program.h>
1401 -# include <candl/dependence.h>
1402 -# include <candl/ddv.h>
1403 -# include <candl/violation.h>
1404 -# include <candl/pruning.h>
1406 -# define CANDL_UNSET -1 /* Must be negative (we do use that property).
1407 - * All other constants have to be different.
1410 -# define CANDL_RAW 1
1411 -# define CANDL_WAR 2
1412 -# define CANDL_WAW 3
1413 -# define CANDL_RAR 4
1414 -# define CANDL_RAW_SCALPRIV 5
1416 -# define CANDL_ASSIGNMENT 1
1417 -# define CANDL_P_REDUCTION 2
1418 -# define CANDL_M_REDUCTION 3
1419 -# define CANDL_T_REDUCTION 4
1421 -# define CANDL_EQUAL 1
1422 -# define CANDL_POSIT 2
1423 -# define CANDL_LATER 3
1424 -# define CANDL_NEVER 4
1426 -# define CANDL_NB_INFOS 3
1428 -# define CANDL_MAX_STRING 2048
1429 -# define CANDL_TEMP_OUTPUT "candl.temp"
1431 -/* Useful macros. */
1432 -# define CANDL_max(x,y) ((x) > (y)? (x) : (y))
1433 -# define CANDL_min(x,y) ((x) < (y)? (x) : (y))
1435 -# define CANDL_FAIL(msg) { fprintf(stderr, "[Candl] " msg "\n"); exit(1); }
1437 -/******************************************************************************
1439 - ******************************************************************************/
1440 -#if defined(LINEAR_VALUE_IS_LONGLONG)
1441 -#define CANDL_FMT "%4lld "
1442 -#elif defined(LINEAR_VALUE_IS_LONG)
1443 -#define CANDL_FMT "%4ld "
1445 -#define CANDL_FMT "%4s"
1448 -/******************************************************************************
1449 - * CANDL GMP MACROS *
1450 - ******************************************************************************/
1451 -#ifdef LINEAR_VALUE_IS_MP
1453 -#define CANDL_init(val) (mpz_init((val)))
1454 -#define CANDL_assign(v1,v2) (mpz_set((v1),(v2)))
1455 -#define CANDL_set_si(val,i) (mpz_set_si((val),(i)))
1456 -#define CANDL_get_si(val) (mpz_get_si((val)))
1457 -#define CANDL_clear(val) (mpz_clear((val)))
1458 -#define CANDL_print(Dst,fmt,val) { char *str; \
1459 - str = mpz_get_str(0,10,(val)); \
1460 - fprintf((Dst),(fmt),str); free(str); \
1463 -/* Boolean operators on 'Value' or 'Entier' */
1464 -#define CANDL_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
1465 -#define CANDL_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
1467 -/* Binary operators on 'Value' or 'Entier' */
1468 -#define CANDL_increment(ref,val) (mpz_add_ui((ref),(val),1))
1469 -#define CANDL_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
1470 -#define CANDL_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
1471 -#define CANDL_oppose(ref,val) (mpz_neg((ref),(val)))
1473 -/* Conditional operations on 'Value' or 'Entier' */
1474 -#define CANDL_zero_p(val) (mpz_sgn(val) == 0)
1475 -#define CANDL_notzero_p(val) (mpz_sgn(val) != 0)
1477 -/******************************************************************************
1478 - * CANDL BASIC TYPES MACROS *
1479 - ******************************************************************************/
1482 -#define CANDL_init(val) ((val) = 0)
1483 -#define CANDL_assign(v1,v2) ((v1) = (v2))
1484 -#define CANDL_set_si(val,i) ((val) = (Entier)(i))
1485 -#define CANDL_get_si(val) ((val))
1486 -#define CANDL_clear(val) ((val) = 0)
1487 -#define CANDL_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
1489 -/* Boolean operators on 'Value' or 'Entier' */
1490 -#define CANDL_eq(v1,v2) ((v1)==(v2))
1491 -#define CANDL_ne(v1,v2) ((v1)!=(v2))
1493 -/* Binary operators on 'Value' or 'Entier' */
1494 -#define CANDL_increment(ref,val) ((ref) = (val)+(Entier)(1))
1495 -#define CANDL_decrement(ref,val) ((ref) = (val)-(Entier)(1))
1496 -#define CANDL_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
1497 -#define CANDL_oppose(ref,val) ((ref) = (-(val)))
1499 -/* Conditional operations on 'Value' or 'Entier' */
1500 -#define CANDL_zero_p(val) CANDL_eq(val,0)
1501 -#define CANDL_notzero_p(val) CANDL_ne(val,0)
1506 diff --git a/include/candl/ddv.h b/include/candl/ddv.h
1507 index bbc97db..8ae9a61 100644
1508 --- a/include/candl/ddv.h
1509 +++ b/include/candl/ddv.h
1511 * \author Louis-Noel Pouchet
1516 # define CANDL_DDV_H
1520 -# include <candl/statement.h>
1521 -# include <candl/matrix.h>
1522 -# include <candl/program.h>
1523 -# include <candl/options.h>
1524 -# include <candl/dependence.h>
1528 # if defined(__cplusplus)
1535 +struct osl_dependence;
1537 /******************************************************************************
1538 * Dependence Distance structures *
1539 @@ -112,9 +104,6 @@ extern "C"
1541 typedef struct candl_ddv CandlDDV;
1546 /******************************************************************************
1547 * Memory deallocation function *
1548 ******************************************************************************/
1549 @@ -127,7 +116,6 @@ extern "C"
1555 * candl_ddv_alloc: Allocate a ddv for a loop of depth 'size'.
1557 @@ -136,7 +124,6 @@ candl_ddv_malloc();
1559 candl_ddv_alloc(int);
1563 * candl_ddv_free: Free a ddv.
1565 @@ -145,7 +132,6 @@ candl_ddv_alloc(int);
1567 candl_ddv_free(CandlDDV*);
1571 * candl_ddv_set_type_at: Set the type of a ddv component. Type is one of
1572 * '=', '>', '<', '*' or 'constant' as defined by the enum e_dv_type.
1573 @@ -173,12 +159,10 @@ candl_ddv_set_value_at(CandlDDV*, int, int);
1575 candl_ddv_set_deptype(CandlDDV*, int);
1578 /******************************************************************************
1579 * Structure display function *
1580 ******************************************************************************/
1584 * candl_ddv_print: print a ddv.
1586 @@ -186,7 +170,6 @@ candl_ddv_set_deptype(CandlDDV*, int);
1588 candl_ddv_print(FILE*, CandlDDV*);
1591 /******************************************************************************
1592 * Processing functions *
1593 ******************************************************************************/
1594 @@ -199,7 +182,7 @@ candl_ddv_print(FILE*, CandlDDV*);
1598 -candl_ddv_extract_in_loop(CandlProgram*, CandlDependence*, int);
1599 +candl_ddv_extract_in_loop(struct osl_scop*, struct osl_dependence*, int);
1602 * candl_loops_are_permutable: output 1 if the 2 loops are permutable.
1603 @@ -207,10 +190,7 @@ candl_ddv_extract_in_loop(CandlProgram*, CandlDependence*, int);
1607 -candl_loops_are_permutable(CandlProgram* program, CandlDependence* deps,
1608 - int loop_id1, int loop_id2);
1611 +candl_loops_are_permutable(struct osl_scop*, struct osl_dependence*, int, int);
1613 # if defined(__cplusplus)
1615 diff --git a/include/candl/dependence.h b/include/candl/dependence.h
1616 index 0f40e65..9205de4 100644
1617 --- a/include/candl/dependence.h
1618 +++ b/include/candl/dependence.h
1619 @@ -33,153 +33,99 @@
1621 ******************************************************************************/
1624 #ifndef CANDL_DEPENDENCE_H
1625 # define CANDL_DEPENDENCE_H
1629 -# include <candl/statement.h>
1630 -# include <candl/matrix.h>
1631 -# include <candl/program.h>
1632 # include <candl/options.h>
1636 -# define CANDL_ARRAY_BUFF_SIZE 2048
1637 -# define CANDL_VAR_UNDEF 1
1638 -# define CANDL_VAR_IS_DEF 2
1639 -# define CANDL_VAR_IS_USED 3
1640 -# define CANDL_VAR_IS_DEF_USED 4
1642 +# define CANDL_ARRAY_BUFF_SIZE 2048
1643 +# define CANDL_VAR_UNDEF 1
1644 +# define CANDL_VAR_IS_DEF 2
1645 +# define CANDL_VAR_IS_USED 3
1646 +# define CANDL_VAR_IS_DEF_USED 4
1648 # if defined(__cplusplus)
1655 - * CandlDependence structure:
1656 - * this structure contains all the informations about a data dependence, it is
1657 - * also a node of the linked list of all dependences of the dependence graph.
1659 -struct candldependence
1660 -{ CandlStatement * source; /**< Pointer to source statement. */
1661 - CandlStatement * target; /**< Pointer to target statement. */
1662 - int depth; /**< Dependence level. */
1663 - int type; /**< Dependence type: a dependence from source
1664 - * to target can be:
1665 - * - CANDL_UNSET if the dependence type is
1667 - * - CANDL_RAW if source writes M and
1668 - * target read M (flow-dependence),
1669 - * - CANDL_WAR if source reads M and
1670 - * target writes M (anti-dependence),
1671 - * - CANDL_WAW if source writes M and
1672 - * target writes M too (output-dependence)
1673 - * - CANDL_RAR if source reads M and
1674 - * target reads M too (input-dependence).
1676 - int ref_source; /**< Position of source reference. */
1677 - int ref_target; /**< Position of target reference. */
1678 - CandlMatrix * domain; /**< Dependence polyhedron. */
1680 - void* usr; /**< User field, for library users
1682 - struct candldependence * next; /**< Pointer to next dependence */
1684 -typedef struct candldependence CandlDependence;
1685 -typedef struct candldependence candl_dependence_t;
1686 -typedef struct candldependence * candl_dependence_p;
1689 -/******************************************************************************
1690 - * Structure display function *
1691 - ******************************************************************************/
1692 -void candl_dependence_print_structure(FILE *, candl_dependence_p, int);
1693 -void candl_dependence_print(FILE *, candl_dependence_p);
1694 -void candl_dependence_pprint(FILE *, candl_dependence_p);
1695 -void candl_dependence_view(candl_dependence_p);
1696 -# ifdef CANDL_SUPPORTS_SCOPLIB
1697 -CandlDependence* candl_dependence_read_from_scop(scoplib_scop_p, CandlProgram*);
1698 -void candl_dependence_update_scop_with_deps(scoplib_scop_p, CandlDependence*);
1699 -void candl_dependence_print_scop(FILE*, FILE*, CandlDependence*);
1701 +struct osl_relation;
1702 +struct osl_statement;
1704 +struct osl_dependence;
1706 #ifdef CANDL_SUPPORTS_ISL
1707 -CandlDependence* candl_dependence_isl_simplify(CandlDependence*, CandlProgram*);
1708 +struct osl_dependence* candl_dependence_isl_simplify(struct osl_dependence*,
1709 + struct osl_scop*);
1713 -/******************************************************************************
1714 - * Memory alloc/dealloc function *
1715 - ******************************************************************************/
1716 -candl_dependence_p candl_dependence_malloc();
1717 -void candl_dependence_free(candl_dependence_p);
1719 +/*+***************************************************************************
1720 + * Structure display function *
1721 + *****************************************************************************/
1722 +void candl_dependence_pprint(FILE*, struct osl_dependence*);
1723 +void candl_dependence_view(struct osl_dependence*);
1725 /******************************************************************************
1726 * Processing functions *
1727 ******************************************************************************/
1728 -int candl_dependence_gcd_test(CandlStatement*,
1730 - CandlMatrix*, int);
1731 -int candl_dependence_check(CandlProgram *,
1732 - candl_dependence_p,
1734 -candl_dependence_p candl_dependence(CandlProgram *, CandlOptions *);
1736 +int candl_dependence_gcd_test(struct osl_statement*,
1737 + struct osl_statement*,
1738 + struct osl_relation*, int);
1739 +int candl_dependence_check(struct osl_scop*,
1740 + struct osl_dependence*,
1742 +struct osl_dependence* candl_dependence(struct osl_scop*, candl_options_p);
1743 +void candl_dependence_add_extension(struct osl_scop*,
1746 +/*+***************************************************************************
1747 + * Memory allocation/deallocation function *
1748 + *****************************************************************************/
1749 +void candl_dependence_init_fields(struct osl_scop*,
1750 + struct osl_dependence*);
1752 /******************************************************************************
1753 * Scalar analysis functions *
1754 ******************************************************************************/
1756 -candl_dependence_var_is_scalar (candl_program_p, int);
1759 -candl_dependence_refvar_chain(candl_program_p, CandlStatement*, int, int);
1762 -candl_dependence_var_is_ref(CandlStatement*, int);
1765 -candl_dependence_check_domain_is_included(CandlStatement*, CandlStatement*,
1766 - CandlMatrix*, int);
1769 -candl_dependence_scalar_is_privatizable_at(candl_program_p, int, int);
1772 -candl_dependence_is_loop_carried (candl_program_p, CandlDependence*, int);
1775 -candl_dependence_prune_scalar_waw (candl_program_p, CandlOptions*,
1776 - CandlDependence**);
1779 -candl_dependence_prune_with_privatization (candl_program_p, CandlOptions*,
1780 - CandlDependence**);
1783 -candl_dependence_scalar_renaming(candl_program_p, CandlOptions*,
1784 - CandlDependence**);
1787 -candl_dependence_analyze_scalars(candl_program_p, CandlOptions*);
1788 +int candl_dependence_var_is_scalar(struct osl_scop*, int);
1789 +struct osl_statement** candl_dependence_refvar_chain(struct osl_scop*,
1790 + struct osl_statement*, int, int);
1791 +int candl_dependence_var_is_ref(struct osl_statement*, int);
1792 +int candl_dependence_check_domain_is_included(
1793 + struct osl_statement*,
1794 + struct osl_statement*,
1795 + struct osl_relation*, int);
1796 +int candl_dependence_scalar_is_privatizable_at(
1797 + struct osl_scop*, int, int);
1798 +int candl_dependence_is_loop_carried(struct osl_scop*,
1799 + struct osl_dependence*, int);
1800 +void candl_dependence_prune_scalar_waw(struct osl_scop*,
1802 + struct osl_dependence**);
1803 +void candl_dependence_prune_with_privatization(
1806 + struct osl_dependence**);
1807 +int candl_dependence_scalar_renaming(struct osl_scop*,
1809 + struct osl_dependence**);
1810 +int candl_dependence_analyze_scalars(struct osl_scop*,
1813 /******************************************************************************
1814 * Miscellaneous functions *
1815 ******************************************************************************/
1817 -candl_num_dependences(CandlDependence *candl_deps);
1820 -candl_compute_last_writer (CandlDependence *dep, CandlProgram *prog);
1821 +struct osl_relation* candl_dependence_get_relation_ref_source_in_dep(
1822 + struct osl_dependence*);
1823 +struct osl_relation* candl_dependence_get_relation_ref_target_in_dep(
1824 + struct osl_dependence*);
1825 +int candl_num_dependences(struct osl_dependence*);
1826 +void candl_compute_last_writer(struct osl_dependence*,
1827 + struct osl_scop*);
1828 +struct osl_dependence* candl_dependence_prune_transitively_covered(
1829 + struct osl_dependence*);
1832 -candl_dependence_prune_transitively_covered (CandlDependence* deps);
1834 # if defined(__cplusplus)
1837 diff --git a/include/candl/macros.h.in b/include/candl/macros.h.in
1838 new file mode 100644
1839 index 0000000..def4643
1841 +++ b/include/candl/macros.h.in
1844 + /**------ ( ----------------------------------------------------------**
1846 + **----- / ) --------------------------------------------------------**
1847 + ** ( * ( candl.h **
1848 + **---- \#/ --------------------------------------------------------**
1849 + ** .-"#'-. First version: september 8th 2003 **
1850 + **--- |"-.-"| -------------------------------------------------------**
1853 + ******** | | *************************************************************
1854 + * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
1855 + ******************************************************************************
1857 + * Copyright (C) 2003-2008 Cedric Bastoul *
1859 + * This is free software; you can redistribute it and/or modify it under the *
1860 + * terms of the GNU Lesser General Public License as published by the Free *
1861 + * Software Foundation; either version 3 of the License, or (at your option) *
1862 + * any later version. *
1864 + * This software is distributed in the hope that it will be useful, but *
1865 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
1866 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
1867 + * for more details. *
1869 + * You should have received a copy of the GNU Lesser General Public License *
1870 + * along with software; if not, write to the Free Software Foundation, Inc., *
1871 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
1873 + * CAnDL, the Chunky Dependence Analyser *
1874 + * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
1876 + ******************************************************************************/
1879 +/******************************************************************************
1880 + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED FROM macros.h.in BY configure *
1881 + ******************************************************************************/
1883 +#ifndef CANDL_MACROS_H
1884 +# define CANDL_MACROS_H
1886 +# define CANDL_EQUAL 1
1887 +# define CANDL_POSIT 2
1888 +# define CANDL_LATER 3
1889 +# define CANDL_NEVER 4
1891 +# define CANDL_NB_INFOS 3
1893 +# define CANDL_MAX_STRING 2048
1894 +# define CANDL_TEMP_OUTPUT "candl.temp"
1896 +# define CANDL_RELEASE "@PACKAGE_VERSION@"
1897 +# define CANDL_VERSION "@BITS@"
1898 +@DEFINE_HAS_ISL_LIB@
1900 +/* Useful macros. */
1901 +# define CANDL_max(x,y) ((x) > (y)? (x) : (y))
1902 +# define CANDL_min(x,y) ((x) < (y)? (x) : (y))
1904 +# define CANDL_info(msg) \
1906 + fprintf(stderr,"[Candl] Info: "msg" (%s).\n", __func__); \
1909 +# define CANDL_warning(msg) \
1911 + fprintf(stderr,"[Candl] Warning: "msg" (%s).\n", __func__); \
1914 +# define CANDL_error(msg) \
1916 + fprintf(stderr,"[Candl] Error: "msg" (%s).\n", __func__); \
1920 +# define CANDL_malloc(ptr, type, size) \
1922 + if (((ptr) = (type)malloc(size)) == NULL) \
1923 + CANDL_error("memory overflow"); \
1926 +# define CANDL_realloc(ptr, type, size) \
1928 + if (((ptr) = (type)realloc(ptr, size)) == NULL) \
1929 + CANDL_error("memory overflow"); \
1932 +# define CANDL_fail(msg) { fprintf(stderr, "[Candl] " msg "\n"); exit(1); }
1934 +/******************************************************************************
1936 + ******************************************************************************/
1937 +#if defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
1938 +#define CANDL_FMT "%4lld "
1939 +#elif defined(CANDL_LINEAR_VALUE_IS_LONG)
1940 +#define CANDL_FMT "%4ld "
1942 +#define CANDL_FMT "%4s"
1945 +/******************************************************************************
1946 + * CANDL GMP MACROS *
1947 + ******************************************************************************/
1948 +#ifdef CANDL_LINEAR_VALUE_IS_MP
1950 +#define CANDL_init(val) (mpz_init((val)))
1951 +#define CANDL_assign(v1,v2) (mpz_set((v1),(v2)))
1952 +#define CANDL_set_si(val,i) (mpz_set_si((val),(i)))
1953 +#define CANDL_get_si(val) (mpz_get_si((val)))
1954 +#define CANDL_clear(val) (mpz_clear((val)))
1955 +#define CANDL_print(Dst,fmt,val) { char *str; \
1956 + str = mpz_get_str(0,10,(val)); \
1957 + fprintf((Dst),(fmt),str); free(str); \
1960 +/* Boolean operators on 'Value' or 'Entier' */
1961 +#define CANDL_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
1962 +#define CANDL_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
1964 +/* Binary operators on 'Value' or 'Entier' */
1965 +#define CANDL_increment(ref,val) (mpz_add_ui((ref),(val),1))
1966 +#define CANDL_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
1967 +#define CANDL_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
1968 +#define CANDL_oppose(ref,val) (mpz_neg((ref),(val)))
1970 +/* Conditional operations on 'Value' or 'Entier' */
1971 +#define CANDL_zero_p(val) (mpz_sgn(val) == 0)
1972 +#define CANDL_notzero_p(val) (mpz_sgn(val) != 0)
1974 +/******************************************************************************
1975 + * CANDL BASIC TYPES MACROS *
1976 + ******************************************************************************/
1979 +#define CANDL_init(val) ((val) = 0)
1980 +#define CANDL_assign(v1,v2) ((v1) = (v2))
1981 +#define CANDL_set_si(val,i) ((val) = (Entier)(i))
1982 +#define CANDL_get_si(val) ((val))
1983 +#define CANDL_clear(val) ((val) = 0)
1984 +#define CANDL_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
1986 +/* Boolean operators on 'Value' or 'Entier' */
1987 +#define CANDL_eq(v1,v2) ((v1)==(v2))
1988 +#define CANDL_ne(v1,v2) ((v1)!=(v2))
1990 +/* Binary operators on 'Value' or 'Entier' */
1991 +#define CANDL_increment(ref,val) ((ref) = (val)+(Entier)(1))
1992 +#define CANDL_decrement(ref,val) ((ref) = (val)-(Entier)(1))
1993 +#define CANDL_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
1994 +#define CANDL_oppose(ref,val) ((ref) = (-(val)))
1996 +/* Conditional operations on 'Value' or 'Entier' */
1997 +#define CANDL_zero_p(val) CANDL_eq(val,0)
1998 +#define CANDL_notzero_p(val) CANDL_ne(val,0)
2002 +#endif // !CANDL_MACROS_H
2003 diff --git a/include/candl/matrix.h b/include/candl/matrix.h
2004 index 7bbc13b..60e525f 100644
2005 --- a/include/candl/matrix.h
2006 +++ b/include/candl/matrix.h
2009 ******************************************************************************/
2012 #ifndef CANDL_MATRIX_H
2013 # define CANDL_MATRIX_H
2015 -# include <stdio.h>
2016 -# include <piplib/piplib.h>
2018 -# ifdef LINEAR_VALUE_IS_LONG
2019 -# define CLAN_INT_T_IS_LONG
2021 -# ifdef LINEAR_VALUE_IS_LONGLONG
2022 -# define CLAN_INT_T_IS_LONGLONG
2024 -# ifdef LINEAR_VALUE_IS_MP
2025 -# define CLAN_INT_T_IS_MP
2027 +# include <candl/violation.h>
2029 # if defined(__cplusplus)
2034 +struct osl_relation;
2035 +struct osl_dependence;
2038 - * The matrix structure comes directly from PipLib (defined in piplib/piplib.h)
2039 - * which is directly the PolyLib Matrix (defined in polylib/types.h)
2040 - * here is how it looks like (at least in PipLib 1.3.5 version):
2042 - * struct pipmatrix
2043 - * { unsigned NbRows; // The number of rows (= NbConstraints in Polyhedron).
2044 - * unsigned NbColumns; // The number of columns (= Dimension+2 in Polyhedron).
2045 - * Value **p; // An array of pointers to the beginning of each row.
2046 - * Value *p_Init; // The matrix is stored here, contiguously in memory.
2047 - * int p_Init_size; // Needed to free the memory allocated by mpz_init.
2049 - * typedef struct pipmatrix PipMatrix ;
2052 -typedef PipMatrix CandlMatrix;
2056 - * CandlMatrixList structure:
2057 - * this structure reprensents a node of a linked list of CandlMatrix structures.
2059 -struct candlmatrixlist
2060 -{ CandlMatrix * matrix; /**< An element of the list. */
2061 - struct candlmatrixlist * next;/**< Pointer to the next element of the list.*/
2063 -typedef struct candlmatrixlist CandlMatrixList;
2066 -/******************************************************************************
2067 - * Structure display function *
2068 - ******************************************************************************/
2069 -void candl_matrix_print_structure(FILE *, CandlMatrix *, int);
2070 -void candl_matrix_print(FILE *, CandlMatrix *);
2071 -void candl_matrix_print_data(FILE *, CandlMatrix *);
2072 -void candl_matrix_list_print_structure(FILE *, CandlMatrixList *, int);
2073 -void candl_matrix_list_print(FILE *, CandlMatrixList *);
2075 -/******************************************************************************
2076 - * Memory deallocation function *
2077 - ******************************************************************************/
2078 -void candl_matrix_free(CandlMatrix *);
2079 -void candl_matrix_list_free(CandlMatrixList *);
2082 -/******************************************************************************
2083 - * Reading functions *
2084 - ******************************************************************************/
2085 -CandlMatrix * candl_matrix_read(FILE *);
2086 -CandlMatrixList * candl_matrix_list_read(FILE *);
2089 -/******************************************************************************
2090 - * Processing functions *
2091 - ******************************************************************************/
2092 -CandlMatrix * candl_matrix_malloc(int, int);
2093 -CandlMatrixList * candl_matrix_list_malloc();
2094 -CandlMatrix * candl_matrix_violation(CandlMatrix *, CandlMatrix *,
2095 - CandlMatrix *, int, int);
2096 -int candl_matrix_check_point (CandlMatrix* , CandlMatrix* );
2097 +candl_violation_p candl_matrix_violation(struct osl_dependence*,
2098 + struct osl_relation*, struct osl_relation*,
2100 +int candl_matrix_check_point(struct osl_relation*,
2101 + struct osl_relation*);
2103 # if defined(__cplusplus)
2106 -#endif /* define CANDL_DEPENDENCE_H */
2109 diff --git a/include/candl/options.h b/include/candl/options.h
2110 index e62fddb..7154cb5 100644
2111 --- a/include/candl/options.h
2112 +++ b/include/candl/options.h
2115 ******************************************************************************/
2118 #ifndef CANDL_OPTIONS_H
2119 # define CANDL_OPTIONS_H
2121 @@ -44,60 +43,55 @@ extern "C"
2127 - * CandlOptions structure:
2128 + * candl_options structure:
2129 * this structure contains all the informations on the state of Candl options.
2131 -struct candloptions
2132 -{ /* OPTIONS FOR DEPENDENCE COMPUTATION */
2133 +struct candl_options {
2134 + /* OPTIONS FOR DEPENDENCE COMPUTATION */
2135 int waw; /**< 1 if write after write (output) dependences matter. */
2136 int raw; /**< 1 if read after write (flow) dependences matter. */
2137 int war; /**< 1 if write after read (anti) dependences matter. */
2138 int rar; /**< 1 if read after read (input) dependences matter. */
2139 int commute; /**< 1 to use commutativity to simplify dependences. */
2140 int fullcheck; /**< 1 to compute all dependence violations. */
2141 - int depgraph; /**< 1 to print the dependence graph. */
2142 - int violgraph; /**< 1 to print the violation graph. */
2143 int scalar_renaming; /**< 1 to enable scalar renaming. */
2144 int scalar_privatization; /**< 1 to enable scalar privatization. */
2145 int scalar_expansion; /**< 1 to enable scalar privatization. */
2146 int lastwriter; /**< 1 to compute last writer */
2147 - int readscop; /**< 1 to enable reading from a .scop formatted file. */
2148 - int writescop; /**< 1 to enable writing to a .scop formatted file. */
2149 - int scoptocandl; /**< 1 to act as a .scop to candl converter. */
2150 int verbose; /**< 1 to enable verbose output. */
2151 + int outscop; /**< 1 to print the scop with dependences. */
2152 + int autocorrect; /**< 1 to correct violations. fullcheck is set to 1 and
2153 + * the -test is required.
2155 /* UNDOCUMENTED OPTIONS FOR THE AUTHOR ONLY */
2156 int view; /**< 1 to call dot and gv to visualize the graphs. */
2157 int structure; /**< 1 to print internal dependence structure. */
2158 int prune_dups; /**< 1 to use experimental dependence pruning algorithm. */
2160 -typedef struct candloptions CandlOptions;
2163 +typedef struct candl_options candl_options_t;
2164 +typedef struct candl_options* candl_options_p;
2166 /******************************************************************************
2167 * Structure display function *
2168 ******************************************************************************/
2169 -void candl_options_print(FILE *, CandlOptions *);
2171 +void candl_options_print(FILE *, candl_options_p);
2173 /******************************************************************************
2174 * Memory deallocation function *
2175 ******************************************************************************/
2176 -void candl_options_free(CandlOptions *);
2178 +void candl_options_free(candl_options_p);
2180 /******************************************************************************
2181 * Reading function *
2182 ******************************************************************************/
2183 -void candl_options_read(int, char **, FILE **, FILE **, CandlOptions **);
2185 +void candl_options_read(int, char **, FILE **, FILE **, FILE**, candl_options_p*);
2187 /******************************************************************************
2188 * Processing functions *
2189 ******************************************************************************/
2190 -CandlOptions * candl_options_malloc(void);
2192 +candl_options_p candl_options_malloc(void);
2194 #if defined(__cplusplus)
2196 diff --git a/include/candl/piplib-wrapper.h b/include/candl/piplib-wrapper.h
2197 index 27576f5..642e366 100644
2198 --- a/include/candl/piplib-wrapper.h
2199 +++ b/include/candl/piplib-wrapper.h
2201 #ifndef CANDL_PIPLIB_WRAPPER_H
2202 # define CANDL_PIPLIB_WRAPPER_H
2205 -# include <stdio.h>
2206 -# include <candl/matrix.h>
2210 # if defined(__cplusplus)
2217 -pip_has_rational_point(PipMatrix* system,
2218 - PipMatrix* context,
2219 - int conservative);
2221 +struct osl_relation;
2227 +struct pipmatrix* pip_relation2matrix(struct osl_relation*);
2228 +struct osl_relation* pip_matrix2relation(struct pipmatrix*);
2229 +int pip_has_rational_point(struct osl_relation*,
2230 + struct osl_relation*, int);
2231 +struct pipquast* pip_solve_osl(struct osl_relation*, struct osl_relation*,
2232 + int, struct pipoptions*);
2233 +int piplist_are_equal(struct piplist*, struct piplist*, int);
2234 +struct osl_relation* pip_quast_to_polyhedra(struct pipquast*, int, int);
2235 +struct osl_relation* pip_quast_no_solution_to_polyhedra(struct pipquast*,
2238 # if defined(__cplusplus)
2240 diff --git a/include/candl/piplib.h.in b/include/candl/piplib.h.in
2241 new file mode 100644
2242 index 0000000..dfaf33a
2244 +++ b/include/candl/piplib.h.in
2247 + /**------ ( ----------------------------------------------------------**
2249 + **----- / ) --------------------------------------------------------**
2250 + ** ( * ( piplib.h **
2251 + **---- \#/ --------------------------------------------------------**
2252 + ** .-"#'-. First version: August 5th 2014 **
2253 + **--- |"-.-"| -------------------------------------------------------**
2256 + ******** | | *************************************************************
2257 + * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
2258 + ******************************************************************************
2260 + * Copyright (C) 2003-2008 Cedric Bastoul *
2262 + * This is free software; you can redistribute it and/or modify it under the *
2263 + * terms of the GNU Lesser General Public License as published by the Free *
2264 + * Software Foundation; either version 3 of the License, or (at your option) *
2265 + * any later version. *
2267 + * This software is distributed in the hope that it will be useful, but *
2268 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
2269 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
2270 + * for more details. *
2272 + * You should have received a copy of the GNU Lesser General Public License *
2273 + * along with software; if not, write to the Free Software Foundation, Inc., *
2274 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
2276 + * CAnDL, the Chunky Dependence Analyzer *
2277 + * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
2279 + ******************************************************************************/
2282 +#ifndef CANDL_PIPLIB_H
2283 +# define CANDL_PIPLIB_H
2285 +# if defined(__cplusplus)
2290 +# include <piplib/piplib@BITS@.h>
2292 +# if defined(__cplusplus)
2295 +#endif /* define CANDL_PIPLIB_H */
2297 diff --git a/include/candl/program.h b/include/candl/program.h
2298 deleted file mode 100644
2299 index 073016a..0000000
2300 --- a/include/candl/program.h
2304 - /**------ ( ----------------------------------------------------------**
2306 - **----- / ) --------------------------------------------------------**
2307 - ** ( * ( program.h **
2308 - **---- \#/ --------------------------------------------------------**
2309 - ** .-"#'-. First version: september 9th 2003 **
2310 - **--- |"-.-"| -------------------------------------------------------**
2313 - ******** | | *************************************************************
2314 - * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
2315 - ******************************************************************************
2317 - * Copyright (C) 2003-2008 Cedric Bastoul *
2319 - * This is free software; you can redistribute it and/or modify it under the *
2320 - * terms of the GNU General Public License as published by the Free Software *
2321 - * Foundation; either version 2 of the License, or (at your option) any later *
2324 - * This software is distributed in the hope that it will be useful, but *
2325 - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
2326 - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
2327 - * for more details. *
2329 - * You should have received a copy of the GNU General Public License along *
2330 - * with software; if not, write to the Free Software Foundation, Inc., *
2331 - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
2333 - * CAnDL, the Chunky Dependence Analyzer *
2334 - * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
2336 - ******************************************************************************/
2339 -#ifndef CANDL_PROGRAM_H
2340 -# define CANDL_PROGRAM_H
2342 -# include <stdio.h>
2343 -# include <stdlib.h>
2344 -# include <candl/matrix.h>
2345 -# include <candl/statement.h>
2347 -# ifdef CANDL_SUPPORTS_SCOPLIB
2348 -# include <scoplib/scop.h>
2352 -# if defined(__cplusplus)
2358 - * candl_program_t structure:
2359 - * this structure contains all the informations about a program.
2361 -struct candl_program
2363 - CandlMatrix * context; /**< The context of the program. */
2364 - int nb_statements; /**< The number of statements. */
2365 - CandlStatement ** statement; /**< Array of nb_statements pointers on
2366 - * the statements of the program.
2368 - CandlMatrix ** transformation; /**< Array of nb_statements pointers on
2369 - * the transformation candidate (one
2370 - * function per statement). If NULL:
2371 - * no tranformation candidate.
2373 - int* scalars_privatizable;
2375 -typedef struct candl_program CandlProgram;
2376 -typedef struct candl_program candl_program_t;
2377 -typedef struct candl_program * candl_program_p;
2380 -/******************************************************************************
2381 - * Structure display function *
2382 - ******************************************************************************/
2383 -void candl_program_print_structure(FILE *, candl_program_p, int);
2384 -void candl_program_print(FILE *, candl_program_p);
2385 -void candl_program_print_candl_file(FILE *, candl_program_p);
2387 -/******************************************************************************
2388 - * Memory alloc/dealloc function *
2389 - ******************************************************************************/
2390 -candl_program_p candl_program_malloc();
2391 -void candl_program_free(candl_program_p);
2394 -/******************************************************************************
2395 - * Reading function *
2396 - ******************************************************************************/
2397 -candl_program_p candl_program_read(FILE *);
2398 -/* This function is compiled if candl was configured with CLAN support. */
2399 -# ifdef CANDL_SUPPORTS_SCOPLIB
2400 -candl_program_p candl_program_read_scop(FILE *);
2403 -/******************************************************************************
2404 - * Processing functions *
2405 - ******************************************************************************/
2406 -/* This function is compiled if candl was configured with CLAN support. */
2407 -# ifdef CANDL_SUPPORTS_SCOPLIB
2408 -candl_program_p candl_program_convert_scop(scoplib_scop_p, int**);
2411 -# if defined(__cplusplus)
2414 -#endif /* define CANDL_PROGRAM_H */
2416 diff --git a/include/candl/pruning.h b/include/candl/pruning.h
2417 deleted file mode 100644
2418 index ad75e38..0000000
2419 --- a/include/candl/pruning.h
2423 - /**------ ( ----------------------------------------------------------**
2425 - **----- / ) --------------------------------------------------------**
2426 - ** ( * ( pruning.h **
2427 - **---- \#/ --------------------------------------------------------**
2428 - ** .-"#'-. First version: July 17th 2011 **
2429 - **--- |"-.-"| -------------------------------------------------------**
2432 - ******** | | *************************************************************
2433 - * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
2434 - ******************************************************************************
2436 - * Copyright (C) 2003-2008 Cedric Bastoul *
2438 - * This is free software; you can redistribute it and/or modify it under the *
2439 - * terms of the GNU General Public License as published by the Free Software *
2440 - * Foundation; either version 2 of the License, or (at your option) any later *
2443 - * This software is distributed in the hope that it will be useful, but *
2444 - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
2445 - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
2446 - * for more details. *
2448 - * You should have received a copy of the GNU General Public License along *
2449 - * with software; if not, write to the Free Software Foundation, Inc., *
2450 - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
2452 - * CAnDL, the Chunky Dependence Analyzer *
2453 - * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
2455 - ******************************************************************************/
2459 - * \author Louis-Noel Pouchet
2462 -#ifndef CANDL_PRUNING_H
2463 -# define CANDL_PRUNING_H
2466 -# include <stdio.h>
2467 -# include <candl/statement.h>
2468 -# include <candl/matrix.h>
2469 -# include <candl/program.h>
2470 -# include <candl/options.h>
2471 -# include <candl/matrix.h>
2474 -# if defined(__cplusplus)
2480 -candl_dependence_prune_transitively_covered (CandlDependence* deps);
2482 -# if defined(__cplusplus)
2485 -#endif /* define CANDL_PRUNING_H */
2487 diff --git a/include/candl/scop.h b/include/candl/scop.h
2488 new file mode 100644
2489 index 0000000..ead43ed
2491 +++ b/include/candl/scop.h
2494 + /**------ ( ----------------------------------------------------------**
2496 + **----- / ) --------------------------------------------------------**
2497 + ** ( * ( scop.h **
2498 + **---- \#/ --------------------------------------------------------**
2499 + ** .-"#'-. First version: july 9th 2012 **
2500 + **--- |"-.-"| -------------------------------------------------------**
2503 + ******** | | *************************************************************
2504 + * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
2505 + ******************************************************************************
2507 + * Copyright (C) 2003-2008 Cedric Bastoul *
2509 + * This is free software; you can redistribute it and/or modify it under the *
2510 + * terms of the GNU General Public License as published by the Free Software *
2511 + * Foundation; either version 2 of the License, or (at your option) any later *
2514 + * This software is distributed in the hope that it will be useful, but *
2515 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
2516 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
2517 + * for more details. *
2519 + * You should have received a copy of the GNU General Public License along *
2520 + * with software; if not, write to the Free Software Foundation, Inc., *
2521 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
2523 + * CAnDL, the Chunky Dependence Analyzer *
2524 + * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
2526 + ******************************************************************************/
2529 + * author Joel Poudroux
2532 +#ifndef CANDL_SCOP_H
2533 +# define CANDL_SCOP_H
2535 +# if defined(__cplusplus)
2542 +struct candl_scop_usr {
2544 + int *scalars_privatizable;
2545 + void *usr_backup; /**< If there is already a usr field, it will be saved */
2548 +typedef struct candl_scop_usr candl_scop_usr_t;
2549 +typedef struct candl_scop_usr* candl_scop_usr_p;
2551 +void candl_scop_usr_init(struct osl_scop*);
2552 +void candl_scop_usr_cleanup(struct osl_scop*);
2554 +# if defined(__cplusplus)
2559 diff --git a/include/candl/statement.h b/include/candl/statement.h
2560 index 9e434a4..a26eff6 100644
2561 --- a/include/candl/statement.h
2562 +++ b/include/candl/statement.h
2564 **----- / ) --------------------------------------------------------**
2565 ** ( * ( statement.h **
2566 **---- \#/ --------------------------------------------------------**
2567 - ** .-"#'-. First version: september 8th 2003 **
2568 + ** .-"#'-. First version: july 9th 2012 **
2569 **--- |"-.-"| -------------------------------------------------------**
2574 ******************************************************************************/
2577 + * author Joel Poudroux
2580 #ifndef CANDL_STATEMENT_H
2581 -# define CANDL_STATEMENT_H
2583 -# include <stdio.h>
2584 -# include <candl/matrix.h>
2585 +#define CANDL_STATEMENT_H
2587 # if defined(__cplusplus)
2593 +struct osl_statement;
2596 - * CandlStatement structure:
2597 - * this structure contains all the informations about a program statement.
2599 -struct candlstatement
2600 -{ int label; /**< Statement number (it must be the array
2601 - * index of this statement in the "statement"
2602 - * field of the CandlProgram structure).
2604 - int type; /**< Statement type. */
2605 - int depth; /**< Nesting level (nb of surrounding loops).*/
2606 - int * index; /**< Iteration domain's iterator labels. */
2607 - CandlMatrix * domain; /**< Iteration domain. */
2608 - CandlMatrix * written; /**< Array of written data. */
2609 - CandlMatrix * read; /**< Array of read data. */
2610 - void* ref; /**< Reference to another structure
2611 - describing the same statement. */
2612 +struct candl_statement_usr {
2613 + int label; /**< Statement label = 'n'th statement */
2616 + int *index; /**< Loops label name */
2617 + void *usr_backup; /**< If there is already a usr field, it will be saved */
2619 -typedef struct candlstatement CandlStatement;
2622 -/******************************************************************************
2623 - * Structure display function *
2624 - ******************************************************************************/
2625 -void candl_statement_print_structure(FILE *, CandlStatement *, int);
2626 -void candl_statement_print(FILE *, CandlStatement *);
2629 -/******************************************************************************
2630 - * Memory deallocation function *
2631 - ******************************************************************************/
2632 -void candl_statement_free(CandlStatement *);
2635 -/******************************************************************************
2636 - * Reading functions *
2637 - ******************************************************************************/
2638 -CandlStatement * candl_statement_read(FILE *, int, int);
2641 -/******************************************************************************
2642 - * Processing functions *
2643 - ******************************************************************************/
2644 -CandlStatement * candl_statement_malloc();
2645 -int candl_statement_commute(CandlStatement *, CandlStatement *);
2646 +typedef struct candl_statement_usr candl_statement_usr_t;
2647 +typedef struct candl_statement_usr* candl_statement_usr_p;
2649 +void candl_statement_usr_init_all(struct osl_scop*);
2650 +void candl_statement_usr_cleanup(struct osl_statement*);
2652 # if defined(__cplusplus)
2655 -#endif /* define CANDL_STATEMENT_H */
2659 diff --git a/include/candl/util.h b/include/candl/util.h
2660 new file mode 100644
2661 index 0000000..c20f09b
2663 +++ b/include/candl/util.h
2666 + /**------ ( ----------------------------------------------------------**
2668 + **----- / ) --------------------------------------------------------**
2669 + ** ( * ( util.h **
2670 + **---- \#/ --------------------------------------------------------**
2671 + ** .-"#'-. First version: june 7th 2012 **
2672 + **--- |"-.-"| -------------------------------------------------------**
2675 + ******** | | *************************************************************
2676 + * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
2677 + ******************************************************************************
2679 + * Copyright (C) 2003-2008 Cedric Bastoul *
2681 + * This is free software; you can redistribute it and/or modify it under the *
2682 + * terms of the GNU General Public License as published by the Free Software *
2683 + * Foundation; either version 2 of the License, or (at your option) any later *
2686 + * This software is distributed in the hope that it will be useful, but *
2687 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
2688 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
2689 + * for more details. *
2691 + * You should have received a copy of the GNU General Public License along *
2692 + * with software; if not, write to the Free Software Foundation, Inc., *
2693 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
2695 + * CAnDL, the Chunky Dependence Analyzer *
2696 + * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
2698 + ******************************************************************************/
2701 + * author Joel Poudroux
2704 +#ifndef CANDL_UTIL_H
2705 +#define CANDL_UTIL_H
2707 +# if defined(__cplusplus)
2713 +struct osl_relation;
2714 +struct osl_statement;
2716 +int candl_util_relation_get_line(struct osl_relation*, int);
2717 +int candl_util_statement_commute(struct osl_statement*, struct osl_statement*);
2718 +int candl_util_check_scop(struct osl_scop*, struct osl_scop*);
2719 +int candl_util_check_scop_list(struct osl_scop*, struct osl_scop*);
2721 +# if defined(__cplusplus)
2726 diff --git a/include/candl/violation.h b/include/candl/violation.h
2727 index da09565..f395b63 100644
2728 --- a/include/candl/violation.h
2729 +++ b/include/candl/violation.h
2731 # define CANDL_VIOLATION_H
2734 -# include <candl/dependence.h>
2735 -# include <candl/matrix.h>
2736 +# include <candl/options.h>
2738 # if defined(__cplusplus)
2744 +struct osl_dependence;
2745 +struct osl_relation;
2748 * CandlViolation structure:
2749 * this structure contains all informations about a data dependence violation.
2751 -struct candlviolation
2752 -{ CandlDependence * dependence; /**< Pointer to violated dependence. */
2753 - int dimension; /**< Violation dimension. */
2754 - CandlMatrix * domain; /**< Violation polyhedron. */
2755 - struct candlviolation * next; /**< Pointer to next violation. */
2758 + Violation domain structure
2759 + ________________________________________________________________________________________________
2760 + / source (output) | target (input) | local dims \
2761 + __ |_______________________|_______________________|___________________________________________________|_____________
2762 + / eq |output |output |output |output |output |output |ld dom |ld acc |ld scatt |ld dom |ld acc |ld scatt | | \
2763 + | in |domain |access |scatt |domain |access |scatt |source |source |source |target |target |target |parameters | 1 |
2764 + _____________________|____|_______|_______|_______|_______|_______|_______|_______|_______|_________|_______|_______|_________|___________|___|
2765 + |Domain source | X | X : : | : : | X : : | : : | X | X |
2766 + |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
2767 + |Domain target | X | : : | X : : | : : | X : : | X | X |
2768 + |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
2769 + Dependence |Access source | X | X : X : | : : | : X : | : : | X | X |
2770 + system |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
2771 + |Access target | X | : : | X : X : | : : | : X : | X | X |
2772 + |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
2773 + |Access equality | | : Id : | : -Id : | : : | : : | | |
2774 + |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___| | 0 : 0..depth-1
2775 + |Precedence | X | Id : : | -Id : : | : : | : : | | X | <--| 0|-1 : depth
2776 + ===============================================================================================================================================
2777 + |Scattering | | : : | : : | : : | : : | | |
2778 + |source | X | X : : X | : : | : : X | : : | X | X |
2779 + |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
2780 + |Scattering | | : : | : : | : : | : : | | |
2781 + |target | X | : : | X : : X | : : | : : X | X | X |
2782 + |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
2783 + |Equality at | | : : | : : | : : | : : | | |
2784 + |1 ... dim_1 | | : : Id | : : -Id | : : | : : | | |
2785 + |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
2786 + at |Scat source > | | : : | : : | : : | : : | | |
2787 + dim |Scat target | 1 | : : 1 | : : -1 | : : | : : | |-1 |
2788 + \________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___/
2793 +struct candl_violation {
2794 + struct osl_dependence* dependence; /**< Pointer to violated dependence. */
2795 + int dimension; /**< Violation dimension. */
2796 + struct osl_relation* domain; /**< Violation polyhedron. */
2797 + struct candl_violation* next; /**< Pointer to next violation. */
2799 + int source_nb_output_dims_scattering; // (1)
2800 + int target_nb_output_dims_scattering; // (2)
2801 + int source_nb_local_dims_scattering; // (3)
2802 + int target_nb_local_dims_scattering; // (4)
2804 -typedef struct candlviolation CandlViolation;
2806 +typedef struct candl_violation candl_violation_t;
2807 +typedef struct candl_violation* candl_violation_p;
2809 /******************************************************************************
2810 * Structure display function *
2811 ******************************************************************************/
2812 -void candl_violation_print_structure(FILE *, CandlViolation *, int);
2813 -void candl_violation_print(FILE *, CandlViolation *);
2814 -void candl_violation_pprint(FILE *, CandlViolation *);
2815 -void candl_violation_view(CandlViolation *);
2817 +void candl_violation_idump(FILE*, candl_violation_p, int);
2818 +void candl_violation_dump(FILE*, candl_violation_p);
2819 +void candl_violation_pprint(FILE*, candl_violation_p);
2820 +void candl_violation_view(candl_violation_p);
2822 /******************************************************************************
2823 * Memory deallocation function *
2824 ******************************************************************************/
2825 -void candl_violation_free(CandlViolation *);
2827 +void candl_violation_free(candl_violation_p);
2829 /******************************************************************************
2830 * Processing functions *
2831 ******************************************************************************/
2832 -CandlViolation * candl_violation_malloc();
2833 -void candl_violation_add(CandlViolation **, CandlViolation **,
2834 - CandlViolation *);
2835 -CandlViolation * candl_violation(CandlProgram *, CandlDependence *,
2838 +candl_violation_p candl_violation_malloc();
2839 +void candl_violation_add(candl_violation_p*, candl_violation_p*,
2840 + candl_violation_p);
2841 +candl_violation_p candl_violation(struct osl_scop*, struct osl_dependence*,
2842 + struct osl_scop*, candl_options_p);
2844 # if defined(__cplusplus)
2846 diff --git a/m4/ax_cc_maxopt.m4 b/m4/ax_cc_maxopt.m4
2847 new file mode 100644
2848 index 0000000..da415be
2850 +++ b/m4/ax_cc_maxopt.m4
2852 +# ===========================================================================
2853 +# http://www.nongnu.org/autoconf-archive/ax_cc_maxopt.html
2854 +# ===========================================================================
2862 +# Try to turn on "good" C optimization flags for various compilers and
2863 +# architectures, for some definition of "good". (In our case, good for
2864 +# FFTW and hopefully for other scientific codes. Modify as needed.)
2866 +# The user can override the flags by setting the CFLAGS environment
2867 +# variable. The user can also specify --enable-portable-binary in order to
2868 +# disable any optimization flags that might result in a binary that only
2869 +# runs on the host architecture.
2871 +# Note also that the flags assume that ANSI C aliasing rules are followed
2872 +# by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point
2873 +# computations can be re-ordered as needed.
2875 +# Requires macros: AX_CHECK_COMPILER_FLAGS, AX_COMPILER_VENDOR,
2876 +# AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID.
2880 +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
2881 +# Copyright (c) 2008 Matteo Frigo
2883 +# This program is free software: you can redistribute it and/or modify it
2884 +# under the terms of the GNU General Public License as published by the
2885 +# Free Software Foundation, either version 3 of the License, or (at your
2886 +# option) any later version.
2888 +# This program is distributed in the hope that it will be useful, but
2889 +# WITHOUT ANY WARRANTY; without even the implied warranty of
2890 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
2891 +# Public License for more details.
2893 +# You should have received a copy of the GNU General Public License along
2894 +# with this program. If not, see <http://www.gnu.org/licenses/>.
2896 +# As a special exception, the respective Autoconf Macro's copyright owner
2897 +# gives unlimited permission to copy, distribute and modify the configure
2898 +# scripts that are the output of Autoconf when processing the Macro. You
2899 +# need not follow the terms of the GNU General Public License when using
2900 +# or distributing such scripts, even though portions of the text of the
2901 +# Macro appear in them. The GNU General Public License (GPL) does govern
2902 +# all other use of the material that constitutes the Autoconf Macro.
2904 +# This special exception to the GPL applies to versions of the Autoconf
2905 +# Macro released by the Autoconf Archive. When you make and distribute a
2906 +# modified version of the Autoconf Macro, you may extend this special
2907 +# exception to the GPL to apply to your modified version as well.
2909 +AC_DEFUN([AX_CC_MAXOPT],
2911 +AC_REQUIRE([AC_PROG_CC])
2912 +AC_REQUIRE([AX_COMPILER_VENDOR])
2913 +AC_REQUIRE([AC_CANONICAL_HOST])
2915 +AC_ARG_ENABLE(portable-binary, [AC_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],
2916 + acx_maxopt_portable=$withval, acx_maxopt_portable=no)
2918 +# Try to determine "good" native compiler flags if none specified via CFLAGS
2919 +if test "$ac_test_CFLAGS" != "set"; then
2921 + case $ax_cv_c_compiler_vendor in
2922 + dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"
2923 + if test "x$acx_maxopt_portable" = xno; then
2924 + CFLAGS="$CFLAGS -arch host"
2927 + sun) CFLAGS="-native -fast -xO5 -dalign"
2928 + if test "x$acx_maxopt_portable" = xyes; then
2929 + CFLAGS="$CFLAGS -xarch=generic"
2932 + hp) CFLAGS="+Oall +Optrs_ansi +DSnative"
2933 + if test "x$acx_maxopt_portable" = xyes; then
2934 + CFLAGS="$CFLAGS +DAportable"
2937 + ibm) if test "x$acx_maxopt_portable" = xno; then
2938 + xlc_opt="-qarch=auto -qtune=auto"
2940 + xlc_opt="-qtune=auto"
2942 + AX_CHECK_COMPILER_FLAGS($xlc_opt,
2943 + CFLAGS="-O3 -qansialias -w $xlc_opt",
2944 + [CFLAGS="-O3 -qansialias -w"
2945 + echo "******************************************************"
2946 + echo "* You seem to have the IBM C compiler. It is *"
2947 + echo "* recommended for best performance that you use: *"
2949 + echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"
2950 + echo "* ^^^ ^^^ *"
2951 + echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *"
2952 + echo "* CPU you have. (Set the CFLAGS environment var. *"
2953 + echo "* and re-run configure.) For more info, man cc. *"
2954 + echo "******************************************************"])
2957 + intel) CFLAGS="-O3 -ansi_alias"
2958 + if test "x$acx_maxopt_portable" = xno; then
2959 + icc_archflag=unknown
2963 + # icc accepts gcc assembly syntax, so these should work:
2964 + AX_GCC_X86_CPUID(0)
2965 + AX_GCC_X86_CPUID(1)
2966 + case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
2967 + *:756e6547:*:*) # Intel
2968 + case $ax_cv_gcc_x86_cpuid_1 in
2969 + *6a?:*[[234]]:*:*|*6[[789b]]?:*:*:*) icc_flags="-xK";;
2970 + *f3[[347]]:*:*:*|*f4[1347]:*:*:*) icc_flags="-xP -xN -xW -xK";;
2971 + *f??:*:*:*) icc_flags="-xN -xW -xK";;
2975 + if test "x$icc_flags" != x; then
2976 + for flag in $icc_flags; do
2977 + AX_CHECK_COMPILER_FLAGS($flag, [icc_archflag=$flag; break])
2980 + AC_MSG_CHECKING([for icc architecture flag])
2981 + AC_MSG_RESULT($icc_archflag)
2982 + if test "x$icc_archflag" != xunknown; then
2983 + CFLAGS="$CFLAGS $icc_archflag"
2989 + # default optimization flags for gcc on all systems
2990 + CFLAGS="-O3 -fomit-frame-pointer"
2992 + # -malign-double for x86 systems
2993 + AX_CHECK_COMPILER_FLAGS(-malign-double, CFLAGS="$CFLAGS -malign-double")
2995 + # -fstrict-aliasing for gcc-2.95+
2996 + AX_CHECK_COMPILER_FLAGS(-fstrict-aliasing,
2997 + CFLAGS="$CFLAGS -fstrict-aliasing")
2999 + # note that we enable "unsafe" fp optimization with other compilers, too
3000 + AX_CHECK_COMPILER_FLAGS(-ffast-math, CFLAGS="$CFLAGS -ffast-math")
3002 + AX_GCC_ARCHFLAG($acx_maxopt_portable)
3006 + if test -z "$CFLAGS"; then
3008 + echo "********************************************************"
3009 + echo "* WARNING: Don't know the best CFLAGS for this system *"
3010 + echo "* Use ./configure CFLAGS=... to specify your own flags *"
3011 + echo "* (otherwise, a default of CFLAGS=-O3 will be used) *"
3012 + echo "********************************************************"
3017 + AX_CHECK_COMPILER_FLAGS($CFLAGS, [], [
3019 + echo "********************************************************"
3020 + echo "* WARNING: The guessed CFLAGS don't seem to work with *"
3021 + echo "* your compiler. *"
3022 + echo "* Use ./configure CFLAGS=... to specify your own flags *"
3023 + echo "********************************************************"
3030 diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4
3031 new file mode 100644
3032 index 0000000..026c6e9
3034 +++ b/m4/ax_cflags_warn_all.m4
3036 +# ===========================================================================
3037 +# http://www.nongnu.org/autoconf-archive/ax_cflags_warn_all.html
3038 +# ===========================================================================
3042 +# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
3046 +# Try to find a compiler option that enables most reasonable warnings.
3048 +# For the GNU CC compiler it will be -Wall (and -ansi -pedantic) The
3049 +# result is added to the shellvar being CFLAGS by default.
3051 +# Currently this macro knows about GCC, Solaris C compiler, Digital Unix C
3052 +# compiler, C for AIX Compiler, HP-UX C compiler, IRIX C compiler, NEC
3053 +# SX-5 (Super-UX 10) C compiler, and Cray J90 (Unicos 10.0.0.8) C
3056 +# - $1 shell-variable-to-add-to : CFLAGS
3057 +# - $2 add-value-if-not-found : nothing
3058 +# - $3 action-if-found : add value to shellvariable
3059 +# - $4 action-if-not-found : nothing
3063 +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
3065 +# This program is free software; you can redistribute it and/or modify it
3066 +# under the terms of the GNU General Public License as published by the
3067 +# Free Software Foundation; either version 2 of the License, or (at your
3068 +# option) any later version.
3070 +# This program is distributed in the hope that it will be useful, but
3071 +# WITHOUT ANY WARRANTY; without even the implied warranty of
3072 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
3073 +# Public License for more details.
3075 +# You should have received a copy of the GNU General Public License along
3076 +# with this program. If not, see <http://www.gnu.org/licenses/>.
3078 +# As a special exception, the respective Autoconf Macro's copyright owner
3079 +# gives unlimited permission to copy, distribute and modify the configure
3080 +# scripts that are the output of Autoconf when processing the Macro. You
3081 +# need not follow the terms of the GNU General Public License when using
3082 +# or distributing such scripts, even though portions of the text of the
3083 +# Macro appear in them. The GNU General Public License (GPL) does govern
3084 +# all other use of the material that constitutes the Autoconf Macro.
3086 +# This special exception to the GPL applies to versions of the Autoconf
3087 +# Macro released by the Autoconf Archive. When you make and distribute a
3088 +# modified version of the Autoconf Macro, you may extend this special
3089 +# exception to the GPL to apply to your modified version as well.
3091 +AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
3092 +AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
3093 +AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_warn_all])dnl
3094 +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
3095 +VAR,[VAR="no, unknown"
3098 + ac_save_[]FLAGS="$[]FLAGS"
3100 +in "-pedantic % -Wall" dnl GCC
3101 + "-xstrconst % -v" dnl Solaris C
3102 + "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
3103 + "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
3104 + "-ansi -ansiE % -fullwarn" dnl IRIX
3105 + "+ESlit % +w1" dnl HP-UX C
3106 + "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
3107 + "-h conform % -h msglevel 2" dnl Cray C (Unicos)
3109 +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
3110 + AC_TRY_COMPILE([],[return 0;],
3111 + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
3113 + FLAGS="$ac_save_[]FLAGS"
3117 + .ok|.ok,*) m4_ifvaln($3,$3) ;;
3118 + .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
3119 + AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
3120 + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
3121 + *) m4_ifvaln($3,$3,[
3122 + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
3123 + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
3124 + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
3125 + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
3128 +AS_VAR_POPDEF([VAR])dnl
3129 +AS_VAR_POPDEF([FLAGS])dnl
3132 +dnl the only difference - the LANG selection... and the default FLAGS
3134 +AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
3135 +AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
3136 +AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_warn_all])dnl
3137 +AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
3138 +VAR,[VAR="no, unknown"
3141 + ac_save_[]FLAGS="$[]FLAGS"
3143 +in "-pedantic % -Wall" dnl GCC
3144 + "-xstrconst % -v" dnl Solaris C
3145 + "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
3146 + "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
3147 + "-ansi -ansiE % -fullwarn" dnl IRIX
3148 + "+ESlit % +w1" dnl HP-UX C
3149 + "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
3150 + "-h conform % -h msglevel 2" dnl Cray C (Unicos)
3152 +do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
3153 + AC_TRY_COMPILE([],[return 0;],
3154 + [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
3156 + FLAGS="$ac_save_[]FLAGS"
3160 + .ok|.ok,*) m4_ifvaln($3,$3) ;;
3161 + .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
3162 + AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
3163 + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
3164 + *) m4_ifvaln($3,$3,[
3165 + if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
3166 + then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
3167 + else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
3168 + m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
3171 +AS_VAR_POPDEF([VAR])dnl
3172 +AS_VAR_POPDEF([FLAGS])dnl
3175 +dnl implementation tactics:
3176 +dnl the for-argument contains a list of options. The first part of
3177 +dnl these does only exist to detect the compiler - usually it is
3178 +dnl a global option to enable -ansi or -extrawarnings. All other
3179 +dnl compilers will fail about it. That was needed since a lot of
3180 +dnl compilers will give false positives for some option-syntax
3181 +dnl like -Woption or -Xoption as they think of it is a pass-through
3182 +dnl to later compile stages or something. The "%" is used as a
3183 +dnl delimimiter. A non-option comment can be given after "%%" marks
3184 +dnl which will be shown but not added to the respective C/CXXFLAGS.
3185 diff --git a/m4/ax_check_compiler_flags.m4 b/m4/ax_check_compiler_flags.m4
3186 new file mode 100644
3187 index 0000000..7da8324
3189 +++ b/m4/ax_check_compiler_flags.m4
3191 +# ===========================================================================
3192 +# http://www.nongnu.org/autoconf-archive/ax_check_compiler_flags.html
3193 +# ===========================================================================
3197 +# AX_CHECK_COMPILER_FLAGS(FLAGS, [ACTION-SUCCESS], [ACTION-FAILURE])
3201 +# Check whether the given compiler FLAGS work with the current language's
3202 +# compiler, or whether they give an error. (Warnings, however, are
3205 +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
3210 +# Copyright (c) 2009 Steven G. Johnson <stevenj@alum.mit.edu>
3211 +# Copyright (c) 2009 Matteo Frigo
3213 +# This program is free software: you can redistribute it and/or modify it
3214 +# under the terms of the GNU General Public License as published by the
3215 +# Free Software Foundation, either version 3 of the License, or (at your
3216 +# option) any later version.
3218 +# This program is distributed in the hope that it will be useful, but
3219 +# WITHOUT ANY WARRANTY; without even the implied warranty of
3220 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
3221 +# Public License for more details.
3223 +# You should have received a copy of the GNU General Public License along
3224 +# with this program. If not, see <http://www.gnu.org/licenses/>.
3226 +# As a special exception, the respective Autoconf Macro's copyright owner
3227 +# gives unlimited permission to copy, distribute and modify the configure
3228 +# scripts that are the output of Autoconf when processing the Macro. You
3229 +# need not follow the terms of the GNU General Public License when using
3230 +# or distributing such scripts, even though portions of the text of the
3231 +# Macro appear in them. The GNU General Public License (GPL) does govern
3232 +# all other use of the material that constitutes the Autoconf Macro.
3234 +# This special exception to the GPL applies to versions of the Autoconf
3235 +# Macro released by the Autoconf Archive. When you make and distribute a
3236 +# modified version of the Autoconf Macro, you may extend this special
3237 +# exception to the GPL to apply to your modified version as well.
3239 +AC_DEFUN([AX_CHECK_COMPILER_FLAGS],
3240 +[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
3241 +AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1])
3242 +dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname:
3243 +AS_LITERAL_IF([$1],
3244 + [AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1]), [
3245 + ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
3246 + _AC_LANG_PREFIX[]FLAGS="$1"
3247 + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
3248 + AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=yes,
3249 + AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=no)
3250 + _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])],
3251 + [ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
3252 + _AC_LANG_PREFIX[]FLAGS="$1"
3253 + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
3254 + eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=yes,
3255 + eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=no)
3256 + _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])
3257 +eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])
3258 +AC_MSG_RESULT($ax_check_compiler_flags)
3259 +if test "x$ax_check_compiler_flags" = xyes; then
3260 + m4_default([$2], :)
3262 + m4_default([$3], :)
3264 +])dnl AX_CHECK_COMPILER_FLAGS
3265 diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4
3266 new file mode 100644
3267 index 0000000..b074260
3269 +++ b/m4/ax_compiler_vendor.m4
3271 +# ===========================================================================
3272 +# http://www.nongnu.org/autoconf-archive/ax_compiler_vendor.html
3273 +# ===========================================================================
3277 +# AX_COMPILER_VENDOR
3281 +# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
3282 +# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
3283 +# watcom, etc. The vendor is returned in the cache variable
3284 +# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
3288 +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
3289 +# Copyright (c) 2008 Matteo Frigo
3291 +# This program is free software: you can redistribute it and/or modify it
3292 +# under the terms of the GNU General Public License as published by the
3293 +# Free Software Foundation, either version 3 of the License, or (at your
3294 +# option) any later version.
3296 +# This program is distributed in the hope that it will be useful, but
3297 +# WITHOUT ANY WARRANTY; without even the implied warranty of
3298 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
3299 +# Public License for more details.
3301 +# You should have received a copy of the GNU General Public License along
3302 +# with this program. If not, see <http://www.gnu.org/licenses/>.
3304 +# As a special exception, the respective Autoconf Macro's copyright owner
3305 +# gives unlimited permission to copy, distribute and modify the configure
3306 +# scripts that are the output of Autoconf when processing the Macro. You
3307 +# need not follow the terms of the GNU General Public License when using
3308 +# or distributing such scripts, even though portions of the text of the
3309 +# Macro appear in them. The GNU General Public License (GPL) does govern
3310 +# all other use of the material that constitutes the Autoconf Macro.
3312 +# This special exception to the GPL applies to versions of the Autoconf
3313 +# Macro released by the Autoconf Archive. When you make and distribute a
3314 +# modified version of the Autoconf Macro, you may extend this special
3315 +# exception to the GPL to apply to your modified version as well.
3317 +AC_DEFUN([AX_COMPILER_VENDOR],
3319 +AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
3320 + [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown
3321 + # note: don't check for gcc first since some other compilers define __GNUC__
3322 + for ventest in intel:__ICC,__ECC,__INTEL_COMPILER ibm:__xlc__,__xlC__,__IBMC__,__IBMCPP__ pathscale:__PATHCC__,__PATHSCALE__ gnu:__GNUC__ sun:__SUNPRO_C,__SUNPRO_CC hp:__HP_cc,__HP_aCC dec:__DECC,__DECCXX,__DECC_VER,__DECCXX_VER borland:__BORLANDC__,__TURBOC__ comeau:__COMO__ cray:_CRAYC kai:__KCC lcc:__LCC__ metrowerks:__MWERKS__ sgi:__sgi,sgi microsoft:_MSC_VER watcom:__WATCOMC__ portland:__PGI; do
3323 + vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
3324 + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
3328 +])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break])
3332 diff --git a/m4/ax_gcc_archflag.m4 b/m4/ax_gcc_archflag.m4
3333 new file mode 100644
3334 index 0000000..dedeef4
3336 +++ b/m4/ax_gcc_archflag.m4
3338 +# ===========================================================================
3339 +# http://www.nongnu.org/autoconf-archive/ax_gcc_archflag.html
3340 +# ===========================================================================
3344 +# AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])
3348 +# This macro tries to guess the "native" arch corresponding to the target
3349 +# architecture for use with gcc's -march=arch or -mtune=arch flags. If
3350 +# found, the cache variable $ax_cv_gcc_archflag is set to this flag and
3351 +# ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is is set to
3352 +# "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is
3353 +# to add $ax_cv_gcc_archflag to the end of $CFLAGS.
3355 +# PORTABLE? should be either [yes] (default) or [no]. In the former case,
3356 +# the flag is set to -mtune (or equivalent) so that the architecture is
3357 +# only used for tuning, but the instruction set used is still portable. In
3358 +# the latter case, the flag is set to -march (or equivalent) so that
3359 +# architecture-specific instructions are enabled.
3361 +# The user can specify --with-gcc-arch=<arch> in order to override the
3362 +# macro's choice of architecture, or --without-gcc-arch to disable this.
3364 +# When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is
3365 +# called unless the user specified --with-gcc-arch manually.
3367 +# Requires macros: AX_CHECK_COMPILER_FLAGS, AX_GCC_X86_CPUID
3369 +# (The main emphasis here is on recent CPUs, on the principle that doing
3370 +# high-performance computing on old hardware is uncommon.)
3374 +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
3375 +# Copyright (c) 2008 Matteo Frigo
3377 +# This program is free software: you can redistribute it and/or modify it
3378 +# under the terms of the GNU General Public License as published by the
3379 +# Free Software Foundation, either version 3 of the License, or (at your
3380 +# option) any later version.
3382 +# This program is distributed in the hope that it will be useful, but
3383 +# WITHOUT ANY WARRANTY; without even the implied warranty of
3384 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
3385 +# Public License for more details.
3387 +# You should have received a copy of the GNU General Public License along
3388 +# with this program. If not, see <http://www.gnu.org/licenses/>.
3390 +# As a special exception, the respective Autoconf Macro's copyright owner
3391 +# gives unlimited permission to copy, distribute and modify the configure
3392 +# scripts that are the output of Autoconf when processing the Macro. You
3393 +# need not follow the terms of the GNU General Public License when using
3394 +# or distributing such scripts, even though portions of the text of the
3395 +# Macro appear in them. The GNU General Public License (GPL) does govern
3396 +# all other use of the material that constitutes the Autoconf Macro.
3398 +# This special exception to the GPL applies to versions of the Autoconf
3399 +# Macro released by the Autoconf Archive. When you make and distribute a
3400 +# modified version of the Autoconf Macro, you may extend this special
3401 +# exception to the GPL to apply to your modified version as well.
3403 +AC_DEFUN([AX_GCC_ARCHFLAG],
3404 +[AC_REQUIRE([AC_PROG_CC])
3405 +AC_REQUIRE([AC_CANONICAL_HOST])
3407 +AC_ARG_WITH(gcc-arch, [AC_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
3408 + ax_gcc_arch=$withval, ax_gcc_arch=yes)
3410 +AC_MSG_CHECKING([for gcc architecture flag])
3412 +AC_CACHE_VAL(ax_cv_gcc_archflag,
3414 +ax_cv_gcc_archflag="unknown"
3416 +if test "$GCC" = yes; then
3418 +if test "x$ax_gcc_arch" = xyes; then
3420 +if test "$cross_compiling" = no; then
3422 + i[[3456]]86*|x86_64*) # use cpuid codes, in part from x86info-1.7 by D. Jones
3423 + AX_GCC_X86_CPUID(0)
3424 + AX_GCC_X86_CPUID(1)
3425 + case $ax_cv_gcc_x86_cpuid_0 in
3426 + *:756e6547:*:*) # Intel
3427 + case $ax_cv_gcc_x86_cpuid_1 in
3428 + *5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
3429 + *5??:*:*:*) ax_gcc_arch=pentium ;;
3430 + *6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
3431 + *6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
3432 + *6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
3433 + *6[[9d]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
3434 + *6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
3435 + *6??:*:*:*) ax_gcc_arch=pentiumpro ;;
3436 + *f3[[347]]:*:*:*|*f4[1347]:*:*:*)
3438 + x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
3439 + *) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
3441 + *f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";;
3443 + *:68747541:*:*) # AMD
3444 + case $ax_cv_gcc_x86_cpuid_1 in
3445 + *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
3446 + *5[[8d]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
3447 + *5[[9]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
3448 + *60?:*:*:*) ax_gcc_arch=k7 ;;
3449 + *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
3450 + *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
3451 + *67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;;
3453 + AX_GCC_X86_CPUID(0x80000006) # L2 cache size
3454 + case $ax_cv_gcc_x86_cpuid_0x80000006 in
3455 + *:*:*[[1-9a-f]]??????:*) # (L2 = ecx >> 16) >= 256
3456 + ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
3457 + *) ax_gcc_arch="athlon-4 athlon k7" ;;
3459 + *f[[4cef8b]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
3460 + *f5?:*:*:*) ax_gcc_arch="opteron k8" ;;
3461 + *f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;;
3462 + *f??:*:*:*) ax_gcc_arch="k8" ;;
3464 + *:746e6543:*:*) # IDT
3465 + case $ax_cv_gcc_x86_cpuid_1 in
3466 + *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
3467 + *58?:*:*:*) ax_gcc_arch=winchip2 ;;
3468 + *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
3469 + *69?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
3472 + if test x"$ax_gcc_arch" = x; then # fallback
3474 + i586*) ax_gcc_arch=pentium ;;
3475 + i686*) ax_gcc_arch=pentiumpro ;;
3481 + AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
3482 + cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
3483 + cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters`
3485 + *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
3486 + *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
3487 + *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
3488 + *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
3489 + *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
3490 + *cypress*) ax_gcc_arch=cypress ;;
3493 + alphaev5) ax_gcc_arch=ev5 ;;
3494 + alphaev56) ax_gcc_arch=ev56 ;;
3495 + alphapca56) ax_gcc_arch="pca56 ev56" ;;
3496 + alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
3497 + alphaev6) ax_gcc_arch=ev6 ;;
3498 + alphaev67) ax_gcc_arch=ev67 ;;
3499 + alphaev68) ax_gcc_arch="ev68 ev67" ;;
3500 + alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
3501 + alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
3502 + alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
3505 + cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | sed 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
3506 + cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
3508 + *750*) ax_gcc_arch="750 G3" ;;
3509 + *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
3510 + *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
3511 + *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
3512 + *970*) ax_gcc_arch="970 G5 power4";;
3513 + *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
3514 + *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
3515 + 603ev|8240) ax_gcc_arch="$cputype 603e 603";;
3516 + *) ax_gcc_arch=$cputype ;;
3518 + ax_gcc_arch="$ax_gcc_arch powerpc"
3521 +fi # not cross-compiling
3524 +if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
3525 +for arch in $ax_gcc_arch; do
3526 + if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
3527 + flags="-mtune=$arch"
3528 + # -mcpu=$arch and m$arch generate nonportable code on every arch except
3529 + # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr.
3530 + case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac
3532 + flags="-march=$arch -mcpu=$arch -m$arch"
3534 + for flag in $flags; do
3535 + AX_CHECK_COMPILER_FLAGS($flag, [ax_cv_gcc_archflag=$flag; break])
3537 + test "x$ax_cv_gcc_archflag" = xunknown || break
3543 +AC_MSG_CHECKING([for gcc architecture flag])
3544 +AC_MSG_RESULT($ax_cv_gcc_archflag)
3545 +if test "x$ax_cv_gcc_archflag" = xunknown; then
3546 + m4_default([$3],:)
3548 + m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
3551 diff --git a/m4/ax_gcc_x86_cpuid.m4 b/m4/ax_gcc_x86_cpuid.m4
3552 new file mode 100644
3553 index 0000000..5420b09
3555 +++ b/m4/ax_gcc_x86_cpuid.m4
3557 +# ===========================================================================
3558 +# http://www.nongnu.org/autoconf-archive/ax_gcc_x86_cpuid.html
3559 +# ===========================================================================
3563 +# AX_GCC_X86_CPUID(OP)
3567 +# On Pentium and later x86 processors, with gcc or a compiler that has a
3568 +# compatible syntax for inline assembly instructions, run a small program
3569 +# that executes the cpuid instruction with input OP. This can be used to
3570 +# detect the CPU type.
3572 +# On output, the values of the eax, ebx, ecx, and edx registers are stored
3573 +# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
3574 +# ax_cv_gcc_x86_cpuid_OP.
3576 +# If the cpuid instruction fails (because you are running a
3577 +# cross-compiler, or because you are not using gcc, or because you are on
3578 +# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP
3579 +# is set to the string "unknown".
3581 +# This macro mainly exists to be used in AX_GCC_ARCHFLAG.
3585 +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
3586 +# Copyright (c) 2008 Matteo Frigo
3588 +# This program is free software: you can redistribute it and/or modify it
3589 +# under the terms of the GNU General Public License as published by the
3590 +# Free Software Foundation, either version 3 of the License, or (at your
3591 +# option) any later version.
3593 +# This program is distributed in the hope that it will be useful, but
3594 +# WITHOUT ANY WARRANTY; without even the implied warranty of
3595 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
3596 +# Public License for more details.
3598 +# You should have received a copy of the GNU General Public License along
3599 +# with this program. If not, see <http://www.gnu.org/licenses/>.
3601 +# As a special exception, the respective Autoconf Macro's copyright owner
3602 +# gives unlimited permission to copy, distribute and modify the configure
3603 +# scripts that are the output of Autoconf when processing the Macro. You
3604 +# need not follow the terms of the GNU General Public License when using
3605 +# or distributing such scripts, even though portions of the text of the
3606 +# Macro appear in them. The GNU General Public License (GPL) does govern
3607 +# all other use of the material that constitutes the Autoconf Macro.
3609 +# This special exception to the GPL applies to versions of the Autoconf
3610 +# Macro released by the Autoconf Archive. When you make and distribute a
3611 +# modified version of the Autoconf Macro, you may extend this special
3612 +# exception to the GPL to apply to your modified version as well.
3614 +AC_DEFUN([AX_GCC_X86_CPUID],
3615 +[AC_REQUIRE([AC_PROG_CC])
3617 +AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
3618 + [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
3619 + int op = $1, eax, ebx, ecx, edx;
3622 + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
3624 + f = fopen("conftest_cpuid", "w"); if (!f) return 1;
3625 + fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
3629 + [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
3630 + [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
3631 + [ax_cv_gcc_x86_cpuid_$1=unknown])])
3634 diff --git a/m4/ax_submodule.m4 b/m4/ax_submodule.m4
3635 new file mode 100644
3636 index 0000000..57e3a56
3638 +++ b/m4/ax_submodule.m4
3640 +AC_DEFUN([AX_SUBMODULE],
3644 + [AS_HELP_STRING([--with-$1=$2],
3645 + [Which $1 to use])])
3648 + AC_ARG_WITH($1_prefix,
3649 + [AS_HELP_STRING([--with-$1-prefix=DIR],
3650 + [Prefix of $1 installation])])
3651 + AC_ARG_WITH($1_exec_prefix,
3652 + [AS_HELP_STRING([--with-$1-exec-prefix=DIR],
3653 + [Exec prefix of $1 installation])])
3657 + AC_ARG_WITH($1_builddir,
3658 + [AS_HELP_STRING([--with-$1-builddir=DIR],
3659 + [Location of $1 builddir])])
3661 +if test "x$with_$1_prefix" != "x" -a "x$with_$1_exec_prefix" = "x"; then
3662 + with_$1_exec_prefix=$with_$1_prefix
3664 +if test "x$with_$1_prefix" != "x" -o "x$with_$1_exec_prefix" != "x"; then
3665 + if test "x$with_$1" != "x" -a "x$with_$1" != "xsystem"; then
3666 + AC_MSG_ERROR([Setting $with_$1_prefix implies use of system $1])
3670 +if test "x$with_$1_builddir" != "x"; then
3671 + if test "x$with_$1" != "x" -a "x$with_$1" != "xbuild"; then
3672 + AC_MSG_ERROR([Setting $with_$1_builddir implies use of build $1])
3675 + $1_srcdir=`echo @abs_srcdir@ | $with_$1_builddir/config.status --file=-`
3676 + AC_MSG_NOTICE($1 sources in $$1_srcdir)
3682 + if test -d $srcdir/.git -a \
3683 + -d $srcdir/$1 -a \
3684 + ! -d $srcdir/$1/.git; then
3686 +[git repo detected, but submodule $1 not initialized])
3687 + AC_MSG_WARN([You may want to run])
3688 + AC_MSG_WARN([ git submodule init])
3689 + AC_MSG_WARN([ git submodule update])
3690 + AC_MSG_WARN([ sh autogen.sh])
3692 + if test -f $srcdir/$1/configure -a "$3" != "no"; then
3699 +AC_MSG_CHECKING([which $1 to use])
3700 +AC_MSG_RESULT($with_$1)
3703 diff --git a/osl b/osl
3704 new file mode 160000
3705 index 0000000..46ef4ec
3709 +Subproject commit 46ef4ec9917713d5d51dd45331c0e74870c5375d
3710 diff --git a/piplib b/piplib
3711 new file mode 160000
3712 index 0000000..f2cfdd3
3716 +Subproject commit f2cfdd3f7a7c4c0c4f7408437205fa27bfb041ba
3717 diff --git a/redo.sh b/redo.sh
3718 new file mode 100755
3719 index 0000000..a1cdb50
3724 +make maintainer-clean
3725 +#./get_submodules.sh
3728 + --prefix=$HOME/usr \
3729 + --with-osl=system \
3730 + --with-osl-prefix=$HOME/usr \
3731 + --with-piplib=system \
3732 + --with-piplib-prefix=$HOME/usr
3735 diff --git a/source/Makefile.am b/source/Makefile.am
3736 deleted file mode 100644
3737 index 3909be1..0000000
3738 --- a/source/Makefile.am
3742 -# /**-------------------------------------------------------------------**
3744 -# **-------------------------------------------------------------------**
3745 -# ** Makefile.am **
3746 -# **-------------------------------------------------------------------**
3747 -# ** First version: september 8th 2003 **
3748 -# **-------------------------------------------------------------------**/
3750 -#/*****************************************************************************
3751 -# * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
3752 -# *****************************************************************************
3754 -# * Copyright (C) 2003-2008 Cedric Bastoul *
3756 -# * This is free software; you can redistribute it and/or modify it under the *
3757 -# * terms of the GNU General Public License as published by the Free Software *
3758 -# * Foundation; either version 2 of the License, or (at your option) any *
3759 -# * later version. *
3761 -# * This software is distributed in the hope that it will be useful, but *
3762 -# * WITHOUT ANY WARRANTY; without even the implied warranty of *
3763 -# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
3764 -# * Public License for more details. *
3766 -# * You should have received a copy of the GNU General Public License along *
3767 -# * with software; if not, write to the Free Software Foundation, Inc., *
3768 -# * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
3770 -# * CAnDL, the Chunky Dependence Analyser *
3771 -# * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
3773 -# *****************************************************************************/
3776 -#############################################################################
3779 -#############################################################################
3780 -MAINTAINERCLEANFILES = Makefile.in
3782 -INCLUDES = -I$(top_builddir) -I$(top_srcdir) \
3783 - -I$(top_builddir)/include \
3784 - -I$(top_srcdir)/include
3786 -#############################################################################
3788 -lib_LTLIBRARIES = libcandl.la
3791 -libcandl_la_SOURCES = \
3797 - piplib-wrapper.c \
3803 -AM_CFLAGS = -Wall -fomit-frame-pointer -g
3806 -bin_PROGRAMS = candl
3808 -LDADD = libcandl.la
3810 -candl_SOURCES = candl.c
3811 diff --git a/source/candl.c b/source/candl.c
3812 index 27e8ca4..df6bf18 100644
3813 --- a/source/candl.c
3814 +++ b/source/candl.c
3816 **---- \#/ --------------------------------------------------------**
3817 ** .-"#'-. First version: september 8th 2003 **
3818 **--- |"-.-"| -------------------------------------------------------**
3823 ******** | | *************************************************************
3824 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
3825 ******************************************************************************
3826 @@ -33,98 +33,162 @@
3828 ******************************************************************************/
3833 -#include <candl/candl.h>
3834 +#include <osl/scop.h>
3835 +#include <osl/macros.h>
3836 +#include <osl/util.h>
3837 +#include <osl/extensions/dependence.h>
3838 +#include <candl/macros.h>
3839 #include <candl/dependence.h>
3840 -#include <candl/program.h>
3841 #include <candl/violation.h>
3842 #include <candl/options.h>
3843 +#include <candl/scop.h>
3844 +#include <candl/util.h>
3845 +#include <candl/piplib.h>
3848 -int main(int argc, char * argv[])
3850 - CandlProgram * program = NULL;
3851 - CandlOptions * options;
3852 - CandlDependence * dependence;
3853 - CandlViolation * violation = NULL;
3854 - FILE * input, * output;
3855 +int main(int argc, char * argv[]) {
3857 + osl_scop_p scop = NULL;
3858 + osl_scop_p orig_scop = NULL;
3859 + osl_dependence_p dep = NULL;
3860 + int num_scops = 0, i= 0;
3861 + candl_options_p options;
3862 + candl_violation_p *violations = NULL;
3863 + FILE *input, *output, *input_test;
3865 + #if defined(CANDL_LINEAR_VALUE_IS_INT)
3866 + precision = OSL_PRECISION_SP;
3867 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
3868 + precision = OSL_PRECISION_DP;
3869 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
3870 + precision = OSL_PRECISION_MP;
3873 /* Options and input/output file setting. */
3874 - candl_options_read(argc, argv, &input, &output, &options);
3876 - /* Reading the program informations. */
3877 -#ifdef CANDL_SUPPORTS_SCOPLIB
3878 - if (options->readscop)
3880 - program = candl_program_read_scop(input);
3881 - if (options->scoptocandl)
3883 - if (! options->readscop)
3884 - program = candl_program_read_scop(input);
3885 - candl_program_print_candl_file(output, program);
3886 - candl_program_free(program);
3887 - candl_options_free(options);
3893 - program = candl_program_read(input);
3895 + candl_options_read(argc, argv, &input, &output, &input_test, &options);
3898 + * If there is no original scop (given with the -test), the input file
3899 + * is considered as the original scop
3901 + osl_interface_p registry = osl_interface_get_default_registry();
3902 + if (input_test != NULL) {
3903 + scop = osl_scop_pread(input, registry, precision);
3904 + orig_scop = osl_scop_pread(input_test, registry, precision);
3906 + orig_scop = osl_scop_pread(input, registry, precision);
3908 + osl_interface_free(registry);
3910 + if (orig_scop == NULL || (scop == NULL && input_test != NULL)) {
3911 + CANDL_error("Fail to open scop");
3915 + /* Check if we can compare the two scop
3916 + * The function compare only domains and access arrays
3918 + if (input_test != NULL && !candl_util_check_scop_list(orig_scop, scop))
3919 + CANDL_error("The two scop lists can't be compared");
3921 + /* Add more infos (depth, label, ...)
3922 + * Not important for the transformed scop
3923 + * TODO : the statements must be sorted to compute the statement label
3924 + * the problem is if the scop is reordered, the second transformed scop
3925 + * must be aligned with it
3927 + candl_scop_usr_init(orig_scop);
3929 /* Calculating dependences. */
3930 - dependence = candl_dependence(program, options);
3931 + candl_dependence_add_extension(orig_scop, options);
3933 + osl_scop_p s1 = orig_scop;
3934 + while (s1) {num_scops++; s1 = s1->next;}
3937 + osl_scop_p s2 = scop;
3938 /* Calculating legality violations. */
3939 - if (options->violgraph)
3940 - violation = candl_violation(program, dependence, options);
3941 + if (input_test != NULL) {
3942 + CANDL_malloc(violations, candl_violation_p*, num_scops);
3944 - /* Printing data structures if asked. */
3945 - if (options->structure)
3947 - fprintf(output, "Program:\n");
3948 - candl_program_print(output, program);
3949 - fprintf(output, "\nDependences:\n");
3950 - candl_dependence_print(output, dependence);
3951 - fprintf(output, "\nViolations:\n");
3952 - candl_violation_print(output, violation);
3953 + for (i=0; i< num_scops; i++, s1 = s1->next, s2 = s2->next) {
3954 + dep = osl_generic_lookup(s1->extension,
3955 + OSL_URI_DEPENDENCE);
3956 + violations[i] = candl_violation(s1, dep, s2, options);
3960 + /* Printing data structures if asked. */
3961 + if (options->structure) {
3963 + if (input_test != NULL) {
3964 + s1=orig_scop; s2=scop;
3965 + for (i=0; i< num_scops; i++, s1=s1->next, s2=s2->next) {
3966 + fprintf(output, "\033[33mORIGINAL SCOP:\033[00m\n");
3967 + osl_scop_print(output, s1);
3968 + fprintf(output, "\n\033[33mTRANSFORMED SCOP:\033[00m\n");
3969 + osl_scop_print(output, s2);
3971 -#ifdef CANDL_SUPPORTS_SCOPLIB
3972 - if (options->readscop && options->writescop)
3973 - candl_dependence_print_scop (input, output, dependence);
3977 - /* Printing dependence graph if asked or if there is no transformation. */
3978 - if (options->depgraph || (program->transformation == NULL))
3980 - candl_dependence_pprint(output, dependence);
3981 - if (options->view)
3982 - candl_dependence_view(dependence);
3984 - /* Printing violation graph if asked and if there is a transformation. */
3985 - if (options->violgraph && (program->transformation != NULL))
3987 - candl_violation_pprint(output, violation);
3988 - if (options->view)
3989 - candl_violation_view(violation);
3991 + dep = osl_generic_lookup(s1->extension, OSL_URI_DEPENDENCE);
3992 + fprintf(output, "\n\033[33mDEPENDENCES GRAPH:\033[00m\n");
3993 + candl_dependence_pprint(output, dep);
3994 + fprintf(output, "\n\n\033[33mVIOLATIONS GRAPH:\033[00m\n");
3995 + candl_violation_pprint(output, violations[i]);
3999 + for (i=0; i< num_scops; i++, s1=s1->next) {
4000 + fprintf(output, "\033[33mORIGINAL SCOP:\033[00m\n");
4001 + osl_scop_print(output, s1);
4003 -#ifdef CANDL_SUPPORTS_SCOPLIB
4004 + dep = osl_generic_lookup(s1->extension, OSL_URI_DEPENDENCE);
4005 + fprintf(output, "\n\033[33mDEPENDENCES GRAPH:\033[00m\n");
4006 + candl_dependence_pprint(output, dep);
4011 + } else if (input_test != NULL) {
4012 + /* Printing violation graph */
4013 + for (i=0; i< num_scops; i++) {
4014 + candl_violation_pprint(output, violations[i]);
4015 + if (options->view)
4016 + candl_violation_view(violations[i]);
4018 + } else if (options->outscop) {
4019 + /* Export to the scop format */
4021 + osl_scop_print(output, s1); //prints list
4023 + /* Printing dependence graph if asked or if there is no transformation. */
4025 + for(i=0; i< num_scops; i++, s1=s1->next){
4026 + dep = osl_generic_lookup(s1->extension, OSL_URI_DEPENDENCE);
4027 + fprintf(output, "\033[33mSCOP #%d:\033[00m\n", i+1);
4028 + candl_dependence_pprint(output, dep);
4029 + fprintf(output, "\n");
4030 + if (options->view)
4031 + candl_dependence_view(dep);
4036 - candl_violation_free(violation);
4037 - candl_dependence_free(dependence);
4038 - candl_program_free(program);
4039 + if (input_test != NULL) {
4040 + for (i=0; i< num_scops; i++)
4041 + candl_violation_free(violations[i]);
4042 + osl_scop_free(scop);
4043 + fclose(input_test);
4046 + // the dependence is freed with the scop
4047 + //osl_dependence_free(orig_dependence);
4048 candl_options_free(options);
4050 + candl_scop_usr_cleanup(orig_scop);
4051 + osl_scop_free(orig_scop);
4059 diff --git a/source/ddv.c b/source/ddv.c
4060 index 8ac06f5..7220198 100644
4064 **---- \#/ --------------------------------------------------------**
4065 ** .-"#'-. First version: February 4th 2010 **
4066 **--- |"-.-"| -------------------------------------------------------**
4071 ******** | | *************************************************************
4072 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
4073 ******************************************************************************
4078 -#include <candl/candl.h>
4082 +#include <osl/statement.h>
4083 +#include <osl/scop.h>
4084 +#include <osl/extensions/dependence.h>
4085 +#include <candl/macros.h>
4086 +#include <candl/ddv.h>
4087 +#include <candl/statement.h>
4088 +#include <candl/piplib.h>
4089 #include <candl/piplib-wrapper.h>
4093 # define min(x,y) (x < y ? x : y)
4096 # define max(x,y) (x > y ? x : y)
4100 /******************************************************************************
4101 * Memory deallocation function *
4102 ******************************************************************************/
4109 +candl_ddv_malloc() {
4110 CandlDDV* dv = (CandlDDV*) malloc(sizeof(CandlDDV));
4113 @@ -82,19 +85,17 @@ candl_ddv_malloc()
4117 -candl_ddv_alloc(int size)
4119 +candl_ddv_alloc(int size) {
4120 CandlDDV* dv = candl_ddv_malloc();
4122 dv->data = (s_dv_descriptor*) malloc(size * sizeof(s_dv_descriptor));
4126 - for (i = 0; i < size; ++i)
4128 - dv->data[i].type = candl_dv_star;
4129 - dv->data[i].value = 0;
4131 + for (i = 0; i < size; ++i) {
4132 + dv->data[i].type = candl_dv_star;
4133 + dv->data[i].value = 0;
4138 @@ -106,19 +107,17 @@ candl_ddv_alloc(int size)
4142 -candl_ddv_free(CandlDDV* dv)
4144 +candl_ddv_free(CandlDDV* dv) {
4148 - for (tmp = dv; tmp; )
4156 + for (tmp = dv; tmp; ) {
4166 @@ -130,8 +129,7 @@ candl_ddv_free(CandlDDV* dv)
4170 -candl_ddv_set_type_at(CandlDDV* dv, e_dv_type type, int pos)
4172 +candl_ddv_set_type_at(CandlDDV* dv, e_dv_type type, int pos) {
4173 dv->data[pos].type = type;
4176 @@ -143,19 +141,17 @@ candl_ddv_set_type_at(CandlDDV* dv, e_dv_type type, int pos)
4180 -candl_ddv_set_value_at(CandlDDV* dv, int value, int pos)
4182 +candl_ddv_set_value_at(CandlDDV* dv, int value, int pos) {
4183 dv->data[pos].value = value;
4187 * candl_ddv_set_type: Set the type of the dependence in
4188 - * CANDL_UNSET, CANDL_RAW, CANDL_WAR, CANDL_WAW, CANDL_RAR.
4189 + * CANDL_UNDEFINED, CANDL_RAW, CANDL_WAR, CANDL_WAW, CANDL_RAR.
4193 -candl_ddv_set_deptype(CandlDDV* dv, int type)
4195 +candl_ddv_set_deptype(CandlDDV* dv, int type) {
4199 @@ -170,33 +166,30 @@ candl_ddv_set_deptype(CandlDDV* dv, int type)
4203 -candl_ddv_print(FILE* out, CandlDDV* dv)
4207 - fprintf(out, "(null ddv)\n");
4210 +candl_ddv_print(FILE* out, CandlDDV* dv) {
4212 + fprintf(out, "(null ddv)\n");
4217 fprintf(out, "loop_id=%d, (", dv->loop_id);
4218 - for (i = 0; i < dv->length; ++i)
4220 - if (dv->data[i].type == candl_dv_star)
4221 - fprintf(out, "*");
4222 - else if (dv->data[i].type == candl_dv_eq)
4223 - fprintf(out, "=");
4224 - else if (dv->data[i].type == candl_dv_plus)
4225 - fprintf(out, ">");
4226 - else if (dv->data[i].type == candl_dv_minus)
4227 - fprintf(out, "<");
4228 - else if (dv->data[i].type == candl_dv_scalar)
4229 - fprintf(out, "%d", dv->data[i].value);
4230 - if (i < dv->length - 1)
4231 - fprintf(out, ", ");
4233 - fprintf(out, ")\n");
4235 + for (i = 0; i < dv->length; ++i) {
4236 + if (dv->data[i].type == candl_dv_star)
4237 + fprintf(out, "*");
4238 + else if (dv->data[i].type == candl_dv_eq)
4239 + fprintf(out, "=");
4240 + else if (dv->data[i].type == candl_dv_plus)
4241 + fprintf(out, ">");
4242 + else if (dv->data[i].type == candl_dv_minus)
4243 + fprintf(out, "<");
4244 + else if (dv->data[i].type == candl_dv_scalar)
4245 + fprintf(out, "%d", dv->data[i].value);
4246 + if (i < dv->length - 1)
4247 + fprintf(out, ", ");
4249 + fprintf(out, ")\n");
4254 @@ -206,24 +199,11 @@ candl_ddv_print(FILE* out, CandlDDV* dv)
4258 - * Integer emptiness test on a given polyhedron.
4263 -candl_ddv_has_point(CandlMatrix* system)
4265 - return pip_has_rational_point (system, NULL, 1);
4270 * Recursively count the number of leaves in a QUAST.
4274 -int count_quast_leaves(PipQuast* q)
4276 +int count_quast_leaves(PipQuast* q) {
4279 if (q->condition == NULL)
4280 @@ -238,22 +218,19 @@ int count_quast_leaves(PipQuast* q)
4284 -void get_quast_leaves(PipQuast* q, PipList** leaves)
4286 +void get_quast_leaves(PipQuast* q, PipList** leaves) {
4289 - if (q->condition == NULL)
4292 - for (i = 0; leaves[i]; ++i)
4294 - leaves[i] = q->list;
4298 - get_quast_leaves(q->next_else, leaves);
4299 - get_quast_leaves(q->next_then, leaves);
4301 + if (q->condition == NULL) {
4303 + for (i = 0; leaves[i]; ++i)
4305 + leaves[i] = q->list;
4308 + get_quast_leaves(q->next_else, leaves);
4309 + get_quast_leaves(q->next_then, leaves);
4314 @@ -266,15 +243,16 @@ void get_quast_leaves(PipQuast* q, PipList** leaves)
4318 -candl_ddv_constant_val(CandlMatrix* system, int* val, int nb_par)
4320 +candl_ddv_constant_val(osl_relation_p system, int* val, int nb_par) {
4321 PipOptions * options;
4322 PipQuast * solution;
4323 + osl_relation_p context;
4324 int is_constant_val = 1;
4329 + int precision = system->precision;
4331 // 1- Comute the lexmin of the system, to get a QUAST.
4332 options = pip_options_init();
4333 @@ -282,54 +260,51 @@ candl_ddv_constant_val(CandlMatrix* system, int* val, int nb_par)
4334 options->Urs_parms = -1;
4335 options->Urs_unknowns = -1;
4337 - CandlMatrix* context = candl_matrix_malloc(0, nb_par + 2);
4338 - solution = pip_solve(system, context, -1, options);
4340 + context = osl_relation_pmalloc(precision, 0, nb_par + 2);
4341 + solution = pip_solve_osl(system, context, -1, options);
4343 if ((solution != NULL) &&
4344 - ((solution->list != NULL) || (solution->condition != NULL)))
4346 - // 2- Traverse all leaves, ensure they have the same value.
4347 - int nb_leaves = count_quast_leaves(solution);
4348 - PipList* leaveslist[nb_leaves + 1];
4349 - for (i = 0; i < nb_leaves + 1; ++i)
4350 - leaveslist[i] = NULL;
4351 - get_quast_leaves(solution, leaveslist);
4353 - for (i = 0; i < nb_leaves; ++i)
4355 - PipList* list = leaveslist[i];
4356 - if (list && list->vector)
4358 - PipVector* vect = list->vector;
4359 - for (j = 0; j < nb_par; ++j)
4360 - if (CANDL_get_si(vect->the_vector[j]) != 0)
4362 - is_constant_val = 0;
4365 - if (is_constant_val)
4367 - cst = CANDL_get_si(vect->the_vector[vect->nb_elements - 1]);
4373 - else if (! first && cst != cst_base)
4375 - is_constant_val = 0;
4383 + ((solution->list != NULL) || (solution->condition != NULL))) {
4384 + // 2- Traverse all leaves, ensure they have the same value.
4385 + int nb_leaves = count_quast_leaves(solution);
4386 + PipList* leaveslist[nb_leaves + 1];
4387 + for (i = 0; i < nb_leaves + 1; ++i)
4388 + leaveslist[i] = NULL;
4389 + get_quast_leaves(solution, leaveslist);
4391 + for (i = 0; i < nb_leaves; ++i) {
4392 + PipList* list = leaveslist[i];
4393 + if (list && list->vector) {
4394 + PipVector* vect = list->vector;
4396 + // FIXME : check if precision is correct to use piplib
4398 + for (j = 0; j < nb_par; ++j)
4399 + if (!CANDL_zero_p(vect->the_vector[j])) {
4400 + is_constant_val = 0;
4403 + if (is_constant_val) {
4404 + cst = CANDL_get_si(vect->the_vector[vect->nb_elements-1]);
4409 + else if (! first && cst != cst_base) {
4410 + is_constant_val = 0;
4420 pip_quast_free(solution);
4421 pip_options_free(options);
4422 - candl_matrix_free(context);
4423 + osl_relation_free(context);
4425 if (is_constant_val)
4427 @@ -345,98 +320,97 @@ candl_ddv_constant_val(CandlMatrix* system, int* val, int nb_par)
4431 -candl_ddv_create_from_dep(CandlDependence* dep, int loop_id, int ddv_size)
4433 +candl_ddv_create_from_dep(osl_dependence_p dep, int loop_id, int ddv_size) {
4434 + osl_relation_p mat = dep->domain;
4435 + osl_statement_p src = dep->stmt_source_ptr;
4436 + candl_statement_usr_p usr = src->usr;
4437 + CandlDDV* dv = candl_ddv_alloc(ddv_size);
4438 + int precision = src->domain->precision;
4441 - CandlMatrix* mat = dep->domain;
4442 - CandlStatement* src = dep->source;
4443 - CandlDDV* dv = candl_ddv_alloc(ddv_size);
4445 dv->loop_id = loop_id;
4446 dv->deptype = dep->type;
4448 // Create the template of the system to operate on.
4449 // Add one dimension at the beginning, and one row for the extra constraint.
4450 - int nb_par = src->domain->NbColumns - 2 - src->depth;
4451 - CandlMatrix* testsyst =
4452 - candl_matrix_malloc(mat->NbRows + 1, mat->NbColumns + 1);
4453 - for (pos = 0; pos < mat->NbRows; ++pos)
4455 - CANDL_assign(testsyst->p[pos][0], mat->p[pos][0]);
4456 - for (j = 1; j < mat->NbColumns; ++j)
4457 - CANDL_assign(testsyst->p[pos][j + 1], mat->p[pos][j]);
4459 + int nb_par = src->domain->nb_parameters;
4460 + osl_relation_p testsyst = osl_relation_pmalloc(precision,
4462 + mat->nb_columns + 1);
4463 + for (pos = 0; pos < mat->nb_rows; ++pos) {
4464 + osl_int_assign(precision, &testsyst->m[pos][0], mat->m[pos][0]);
4465 + for (j = 1; j < mat->nb_columns; ++j)
4466 + osl_int_assign(precision, &testsyst->m[pos][j + 1],mat->m[pos][j]);
4469 int has_eq, has_pos, has_neg, has_cst;
4471 - for (i = 1; i <= ddv_size; ++i)
4474 - CANDL_set_si(testsyst->p[pos][0], 0);
4475 - CANDL_set_si(testsyst->p[pos][1 + i], 1);
4476 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
4477 - CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0);
4478 - has_eq = candl_ddv_has_point(testsyst);
4481 - CANDL_set_si(testsyst->p[pos][0], 1);
4482 - CANDL_set_si(testsyst->p[pos][1 + i], 1);
4483 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
4484 - CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1);
4485 - has_pos = candl_ddv_has_point(testsyst);
4488 - CANDL_set_si(testsyst->p[pos][0], 1);
4489 - CANDL_set_si(testsyst->p[pos][1 + i], -1);
4490 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1);
4491 - CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1);
4492 - has_neg = candl_ddv_has_point(testsyst);
4494 - // Test for constant distance.
4495 - // min(x_R^i - x_S^i)
4496 - // max(x_R^i - x_S^i) = - min(- x_R^i + x_S^i)
4497 - CANDL_set_si(testsyst->p[pos][0], 0);
4498 - CANDL_set_si(testsyst->p[pos][1], 1);
4499 - CANDL_set_si(testsyst->p[pos][1 + i], -1);
4500 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1);
4501 - CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0);
4502 - has_cst = candl_ddv_constant_val(testsyst, &scal1, nb_par);
4504 + for (i = 1; i <= ddv_size; ++i) {
4506 + osl_int_set_si(precision, &testsyst->m[pos][0], 0);
4507 + osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1);
4508 + osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1);
4509 + osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0);
4510 + has_eq = pip_has_rational_point(testsyst, NULL, 1);
4513 + osl_int_set_si(precision, &testsyst->m[pos][0], 1);
4514 + osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1);
4515 + osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1);
4516 + osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1);
4517 + has_pos = pip_has_rational_point(testsyst, NULL, 1);
4520 + osl_int_set_si(precision, &testsyst->m[pos][0], 1);
4521 + osl_int_set_si(precision, &testsyst->m[pos][1 + i], -1);
4522 + osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 1);
4523 + osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1);
4524 + has_neg = pip_has_rational_point(testsyst, NULL, 1);
4526 + // Test for constant distance.
4527 + // min(x_R^i - x_S^i)
4528 + // max(x_R^i - x_S^i) = - min(- x_R^i + x_S^i)
4529 + osl_int_set_si(precision, &testsyst->m[pos][0], 0);
4530 + osl_int_set_si(precision, &testsyst->m[pos][1], 1);
4531 + osl_int_set_si(precision, &testsyst->m[pos][1 + i], -1);
4532 + osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 1);
4533 + osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0);
4534 + has_cst = candl_ddv_constant_val(testsyst, &scal1, nb_par);
4537 + osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1);
4538 + osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1);
4539 + osl_int_set_si(precision, &testsyst->m[pos][1], 1);
4540 + has_cst = candl_ddv_constant_val(testsyst, &scal2, nb_par);
4544 - CANDL_set_si(testsyst->p[pos][1 + i], 1);
4545 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
4546 - CANDL_set_si(testsyst->p[pos][1], 1);
4547 - has_cst = candl_ddv_constant_val(testsyst, &scal2, nb_par);
4550 - has_cst = (scal1 == scal2);
4553 - if (has_cst && scal1 != 0)
4555 - candl_ddv_set_type_at (dv, candl_dv_scalar, i - 1);
4556 - candl_ddv_set_value_at (dv, scal1, i - 1);
4558 - else if (has_pos && has_neg)
4559 - candl_ddv_set_type_at (dv, candl_dv_star, i - 1);
4561 - candl_ddv_set_type_at (dv, candl_dv_plus, i - 1);
4563 - candl_ddv_set_type_at (dv, candl_dv_minus, i - 1);
4566 - candl_ddv_set_type_at (dv, candl_dv_eq, i - 1);
4567 - candl_ddv_set_value_at (dv, 0, i - 1);
4570 - // Reset the constraint.
4571 - CANDL_set_si(testsyst->p[pos][0], 0);
4572 - CANDL_set_si(testsyst->p[pos][1], 0);
4573 - CANDL_set_si(testsyst->p[pos][1 + i], 0);
4574 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 0);
4575 - CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0);
4576 + has_cst = (scal1 == scal2);
4579 + if (has_cst && scal1 != 0) {
4580 + candl_ddv_set_type_at(dv, candl_dv_scalar, i - 1);
4581 + candl_ddv_set_value_at(dv, scal1, i - 1);
4583 + else if (has_pos && has_neg)
4584 + candl_ddv_set_type_at(dv, candl_dv_star, i - 1);
4586 + candl_ddv_set_type_at(dv, candl_dv_plus, i - 1);
4588 + candl_ddv_set_type_at(dv, candl_dv_minus, i - 1);
4589 + else if (has_eq) {
4590 + candl_ddv_set_type_at(dv, candl_dv_eq, i - 1);
4591 + candl_ddv_set_value_at(dv, 0, i - 1);
4594 + // Reset the constraint.
4595 + osl_int_set_si(precision, &testsyst->m[pos][0], 0);
4596 + osl_int_set_si(precision, &testsyst->m[pos][1], 0);
4597 + osl_int_set_si(precision, &testsyst->m[pos][1 + i], 0);
4598 + osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 0);
4599 + osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0);
4605 @@ -449,38 +423,39 @@ candl_ddv_create_from_dep(CandlDependence* dep, int loop_id, int ddv_size)
4609 -candl_ddv_extract_in_loop(CandlProgram* program, CandlDependence* deps,
4612 - CandlDependence* tmp;
4613 +candl_ddv_extract_in_loop(osl_scop_p scop, osl_dependence_p deps,
4615 + osl_dependence_p tmp;
4616 + candl_statement_usr_p src_usr, dst_usr;
4617 CandlDDV* head = NULL;
4618 CandlDDV* last = NULL;
4621 - for (tmp = deps; tmp; tmp = tmp->next)
4623 - CandlStatement* src = tmp->source;
4624 - CandlStatement* dst = tmp->target;
4626 - // Iterate on all dependences that lie within the given loop.
4627 - for (i = 0; i < min(src->depth, dst->depth); ++i)
4628 - if (src->index[i] == dst->index[i] && dst->index[i] == loop_id)
4630 - if (i == min(src->depth, dst->depth))
4632 - // The dependence involves statement carried by the loop.
4633 - // Convert it into dependence vector.
4634 - CandlDDV* dv = candl_ddv_create_from_dep(tmp, loop_id, i + 1);
4636 - // Append the dependence vector to the list.
4644 + for (tmp = deps; tmp; tmp = tmp->next) {
4645 + osl_statement_p src = tmp->stmt_source_ptr;
4646 + osl_statement_p dst = tmp->stmt_target_ptr;
4647 + src_usr = src->usr;
4648 + dst_usr = dst->usr;
4650 + // Iterate on all dependences that lie within the given loop.
4651 + for (i = 0; i < min(src_usr->depth, dst_usr->depth); ++i)
4652 + if (src_usr->index[i] == dst_usr->index[i] &&
4653 + dst_usr->index[i] == loop_id)
4655 + if (i == min(src_usr->depth, dst_usr->depth))
4657 + // The dependence involves statement carried by the loop.
4658 + // Convert it into dependence vector.
4659 + CandlDDV* dv = candl_ddv_create_from_dep(tmp, loop_id, i + 1);
4661 + // Append the dependence vector to the list.
4672 @@ -493,11 +468,10 @@ candl_ddv_extract_in_loop(CandlProgram* program, CandlDependence* deps,
4676 -candl_loops_are_permutable(CandlProgram* program, CandlDependence* deps,
4677 - int loop_id1, int loop_id2)
4679 - CandlDDV* l1 = candl_ddv_extract_in_loop (program, deps, loop_id1);
4680 - CandlDDV* l2 = candl_ddv_extract_in_loop (program, deps, loop_id2);
4681 +candl_loops_are_permutable(osl_scop_p scop, osl_dependence_p deps,
4682 + int loop_id1, int loop_id2) {
4683 + CandlDDV* l1 = candl_ddv_extract_in_loop(scop, deps, loop_id1);
4684 + CandlDDV* l2 = candl_ddv_extract_in_loop(scop, deps, loop_id2);
4686 // One of the loop do not carry any dependence.
4687 if (l1 == NULL || l2 == NULL)
4688 @@ -511,79 +485,75 @@ candl_loops_are_permutable(CandlProgram* program, CandlDependence* deps,
4690 int loop_dim_1 = -1;
4691 int loop_dim_2 = -1;
4693 - CandlStatement* stm;
4694 - for (j = 0; j < program->nb_statements; ++j)
4696 - stm = program->statement[j];
4697 - for (i = 0; i < stm->depth; ++i)
4698 - if (stm->index[i] == loop_id1)
4700 - else if (stm->index[i] == loop_id2)
4702 - if (loop_dim_1 != -1 && loop_dim_2 != -1)
4706 + candl_statement_usr_p usr;
4707 + osl_statement_p stm = scop->statement;
4708 + for (; stm != NULL; stm = stm->next) {
4710 + for (i = 0; i < usr->depth; ++i)
4711 + if (usr->index[i] == loop_id1)
4713 + else if (usr->index[i] == loop_id2)
4715 + if (loop_dim_1 != -1 && loop_dim_2 != -1)
4724 - for (; dv; dv = dv->next)
4726 - switch (dv->data[loop_dim_1].type)
4728 - case candl_dv_plus:
4731 - case candl_dv_minus:
4734 - case candl_dv_scalar:
4735 - if (dv->data[loop_dim_1].value > 0)
4737 - else if (dv->data[loop_dim_1].value < 0)
4740 - case candl_dv_star:
4746 - switch (dv->data[loop_dim_2].type)
4748 - case candl_dv_plus:
4751 - case candl_dv_minus:
4754 - case candl_dv_scalar:
4755 - if (dv->data[loop_dim_2].value > 0)
4757 - else if (dv->data[loop_dim_2].value < 0)
4760 - case candl_dv_star:
4766 - if ((is_pos_1 && is_neg_1) || (is_pos_2 && is_neg_2) || is_star)
4768 - candl_ddv_free (l1);
4769 - candl_ddv_free (l2);
4772 + for (; dv; dv = dv->next) {
4773 + switch (dv->data[loop_dim_1].type) {
4774 + case candl_dv_plus:
4777 + case candl_dv_minus:
4780 + case candl_dv_scalar:
4781 + if (dv->data[loop_dim_1].value > 0)
4783 + else if (dv->data[loop_dim_1].value < 0)
4786 + case candl_dv_star:
4793 - candl_ddv_free (l1);
4794 - candl_ddv_free (l2);
4797 + switch (dv->data[loop_dim_2].type) {
4798 + case candl_dv_plus:
4801 + case candl_dv_minus:
4804 + case candl_dv_scalar:
4805 + if (dv->data[loop_dim_2].value > 0)
4807 + else if (dv->data[loop_dim_2].value < 0)
4810 + case candl_dv_star:
4816 + if ((is_pos_1 && is_neg_1) || (is_pos_2 && is_neg_2) || is_star) {
4817 + candl_ddv_free(l1);
4818 + candl_ddv_free(l2);
4823 + candl_ddv_free(l1);
4824 + candl_ddv_free(l2);
4827 return ! ((is_pos_1 && is_neg_2) || (is_neg_1 && is_pos_2));
4830 diff --git a/source/dependence.c b/source/dependence.c
4831 index 41afccf..c8a61dc 100644
4832 --- a/source/dependence.c
4833 +++ b/source/dependence.c
4835 **---- \#/ --------------------------------------------------------**
4836 ** .-"#'-. First version: september 18th 2003 **
4837 **--- |"-.-"| -------------------------------------------------------**
4842 ******** | | *************************************************************
4843 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
4844 ******************************************************************************
4849 -#include <candl/candl.h>
4851 -#include <candl/piplib-wrapper.h>
4854 +#include <candl/macros.h>
4855 +#include <candl/dependence.h>
4856 +#include <candl/scop.h>
4857 +#include <candl/statement.h>
4858 +#include <candl/util.h>
4859 +#include <candl/matrix.h>
4860 +#include <candl/piplib.h>
4861 +#include <candl/piplib-wrapper.h>
4862 +#include <osl/macros.h>
4863 +#include <osl/scop.h>
4864 +#include <osl/statement.h>
4865 +#include <osl/relation.h>
4866 +#include <osl/extensions/dependence.h>
4868 #ifdef CANDL_SUPPORTS_ISL
4869 # undef Q // Thank you polylib...
4870 @@ -55,154 +64,106 @@
4875 -/******************************************************************************
4876 - * Structure display function *
4877 - ******************************************************************************/
4881 - * candl_dependence_print_structure function:
4882 - * Displays a CandlDependence structure (dependence) into a file (file,
4883 - * possibly stdout) in a way that trends to be understandable without falling
4884 - * in a deep depression or, for the lucky ones, getting a headache... It
4885 - * includes an indentation level (level) in order to work with others
4886 - * print_structure functions.
4887 - * - 18/09/2003: first version.
4888 + * candl_dependence_get_relation_ref_source_in_dep function:
4889 + * This function return the corresponding osl_relation_p of
4892 -void candl_dependence_print_structure(FILE* file,
4893 - candl_dependence_p dependence,
4898 - if (dependence != NULL)
4899 - { /* Go to the right level. */
4900 - for(j=0; j<level; j++)
4901 - fprintf(file, "|\t");
4902 - fprintf(file, "+-- CandlDependence\n");
4905 - { for(j=0; j<level; j++)
4906 - fprintf(file, "|\t");
4907 - fprintf(file, "+-- NULL dependence\n");
4910 - while (dependence != NULL)
4912 - { /* Go to the right level. */
4913 - for(j=0; j<level; j++)
4914 - fprintf(file, "|\t");
4915 - fprintf(file, "| CandlDependence\n");
4920 - /* A blank line. */
4921 - for(j=0; j<=level+1; j++)
4922 - fprintf(file, "|\t");
4923 - fprintf(file, "\n");
4925 - /* Go to the right level and print the type. */
4926 - for(j=0; j<=level; j++)
4927 - fprintf(file, "|\t");
4928 - fprintf(file, "Type: ");
4929 - switch (dependence->type)
4931 - case CANDL_UNSET : fprintf(file, "UNSET\n"); break;
4932 - case CANDL_RAW : fprintf(file, "RAW (flow)\n"); break;
4933 - case CANDL_WAR : fprintf(file, "WAR (anti)\n"); break;
4934 - case CANDL_WAW : fprintf(file, "WAW (output)\n"); break;
4935 - case CANDL_RAR : fprintf(file, "RAR (input)\n"); break;
4936 - case CANDL_RAW_SCALPRIV : fprintf(file, "RAW_SCALPRIV (scalar priv)\n"); break;
4937 - default : fprintf(file, "unknown\n"); break;
4940 - /* A blank line. */
4941 - for(j=0; j<=level+1; j++)
4942 - fprintf(file, "|\t");
4943 - fprintf(file, "\n");
4945 - /* Go to the right level and print the depth. */
4946 - for(j=0; j<=level; j++)
4947 - fprintf(file, "|\t");
4948 - fprintf(file, "Depth: %d\n", dependence->depth);
4950 - /* A blank line. */
4951 - for(j=0; j<=level+1; j++)
4952 - fprintf(file, "|\t");
4953 - fprintf(file, "\n");
4955 - /* Print the source statement. */
4956 - candl_statement_print_structure(file, dependence->source, level+1);
4958 - /* Print the target statement. */
4959 - candl_statement_print_structure(file, dependence->target, level+1);
4961 - /* Print the dependence polyhedron. */
4962 - candl_matrix_print_structure(file, dependence->domain, level+1);
4964 - dependence = dependence->next;
4967 - if (dependence != NULL)
4968 - { for (j=0; j<=level; j++)
4969 - fprintf(file, "|\t");
4970 - fprintf(file, "V\n");
4974 +candl_dependence_get_relation_ref_source_in_dep(osl_dependence_p tmp) {
4975 + if (tmp->ref_source_access_ptr != NULL)
4976 + return tmp->ref_source_access_ptr;
4978 + osl_relation_p elt = NULL;
4979 + osl_relation_list_p access;
4980 + access = tmp->stmt_source_ptr->access;
4981 + for (; access != NULL ; access = access->next) {
4982 + elt = access->elt;
4983 + if (count == tmp->ref_source)
4987 + tmp->ref_source_access_ptr = elt;
4991 - /* The last line. */
4992 - for(j=0; j<=level; j++)
4993 - fprintf(file, "|\t");
4994 - fprintf(file, "\n");
4996 + * candl_dependence_get_relation_ref_target_in_dep function:
4997 + * same as candl_dependence_get_relation_ref_source_in_dep but for the target
5000 +candl_dependence_get_relation_ref_target_in_dep(osl_dependence_p tmp) {
5001 + if (tmp->ref_target_access_ptr != NULL)
5002 + return tmp->ref_target_access_ptr;
5004 + osl_relation_list_p access;
5005 + osl_relation_p elt = NULL;
5006 + access = tmp->stmt_target_ptr->access;
5007 + for (; access != NULL ; access = access->next) {
5008 + elt = access->elt;
5009 + if (count == tmp->ref_target)
5013 + tmp->ref_target_access_ptr = elt;
5018 -/* candl_dependence_print function:
5019 - * This function prints the content of a CandlDependence structure (dependence)
5020 - * into a file (file, possibly stdout).
5023 + * candl_dependence_get_array_refs_in_dep function:
5024 + * This function return the array indices referenced in the
5027 -void candl_dependence_print(FILE * file, candl_dependence_p dependence)
5029 - candl_dependence_print_structure(file, dependence, 0);
5030 +void candl_dependence_get_array_refs_in_dep(osl_dependence_p tmp,
5031 + int* refs, int* reft) {
5035 + osl_relation_p src, targ;
5037 + src = candl_dependence_get_relation_ref_source_in_dep(tmp);
5038 + targ = candl_dependence_get_relation_ref_target_in_dep(tmp);
5040 + *refs = osl_relation_get_array_id(src);
5042 + *reft = osl_relation_get_array_id(targ);
5046 -/* candl_dependence_pprint function:
5047 - * This function prints the content of a CandlDependence structure (dependence)
5048 +/* osl_dependence_pprint function:
5049 + * This function prints the content of a osl_dependence_p structure (dependence)
5050 * into a file (file, possibly stdout) as a Graphviz input file.
5051 * See http://www.graphviz.org
5052 * - 08/12/2005: first version.
5054 -void candl_dependence_pprint(FILE * file, candl_dependence_p dependence)
5056 +void candl_dependence_pprint(FILE * file, osl_dependence_p dependence) {
5060 fprintf(file, "digraph G {\n");
5062 fprintf(file, "# Data Dependence Graph\n");
5063 fprintf(file, "# Generated by Candl "CANDL_RELEASE" "CANDL_VERSION" bits\n");
5064 - while (dependence != NULL)
5066 - fprintf(file, " S%d -> S%d [label=\" ", dependence->source->label,
5067 - dependence->target->label);
5068 - switch (dependence->type)
5070 - case CANDL_UNSET : fprintf(file, "UNSET"); break;
5071 - case CANDL_RAW : fprintf(file, "RAW") ; break;
5072 - case CANDL_WAR : fprintf(file, "WAR") ; break;
5073 - case CANDL_WAW : fprintf(file, "WAW") ; break;
5074 - case CANDL_RAR : fprintf(file, "RAR") ; break;
5075 - case CANDL_RAW_SCALPRIV : fprintf(file, "RAW_SCALPRIV (scalar-priv)") ; break;
5076 - default : fprintf(file, "unknown"); break;
5078 - fprintf(file, " depth %d, ref %d->%d \"];\n", dependence->depth,
5079 - dependence->ref_source,
5080 - dependence->ref_target);
5081 - dependence = dependence->next;
5083 + while (dependence != NULL) {
5084 + fprintf(file, " S%d -> S%d [label=\" ", dependence->label_source,
5085 + dependence->label_target);
5086 + switch (dependence->type) {
5087 + case OSL_UNDEFINED : fprintf(file, "UNSET"); break;
5088 + case OSL_DEPENDENCE_RAW : fprintf(file, "RAW") ; break;
5089 + case OSL_DEPENDENCE_WAR : fprintf(file, "WAR") ; break;
5090 + case OSL_DEPENDENCE_WAW : fprintf(file, "WAW") ; break;
5091 + case OSL_DEPENDENCE_RAR : fprintf(file, "RAR") ; break;
5092 + case OSL_DEPENDENCE_RAW_SCALPRIV :
5093 + fprintf(file, "RAW_SCALPRIV (scalar-priv)") ; break;
5094 + default : fprintf(file, "unknown"); break;
5096 + fprintf(file, " depth %d, ref %d->%d \"];\n", dependence->depth,
5097 + dependence->ref_source,
5098 + dependence->ref_target);
5099 + dependence = dependence->next;
5104 fprintf(file, "# Number of edges = %i\n}\n", i);
5105 @@ -217,135 +178,25 @@ void candl_dependence_pprint(FILE * file, candl_dependence_p dependence)
5107 * - 20/03/2006: first version.
5109 -void candl_dependence_view(candl_dependence_p dependence)
5111 +void candl_dependence_view(osl_dependence_p dep) {
5114 - temp_output = fopen(CANDL_TEMP_OUTPUT, "w");
5115 - candl_dependence_pprint(temp_output, dependence);
5116 + temp_output = fopen(CANDL_TEMP_OUTPUT,"w+");
5117 + candl_dependence_pprint(temp_output, dep);
5118 fclose(temp_output);
5119 - system("(dot -Tps "CANDL_TEMP_OUTPUT" | gv - &) && rm -f "CANDL_TEMP_OUTPUT);
5124 - * Returns a string containing the dependence, formatted to fit the
5125 - * .scop representation.
5130 -candl_program_deps_to_string(CandlDependence* dependence)
5132 - CandlDependence* tmp = dependence;
5133 - int refs = 0, reft = 0;
5136 - int buffer_size = 2048;
5138 - char* buffer = (char*) malloc(buffer_size * sizeof(char));
5143 - for (tmp = dependence, nb_deps = 0; tmp; tmp = tmp->next, ++nb_deps)
5144 + /* check the return to remove the warning compilation */
5145 + if(system("dot -Tps "CANDL_TEMP_OUTPUT" | gv - && rm -f "CANDL_TEMP_OUTPUT" &"))
5147 - sprintf(buffer, "# Number of dependences\n%d\n", nb_deps);
5150 - for (tmp = dependence, nb_deps = 1; tmp; tmp = tmp->next, ++nb_deps)
5152 - /* Compute the type of the dependence, and the array id
5154 - switch (tmp->type)
5160 - type = "RAW #(flow)";
5161 - refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
5162 - reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
5165 - type = "WAR #(anti)";
5166 - refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
5167 - reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
5170 - type = "WAW #(output)";
5171 - refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
5172 - reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
5175 - type = "RAR #(input)";
5176 - refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
5177 - reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
5179 - case CANDL_RAW_SCALPRIV:
5180 - type = "RAW_SCALPRIV #(scalar priv)";
5181 - refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
5182 - reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
5188 - /* Quick consistency check. */
5190 - CANDL_FAIL("Internal error. refs != reft\n");
5192 - /* Output dependence information. */
5193 - sprintf(buff, "# Description of dependence %d\n"
5194 - "# type\n%s\n# From statement id\n%d\n"
5195 - "# To statement id\n%d\n# Depth \n%d\n# Array id\n%d\n"
5196 - "# Dependence domain\n%d %d\n", nb_deps, type,
5197 - tmp->source->label, tmp->target->label, tmp->depth,
5198 - refs, tmp->domain->NbRows, tmp->domain->NbColumns);
5199 - strcat(buffer, buff);
5200 - /* Output dependence domain. */
5201 - pbuffer = buffer + strlen(buffer);
5202 - for (i = 0; i < tmp->domain->NbRows; ++i)
5204 - for (j = 0; j < tmp->domain->NbColumns; ++j)
5206 - sprintf(buff, "%lld ", CANDL_get_si(tmp->domain->p[i][j]));
5207 - szbuff = strlen(buff);
5209 - *(pbuffer++) = ' ';
5210 - for (k = 0; k < szbuff; ++k)
5211 - *(pbuffer++) = buff[k];
5213 - *(pbuffer++) = '\n';
5215 - *(pbuffer++) = '\0';
5216 - /* Increase the buffer size if needed. Conservatively assume a
5217 - dependence is never larger than 2k. */
5218 - szbuff = strlen(buffer);
5219 - if (szbuff + 2048 > buffer_size)
5221 - buffer = (char*) realloc(buffer, (buffer_size *= 2) *
5223 - if (buffer == NULL)
5224 - CANDL_FAIL("Error: memory overflow");
5225 - buffer[szbuff] = '\0';
5234 #ifdef CANDL_SUPPORTS_ISL
5237 -isl_set_from_piplib_matrix(struct isl_ctx* ctx,
5238 - PipMatrix* matrix,
5241 -isl_set_to_piplib_matrix(struct isl_ctx* ctx,
5242 - struct isl_set* set,
5244 +struct isl_set* isl_set_from_piplib_matrix(struct isl_ctx* ctx,
5245 + osl_relation_p matrix,
5247 +osl_relation_p isl_set_to_piplib_matrix(struct isl_ctx* ctx,
5248 + struct isl_set* set,
5251 * candl_dependence_isl_simplify function:
5253 @@ -353,33 +204,35 @@ isl_set_to_piplib_matrix(struct isl_ctx* ctx,
5254 * Useful for polyhedra that contain large coefficient values.
5257 -CandlDependence* candl_dependence_isl_simplify(CandlDependence* dep,
5258 - CandlProgram* program)
5260 - if (dep == NULL || program == NULL)
5261 +osl_dependence_p candl_dependence_isl_simplify(osl_dependence_p dep,
5262 + osl_scop_p scop) {
5263 + if (dep == NULL || scop == NULL)
5266 - CandlDependence* tmp;
5267 - PipMatrix* context = (PipMatrix*) program->context;
5268 - int nparam = context->NbColumns - 2;
5270 - struct isl_ctx* ctx = isl_ctx_alloc ();
5272 - for (tmp = dep; tmp; tmp = tmp->next)
5274 - // 1- Convert the dependence polyhedron into ISL set.
5275 - struct isl_set* set =
5276 - isl_set_from_piplib_matrix(ctx, tmp->domain, nparam);
5278 - // 2- Simplify the ISL set.
5279 - set = isl_set_detect_equalities(set);
5281 - // 3- Convert back into Candl matrix representation.
5282 - PipMatrix* newdom = isl_set_to_piplib_matrix(ctx, set, nparam);
5283 - isl_set_free (set);
5284 - candl_matrix_free (tmp->domain);
5285 - tmp->domain = (CandlMatrix*) newdom;
5287 + osl_dependence_p tmp;
5288 + osl_relation_p context = scop->context;
5289 + int nparam = context->nb_parameters;
5291 + struct isl_ctx* ctx = isl_ctx_alloc();
5293 + for (tmp = dep; tmp; tmp = tmp->next) {
5294 + // 1- Convert the dependence polyhedron into ISL set.
5296 + struct isl_set* set = isl_set_from_piplib_matrix(ctx, tmp->domain, nparam);
5298 + // 2- Simplify the ISL set.
5299 + set = isl_set_detect_equalities(set);
5301 + // 3- Convert back into Candl matrix representation.
5302 + osl_relation_p newdom = isl_set_to_piplib_matrix(ctx, set, nparam);
5303 + isl_set_free(set);
5304 + newdom->nb_output_dims = tmp->domain->nb_output_dims;
5305 + newdom->nb_input_dims = tmp->domain->nb_input_dims;
5306 + newdom->nb_local_dims = tmp->domain->nb_local_dims;
5307 + newdom->nb_parameters = tmp->domain->nb_parameters;
5308 + osl_relation_free(tmp->domain);
5309 + tmp->domain = newdom;
5312 /// FIXME: Some dead ref.
5313 //isl_ctx_free (ctx);
5314 @@ -390,476 +243,76 @@ CandlDependence* candl_dependence_isl_simplify(CandlDependence* dep,
5320 - * candl_dependence_print_scop function:
5321 - * This function adds to the .scop file provided as the 'input' the
5322 - * optional tags to represent the dependences 'dependence' of the
5323 - * program. Finally, it prints the updated .scop to the file 'output'.
5327 -#ifdef CANDL_SUPPORTS_SCOPLIB
5329 - * Read one dependence from a string.
5331 +/* candl_dependence_init_fields:
5332 + * Set the various other fields of the dependence structure
5335 -CandlDependence* candl_dependence_read_one_dep(char* str, char** next,
5336 - CandlProgram* program)
5338 - CandlDependence* dep = candl_dependence_malloc();
5339 - CandlMatrix* msource = NULL;
5340 - CandlMatrix* mtarget = NULL;
5341 - char buffer[1024];
5346 - /* # Description of dependence xxx */
5347 - for (; *str != '\n'; ++str);
5351 - for (; *str != '\n'; ++str);
5354 - /* {RAW,RAR,WAR,WAW} #(type) */
5355 - for (i = 0; *str != ' '; ++str, ++i)
5358 - if (! strcmp(buffer, "RAW"))
5359 - dep->type = CANDL_RAW;
5360 - else if (! strcmp(buffer, "RAR"))
5361 - dep->type = CANDL_RAR;
5362 - else if (! strcmp(buffer, "WAR"))
5363 - dep->type = CANDL_WAR;
5364 - else if (! strcmp(buffer, "WAW"))
5365 - dep->type = CANDL_WAW;
5366 - else if (! strcmp(buffer, "RAW_SCALPRIV"))
5367 - dep->type = CANDL_RAW_SCALPRIV;
5368 - for (; *str != '\n'; ++str);
5371 - /* # From statement xxx */
5372 - for (; *str != '\n'; ++str);
5375 - for (i = 0; *str != '\n'; ++str, ++i)
5379 - id = atoi(buffer);
5380 - for (i = 0; i < program->nb_statements; ++i)
5381 - if (program->statement[i]->label == id)
5383 - dep->source = program->statement[i];
5387 - /* # To statement xxx */
5388 - for (; *str != '\n'; ++str);
5391 - for (i = 0; *str != '\n'; ++str, ++i)
5395 - id = atoi(buffer);
5396 - for (i = 0; i < program->nb_statements; ++i)
5397 - if (program->statement[i]->label == id)
5399 - dep->target = program->statement[i];
5404 - for (; *str != '\n'; ++str);
5407 - for (i = 0; *str != '\n'; ++str, ++i)
5411 - dep->depth = atoi(buffer);
5414 - for (; *str != '\n'; ++str);
5417 - for (i = 0; *str != '\n'; ++str, ++i)
5421 - id = atoi(buffer);
5422 - switch (dep->type)
5425 - case CANDL_RAW_SCALPRIV:
5426 - msource = dep->source->written;
5427 - mtarget = dep->target->read;
5430 - msource = dep->source->read;
5431 - mtarget = dep->target->written;
5434 - msource = dep->source->written;
5435 - mtarget = dep->target->written;
5438 - msource = dep->source->read;
5439 - mtarget = dep->target->read;
5443 +void candl_dependence_init_fields(osl_scop_p scop, osl_dependence_p dep) {
5445 + osl_statement_p iter;
5446 + candl_statement_usr_p usr;
5447 + osl_relation_p array_s, array_t;
5449 + /* source statement */
5450 + iter = scop->statement;
5451 + for (; iter != NULL ; iter = iter->next) {
5453 + if (usr->label == dep->label_source) {
5454 + dep->stmt_source_ptr = iter;
5457 - for (i = 0; i < msource->NbRows && msource->p[i][0] != id; ++i)
5459 - if (i < msource->NbRows)
5460 - dep->ref_source = i;
5461 - for (i = 0; i < mtarget->NbRows && mtarget->p[i][0] != id; ++i)
5463 - if (i < mtarget->NbRows)
5464 - dep->ref_target = i;
5466 - /* # Dependence domain */
5467 - for (; *str != '\n'; ++str);
5470 - /* nb-row nb-col */
5471 - for (i = 0; *str != ' '; ++str, ++i)
5475 - id = atoi(buffer);
5476 - for (i = 0; *str != '\n'; ++str, ++i)
5480 - id2 = atoi(buffer);
5482 - dep->domain = candl_matrix_malloc(id, id2);
5483 - /* Read matrix elements. */
5484 - for (j = 0; j < id; ++j)
5486 - for (k = 0; k < id2; ++k)
5488 - while (*str && *str == ' ')
5490 - for (i = 0; *str != '\n' && *str != ' '; ++str, ++i)
5494 - CANDL_set_si(dep->domain->p[j][k], atoi(buffer));
5496 - if (*(str - 1) != '\n')
5498 - for (; *str != '\n'; ++str);
5502 - /* Store the next character in the string to be analyzed. */
5509 - * Retrieve a CandlDependence list from the option tag in the scop.
5512 -CandlDependence* candl_dependence_read_from_scop(scoplib_scop_p scop,
5513 - CandlProgram* program)
5515 - CandlDependence* first = NULL;
5516 - CandlDependence* currdep = NULL;
5518 - char* deps = scoplib_scop_tag_content(scop,
5519 - "<dependence-polyhedra>",
5520 - "</dependence-polyhedra>");
5522 - /* No dependence, nothing to do. */
5526 - /* Keep the starting address of the array. */
5527 - char* base = deps;
5531 - /* Get the number of dependences. */
5532 - char buffer_nb[32];
5533 - /* # Number of dependences */
5534 - for (; *deps != '\n'; ++deps);
5536 - for (i = 0; *deps != '\n'; ++i, ++deps)
5537 - buffer_nb[i] = *deps;
5538 - buffer_nb[i] = '\0';
5540 - int nbdeps = atoi (buffer_nb);
5543 - /* For each of them, read 1 and shift of the read size. */
5544 - for (depcount = 0; depcount < nbdeps; ++depcount)
5546 - CandlDependence* adep =
5547 - candl_dependence_read_one_dep(deps, &next, program);
5548 - if (first == NULL)
5549 - currdep = first = adep;
5552 - currdep->next = adep;
5553 - currdep = currdep->next;
5565 - * Update the scop option tag with the dependence list.
5568 -void candl_dependence_update_scop_with_deps(scoplib_scop_p scop,
5569 - CandlDependence* dependence)
5574 - char* olddeps = NULL;
5581 - int size_olddeps = 0;
5582 - int size_optiontags;
5584 - start = stop = scop->optiontags;
5585 - /* Get the candl tag, if any. */
5586 - content = scoplib_scop_tag_content(scop, "<candl>", "</candl>");
5589 - /* Get the dependence tag, if any. */
5590 - olddeps = scoplib_scop_tag_content_from_string
5591 - (content, "<dependence-polyhedra>", "</dependence-polyhedra>");
5592 - /* Seek for the correct start/stop characters to insert
5596 - size = size_olddeps = strlen(olddeps);
5597 - while (start && *start && strncmp(start, olddeps, size))
5599 - stop = start + size;
5603 - size = strlen(content);
5604 - while (start && *start && strncmp(start, content, size))
5610 - /* Convert the program dependences to dotscop representation. */
5611 - newdeps = candl_program_deps_to_string(dependence);
5613 - /* Compute the new size of the full options tags, and allocate a new
5615 - size_newdeps = newdeps ? strlen(newdeps) : 0;
5616 - size_optiontags = scop->optiontags ? strlen(scop->optiontags) : 0;
5617 - if (content == NULL)
5618 - size = strlen("<candl>") + strlen("</candl>") +
5619 - strlen("<dependence-polyhedra>")
5620 - + strlen("</dependence-polyhedra>");
5621 - else if (olddeps == NULL)
5622 - size = strlen("<dependence-polyhedra>") + strlen("</dependence-polyhedra>");
5625 - newopttags = (char*) malloc((size_newdeps + size_optiontags
5626 - - size_olddeps + size + 1)
5628 - if (newopttags == NULL)
5629 - CANDL_FAIL("Error: memory overflow");
5630 - curr = newopttags;
5632 - /* Copy the beginning of the options. */
5633 - for (tmp = scop->optiontags; tmp != start; ++tmp)
5636 - /* Copy the candl tags, if needed. */
5637 - if (content == NULL)
5639 - strcat(newopttags, "<candl>\n");
5640 - curr += strlen("<candl>\n");
5642 - if (olddeps == NULL)
5644 - strcat(newopttags, "<dependence-polyhedra>\n");
5645 - curr += strlen("<dependence-polyhedra>\n");
5647 - /* Copy the program dependences. */
5648 - for (tmp = newdeps; tmp && *tmp; ++tmp)
5651 - /* Copy the candl tags, if needed. */
5652 - if (olddeps == NULL)
5654 - strcat(curr, "</dependence-polyhedra>\n");
5655 - curr += strlen("</dependence-polyhedra>\n");
5657 - if (content == NULL)
5659 - strcat(curr, "</candl>\n");
5660 - curr += strlen("</candl>\n");
5662 - /* Copy the remainder of the options. */
5663 - for (tmp = stop; tmp && *tmp; ++tmp)
5667 - if (scop->optiontags)
5668 - free(scop->optiontags);
5669 - scop->optiontags = newopttags;
5681 - * Print the scop, containing the list of dependences.
5684 -void candl_dependence_print_scop(FILE* input, FILE* output,
5685 - CandlDependence* dependence)
5687 - scoplib_scop_p scop;
5689 - /* Go to the beginning of the file. */
5692 - /* Re-read the options tags. */
5693 - scop = scoplib_scop_read(input);
5695 - /* Embed the dependences in the scop option tag. */
5696 - candl_dependence_update_scop_with_deps(scop, dependence);
5698 - /* Dump the .scop. */
5699 - scoplib_scop_print_dot_scop(output, scop);
5704 -/******************************************************************************
5705 - * Memory deallocation function *
5706 - ******************************************************************************/
5709 -/* candl_dependence_free function:
5710 - * This function frees the allocated memory for a CandlDependence structure.
5711 - * - 18/09/2003: first version.
5713 -void candl_dependence_free(candl_dependence_p dependence)
5715 - candl_dependence_p next;
5717 - while (dependence != NULL)
5719 - next = dependence->next;
5720 - candl_matrix_free(dependence->domain);
5722 - dependence = next;
5727 -/******************************************************************************
5728 - * Processing functions *
5729 - ******************************************************************************/
5733 - * candl_dependence_malloc function:
5734 - * This function allocates the memory space for a CandlDependence structure and
5735 - * sets its fields with default values. Then it returns a pointer to the
5736 - * allocated space.
5737 - * - 07/12/2005: first version.
5739 -candl_dependence_p candl_dependence_malloc()
5741 - candl_dependence_p dependence;
5743 - /* Memory allocation for the CandlDependence structure. */
5744 - dependence = (candl_dependence_p) malloc(sizeof(CandlDependence));
5745 - if (dependence == NULL)
5746 - CANDL_FAIL(" Error: memory overflow");
5748 - /* We set the various fields with default values. */
5749 - dependence->source = NULL;
5750 - dependence->target = NULL;
5751 - dependence->depth = CANDL_UNSET;
5752 - dependence->type = CANDL_UNSET;
5753 - dependence->ref_source = CANDL_UNSET;
5754 - dependence->ref_target = CANDL_UNSET;
5755 - dependence->domain = NULL;
5756 - dependence->next = NULL;
5757 - dependence->usr = NULL;
5759 - return dependence;
5764 - * candl_dependence_add function:
5765 - * This function adds a CandlDependence structure (dependence) at a given place
5766 - * (now) of a NULL terminated list of CandlDependence structures. The beginning
5767 - * of this list is (start). This function updates (now) to the end of the loop
5768 - * list (loop), and updates (start) if the added element is the first one -that
5769 - * is when (start) is NULL-.
5770 - * - 18/09/2003: first version.
5772 -void candl_dependence_add(candl_dependence_p* start,
5773 - candl_dependence_p* now,
5774 - candl_dependence_p dependence)
5776 - if (dependence != NULL)
5778 - if (*start == NULL)
5780 - *start = dependence;
5785 - (*now)->next = dependence;
5786 - *now = (*now)->next;
5789 - while ((*now)->next != NULL)
5790 - *now = (*now)->next;
5792 + if (iter == NULL) {
5793 + fprintf(stderr, "[Candl] Can't find the %dth label\n", dep->label_source);
5797 + /* target statement */
5798 + iter = scop->statement;
5799 + for (; iter != NULL ; iter = iter->next) {
5801 + if (usr->label == dep->label_target) {
5802 + dep->stmt_target_ptr = iter;
5806 + if (iter == NULL) {
5807 + fprintf(stderr, "[Candl] Can't find the %dth label\n", dep->label_target);
5811 + array_s = candl_dependence_get_relation_ref_source_in_dep(dep);
5812 + if (array_s == NULL) {
5813 + fprintf(stderr, "[Candl] Can't find the %dth access of the statement :\n",
5815 + osl_statement_dump(stderr, dep->stmt_source_ptr);
5819 + array_t = candl_dependence_get_relation_ref_source_in_dep(dep);
5820 + if (array_t == NULL) {
5821 + fprintf(stderr, "[Candl] Can't find the %dth access of the statement :\n",
5823 + osl_statement_dump(stderr, dep->stmt_target_ptr);
5827 + dep->source_nb_output_dims_domain = dep->stmt_source_ptr->domain->nb_output_dims;
5828 + dep->source_nb_output_dims_access = array_s->nb_output_dims;
5830 + dep->target_nb_output_dims_domain = dep->stmt_target_ptr->domain->nb_output_dims;
5831 + dep->target_nb_output_dims_access = array_t->nb_output_dims;
5833 + dep->source_nb_local_dims_domain = dep->stmt_source_ptr->domain->nb_local_dims;
5834 + dep->source_nb_local_dims_access = array_s->nb_local_dims;
5835 + dep->target_nb_local_dims_domain = dep->stmt_target_ptr->domain->nb_local_dims;
5836 + dep->target_nb_local_dims_access = array_t->nb_local_dims;
5845 -candl_dependence_gcd(int a, int b)
5847 +static int candl_dependence_gcd(int a, int b) {
5851 @@ -870,19 +323,17 @@ candl_dependence_gcd(int a, int b)
5881 @@ -891,9 +342,7 @@ candl_dependence_gcd(int a, int b)
5886 -int candl_dependence_gcd_test_context (CandlMatrix* system, int id)
5888 +static int candl_dependence_gcd_test_context(osl_relation_p system, int id) {
5889 /* FIXME: implement me! */
5892 @@ -915,16 +364,18 @@ int candl_dependence_gcd_test_context (CandlMatrix* system, int id)
5893 * are also performed before the actual GCD test.
5896 -int candl_dependence_gcd_test(CandlStatement* source,
5897 - CandlStatement* target,
5898 - CandlMatrix* system,
5901 +int candl_dependence_gcd_test(osl_statement_p source,
5902 + osl_statement_p target,
5903 + osl_relation_p system,
5909 int null_iter, null_param, null_cst, pos_iter, neg_iter;
5910 + int precision = source->domain->precision;
5911 + candl_statement_usr_p s_usr = source->usr;
5912 + candl_statement_usr_p t_usr = target->usr;
5914 /* Check that the precedence constraint, if any, is not strict in a
5916 @@ -937,59 +388,63 @@ int candl_dependence_gcd_test(CandlStatement* source,
5917 /* strict_pred = 0; */
5919 /* Inspect the array access function equalities. */
5920 - for (id = source->domain->NbRows + target->domain->NbRows;
5921 - id < system->NbRows && CANDL_get_si(system->p[id][0]) == 0; ++id)
5923 - /* Inspect which parts of the access function equality are null,
5924 - positive or negative. */
5925 - null_iter = null_param = null_cst = pos_iter = neg_iter = 0;
5926 - for (i = 1; i < source->depth + target->depth + 1 &&
5927 - CANDL_get_si(system->p[id][i]) == 0; ++i)
5929 - if (i == source->depth + target->depth + 1)
5932 - for (pos_iter = 1, neg_iter = 1;
5933 - i < source->depth + target->depth + 1; ++i)
5935 - if (CANDL_get_si(system->p[id][i]) < 0)
5937 - else if (CANDL_get_si(system->p[id][i]) > 0)
5940 - for (; i < system->NbColumns - 1 && CANDL_get_si(system->p[id][i]) == 0;
5943 - if (i == system->NbColumns - 1)
5945 - null_cst = ! CANDL_get_si(system->p[id][system->NbColumns - 1]);
5947 - /* Some useful ZIV/SIV/MIV tests. */
5948 - if (null_iter && null_param && !null_cst)
5951 - if (! candl_dependence_gcd_test_context (system, id))
5953 - if (null_cst || !null_param)
5955 -/* FIXME: implement the loop bound check. */
5956 -/* /\* A clever test on access bounds. *\/ */
5957 -/* if (null_param && pos_iter && */
5958 -/* CANDL_get_si(system->p[id][system->NbColumns - 1]) > 0) */
5960 -/* if (null_param && neg_iter && */
5961 -/* CANDL_get_si(system->p[id][system->NbColumns - 1]) < 0) */
5964 - /* Compute GCD test for the array access equality. */
5965 - for (i = 1, gcd = CANDL_get_si(system->p[id][i]);
5966 - i < source->depth + target->depth; ++i)
5967 - gcd = candl_dependence_gcd(gcd, CANDL_get_si(system->p[id][i + 1]));
5968 - value = CANDL_get_si(system->p[id][system->NbColumns - 1]);
5969 - value = value < 0 ? -value : value;
5970 - if ((gcd == 0 && value != 0) || value % gcd)
5973 + for (id = source->domain->nb_rows + target->domain->nb_rows;
5974 + id < system->nb_rows &&
5975 + osl_int_zero(precision, system->m[id][0]);
5977 + /* Inspect which parts of the access function equality are null,
5978 + positive or negative. */
5979 + null_iter = null_param = null_cst = pos_iter = neg_iter = 0;
5981 + for (i = 1; i < s_usr->depth + t_usr->depth + 1 &&
5982 + osl_int_zero(precision, system->m[id][i]); ++i)
5985 + if (i == s_usr->depth + t_usr->depth + 1)
5988 + for (pos_iter = 1, neg_iter = 1;
5989 + i < s_usr->depth + t_usr->depth + 1; ++i) {
5990 + if (osl_int_neg(precision, system->m[id][i]))
5992 + else if (osl_int_pos(precision, system->m[id][i]))
5995 + for (; i < system->nb_columns - 1 &&
5996 + osl_int_zero(precision, system->m[id][i]) == 0; ++i)
5998 + if (i == system->nb_columns - 1)
6000 + null_cst = osl_int_zero(precision, system->m[id][system->nb_columns - 1]);
6002 + /* Some useful ZIV/SIV/MIV tests. */
6003 + if (null_iter && null_param && !null_cst)
6006 + if (! candl_dependence_gcd_test_context(system, id))
6008 + if (null_cst || !null_param)
6010 + /* FIXME: implement the loop bound check. */
6011 + /* /\* A clever test on access bounds. *\/ */
6012 + /* if (null_param && pos_iter && */
6013 + /* CANDL_get_si(system->p[id][system->NbColumns - 1]) > 0) */
6015 + /* if (null_param && neg_iter && */
6016 + /* CANDL_get_si(system->p[id][system->NbColumns - 1]) < 0) */
6019 + /* Compute GCD test for the array access equality. */
6020 + for (i = 1, gcd = osl_int_get_si(precision, system->m[id][i]);
6021 + i < s_usr->depth + t_usr->depth; ++i)
6022 + gcd = candl_dependence_gcd(gcd,
6023 + osl_int_get_si(precision, system->m[id][i + 1]));
6025 + value = osl_int_get_si(precision, system->m[id][system->nb_columns - 1]);
6026 + value = value < 0 ? -value : value;
6027 + if ((gcd == 0 && value != 0) || value % gcd)
6033 @@ -1006,135 +461,243 @@ int candl_dependence_gcd_test(CandlStatement* source,
6034 * See the [bastoul and Feautrier, PPL 2005] paper for details !
6035 * - source is the source iteration domain,
6036 * - target is the target iteration domain,
6037 - * - array_s is the array list for the source,
6038 - * - array_t is the array list for the target,
6039 - * - ref_s is the position of the source reference in array_s,
6040 - * - ref_s is the position of the target reference in array_t,
6041 + * - array_s is the access array for the source,
6042 + * - array_t is the access array for the target,
6043 * - depth is the dependence depth,
6044 * - before is 1 if the source is textually before the target, 0 otherwise,
6045 - * - nb_par is the number of parameters.
6047 * - 13/12/2005: first version (extracted from candl_dependence_system).
6048 * - 23/02/2006: a stupid bug corrected in the subscript equality.
6049 * - 07/04/2007: fix the precedence condition to respect C. Bastoul PhD thesis
6052 -CandlMatrix * candl_dependence_build_system(source, target, array_s, array_t,
6053 - ref_s, ref_t, depth, before, nb_par)
6054 -CandlStatement * source, * target;
6055 -CandlMatrix * array_s, * array_t ;
6056 -int ref_s, ref_t, depth, before, nb_par ;
6057 -{ int i, j, nb_rows, nb_columns, nb_dimensions, constraint, s_dims, t_dims ;
6058 - CandlMatrix * system ;
6061 - CANDL_init(temp) ;
6063 - /* We calculate the number of dimensions of the considered array. */
6064 - nb_dimensions = 1;
6065 - while (((ref_s + nb_dimensions + 1) <= array_s->NbRows) &&
6066 - (array_s->p[ref_s + nb_dimensions][0] == 0))
6067 - nb_dimensions ++ ;
6069 - /* The number of dimensions of the source and target domains. */
6070 - s_dims = source->domain->NbColumns - nb_par - 2 ;
6071 - t_dims = target->domain->NbColumns - nb_par - 2 ;
6073 - /* The number of rows of the system is:
6074 - * - the number of constraints of the source iteration domain +
6075 - * - the number of constraints of the target iteration domain +
6076 - * - the number of dimensions of the considered array (subscript equality) +
6077 - * - the number of precedence constraints (equal to depth).
6079 - nb_rows = source->domain->NbRows + target->domain->NbRows +
6080 - nb_dimensions + depth ;
6082 - /* The number of columns of the system is:
6083 - * - the number of source statement surrounding loops +
6084 - * - the number of target statement surrounding loops +
6085 - * - the number of parameters +
6086 - * - 2 (1 for equality/inequality identifier + 1 for the constant).
6088 - nb_columns = s_dims + t_dims + nb_par + 2 ;
6090 - /* We allocate memory space for the constraint system. */
6091 - system = candl_matrix_malloc(nb_rows,nb_columns) ;
6093 - /* Compute the maximal common depth. */
6094 +static osl_dependence_p candl_dependence_build_system(
6095 + osl_statement_p source, osl_statement_p target,
6096 + osl_relation_p array_s, osl_relation_p array_t,
6097 + int depth, int before) {
6098 + osl_dependence_p dependence;
6099 + osl_relation_p system;
6101 + int constraint = 0;
6102 + int precision = source->domain->precision;
6103 + int nb_output_dims; // source column
6104 + int nb_input_dims; // target column
6105 + int nb_local_dims;
6107 + int nb_rows, nb_columns;
6108 + int ind_source_local_domain;
6109 + int ind_source_local_access;
6110 + int ind_target_local_domain;
6111 + int ind_target_local_access;
6114 - while (min_depth < source->depth && min_depth < target->depth &&
6115 - source->index[min_depth] == target->index[min_depth])
6118 - /* We fill the constraint system (note that there is no need to put zeros
6119 - * in the empty zones since candl_matrix_alloc initialized all entries to 0):
6122 - /* 1. The source iteration domain constraints. */
6124 - for (i=0;i<source->domain->NbRows;i++)
6125 - { for (j=0;j<=s_dims;j++)
6126 - CANDL_assign(system->p[constraint][j],source->domain->p[i][j]) ;
6128 - for (j=s_dims+1;j<source->domain->NbColumns;j++)
6129 - CANDL_assign(system->p[constraint][j+t_dims],source->domain->p[i][j]) ;
6133 + /* Create a new dependence structure */
6134 + dependence = osl_dependence_malloc();
6136 + /* Compute the maximal common depth. */
6137 + min_depth = CANDL_min(array_s->nb_output_dims, array_t->nb_output_dims);
6139 + /* Compute the system size */
6140 + dependence->source_nb_output_dims_domain = source->domain->nb_output_dims;
6141 + dependence->source_nb_output_dims_access = array_s->nb_output_dims;
6143 + dependence->target_nb_output_dims_domain = target->domain->nb_output_dims;
6144 + dependence->target_nb_output_dims_access = array_t->nb_output_dims;
6146 + dependence->source_nb_local_dims_domain = source->domain->nb_local_dims;
6147 + dependence->source_nb_local_dims_access = array_s->nb_local_dims;
6148 + dependence->target_nb_local_dims_domain = target->domain->nb_local_dims;
6149 + dependence->target_nb_local_dims_access = array_t->nb_local_dims;
6151 + nb_par = source->domain->nb_parameters;
6152 + nb_local_dims = dependence->source_nb_local_dims_domain +
6153 + dependence->source_nb_local_dims_access +
6154 + dependence->target_nb_local_dims_domain +
6155 + dependence->target_nb_local_dims_access;
6156 + nb_output_dims = dependence->source_nb_output_dims_domain +
6157 + dependence->source_nb_output_dims_access;
6158 + nb_input_dims = dependence->target_nb_output_dims_domain +
6159 + dependence->target_nb_output_dims_access;
6161 + nb_columns = nb_output_dims + nb_input_dims + nb_local_dims + nb_par + 2;
6162 + nb_rows = source->domain->nb_rows + target->domain->nb_rows +
6163 + array_s->nb_rows + array_t->nb_rows +
6167 + system = osl_relation_pmalloc(precision, nb_rows, nb_columns);
6169 + /* Compute some indexes */
6170 + ind_source_local_domain = 1 + nb_output_dims + nb_input_dims;
6171 + ind_source_local_access = ind_source_local_domain + dependence->source_nb_local_dims_domain;
6172 + ind_target_local_domain = ind_source_local_access + dependence->source_nb_local_dims_access;
6173 + ind_target_local_access = ind_target_local_domain + dependence->target_nb_local_dims_domain;
6174 + ind_params = ind_target_local_access + dependence->target_nb_local_dims_access;
6176 + /* 1. Copy the source domain */
6177 + for (i = 0 ; i < source->domain->nb_rows ; i++) {
6179 + osl_int_assign(precision,
6180 + &system->m[constraint][0], source->domain->m[i][0]);
6184 + for (c = source->domain->nb_output_dims ; c > 0 ; c--, k++, j++)
6185 + osl_int_assign(precision,
6186 + &system->m[constraint][k], source->domain->m[i][j]);
6187 + /* local dims (no input in domain, so j is the same) */
6188 + k = ind_source_local_domain;
6189 + for (c = source->domain->nb_local_dims ; c > 0 ; c--, k++, j++)
6190 + osl_int_assign(precision,
6191 + &system->m[constraint][k], source->domain->m[i][j]);
6192 + /* params + const */
6194 + for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
6195 + osl_int_assign(precision,
6196 + &system->m[constraint][k], source->domain->m[i][j]);
6200 - /* 2. The target iteration domain constraints. */
6201 - for (i = 0; i < target->domain->NbRows; i++)
6202 - { CANDL_assign(system->p[constraint][0],target->domain->p[i][0]) ;
6204 - for (j = 1; j < target->domain->NbColumns; j++)
6205 - CANDL_assign(system->p[constraint][j + s_dims], target->domain->p[i][j]) ;
6209 + /* 2. Copy the target domain */
6210 + for (i = 0 ; i < target->domain->nb_rows ; i++) {
6212 + osl_int_assign(precision,
6213 + &system->m[constraint][0], target->domain->m[i][0]);
6215 + k = 1 + nb_output_dims;
6217 + for (c = target->domain->nb_output_dims ; c > 0 ; c--, k++, j++)
6218 + osl_int_assign(precision,
6219 + &system->m[constraint][k], target->domain->m[i][j]);
6220 + /* local dims (no input in domain, so j is the same) */
6221 + k = ind_target_local_domain;
6222 + for (c = target->domain->nb_local_dims ; c > 0 ; c--, k++, j++)
6223 + osl_int_assign(precision,
6224 + &system->m[constraint][k], target->domain->m[i][j]);
6225 + /* params + const */
6227 + for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
6228 + osl_int_assign(precision,
6229 + &system->m[constraint][k], target->domain->m[i][j]);
6235 - /* 3. The equality of the subscripts. */
6236 - for (i = 0; i < nb_dimensions; i++)
6237 - { /* Source iterator coefficients part. */
6238 - for (j = 1; j <= s_dims; j++)
6239 - CANDL_assign(system->p[constraint][j], array_s->p[ref_s + i][j]) ;
6241 - /* Target iterator coefficients part (negative). */
6242 - for (j = 1; j <= t_dims; j++)
6243 - { CANDL_oppose(temp, array_t->p[ref_t + i][j]) ;
6244 - CANDL_assign(system->p[constraint][j + s_dims], temp) ;
6246 + /* 3. Copy the source access */
6247 + for (i = 0 ; i < array_s->nb_rows ; i++) {
6249 + osl_int_assign(precision,
6250 + &system->m[constraint][0], array_s->m[i][0]);
6252 + k = 1 + source->domain->nb_output_dims;
6254 + for (c = array_s->nb_output_dims ; c > 0 ; c--, k++, j++)
6255 + osl_int_assign(precision,
6256 + &system->m[constraint][k], array_s->m[i][j]);
6257 + /* link input dims access to the output dims domain */
6259 + for (c = array_s->nb_input_dims ; c > 0 ; c--, k++, j++)
6260 + osl_int_assign(precision,
6261 + &system->m[constraint][k], array_s->m[i][j]);
6263 + k = ind_source_local_access;
6264 + for (c = array_s->nb_local_dims ; c > 0 ; c--, k++, j++)
6265 + osl_int_assign(precision,
6266 + &system->m[constraint][k], array_s->m[i][j]);
6267 + /* params + const */
6269 + for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
6270 + osl_int_assign(precision,
6271 + &system->m[constraint][k], array_s->m[i][j]);
6276 + /* 4. Copy the target access */
6277 + for (i = 0 ; i < array_t->nb_rows ; i++) {
6279 + osl_int_assign(precision,
6280 + &system->m[constraint][0], array_t->m[i][0]);
6282 + k = 1 + nb_output_dims + target->domain->nb_output_dims;
6284 + for (c = array_t->nb_output_dims ; c > 0 ; c--, k++, j++) {
6285 + osl_int_assign(precision,
6286 + &system->m[constraint][k], array_t->m[i][j]);
6287 + osl_int_oppose(precision,
6288 + &system->m[constraint][k], system->m[constraint][k]);
6291 - /* Parameters and constant coefficients part. */
6292 - for (j = 1; j <= nb_par + 1; j++)
6293 - CANDL_subtract(system->p[constraint][j + s_dims + t_dims],
6294 - array_s->p[ref_s + i][j + s_dims],
6295 - array_t->p[ref_t + i][j + t_dims]) ;
6298 + /* link input dims access to the output dims domain */
6299 + k = 1 + nb_output_dims;
6300 + for (c = array_t->nb_input_dims ; c > 0 ; c--, k++, j++) {
6301 + osl_int_assign(precision,
6302 + &system->m[constraint][k], array_t->m[i][j]);
6303 + osl_int_oppose(precision,
6304 + &system->m[constraint][k], system->m[constraint][k]);
6307 + k = ind_target_local_access;
6308 + for (c = array_t->nb_local_dims ; c > 0 ; c--, k++, j++) {
6309 + osl_int_assign(precision,
6310 + &system->m[constraint][k], array_t->m[i][j]);
6311 + osl_int_oppose(precision,
6312 + &system->m[constraint][k], system->m[constraint][k]);
6314 + /* params + const */
6316 + for (c = nb_par+1 ; c > 0 ; c--, k++, j++) {
6317 + osl_int_assign(precision,
6318 + &system->m[constraint][k], array_t->m[i][j]);
6319 + osl_int_oppose(precision,
6320 + &system->m[constraint][k], system->m[constraint][k]);
6325 - /* 4. The precedence constraints (their number is equal to depth). */
6326 - for (i = 0; i < depth; i++)
6327 - { /* i = i' for all dimension less than depth. */
6328 - CANDL_set_si(system->p[constraint][i + 1], -1) ;
6329 - CANDL_set_si(system->p[constraint][s_dims + i + 1], 1) ;
6330 - if (i == depth - 1)
6332 - /* i <= i' at dimension depth if source is textually before target. */
6333 - CANDL_set_si(system->p[constraint][0], 1) ;
6334 - /* If source is textually after target, this is obviously i < i'. */
6335 - if (before || depth < min_depth)
6337 - CANDL_set_si(system->p[constraint][nb_columns - 1], -1);
6343 + /* 5. Set the equality between the output access */
6344 + /* Note here that the equality between the 2 Arr are necessarily equal */
6345 + k = 1 + source->domain->nb_output_dims;
6346 + j = 1 + nb_output_dims + target->domain->nb_output_dims;
6347 + for (i = 0 ; i < min_depth ; i++, k++, j++) {
6348 + osl_int_set_si(precision, &system->m[constraint][k], -1);
6349 + osl_int_set_si(precision, &system->m[constraint][j], 1);
6353 + /* 6. The precedence constraints */
6355 + while (min_dim < ((candl_statement_usr_p)source->usr)->depth &&
6356 + min_dim < ((candl_statement_usr_p)target->usr)->depth &&
6357 + ((candl_statement_usr_p)source->usr)->index[min_dim] ==
6358 + ((candl_statement_usr_p)target->usr)->index[min_dim])
6362 + j = 1 + nb_output_dims;
6363 + for (i = 0; i < depth; i++, k++, j++) {
6364 + /* i = i' for all dimension less than depth. */
6365 + osl_int_set_si(precision, &system->m[constraint][k], -1);
6366 + osl_int_set_si(precision, &system->m[constraint][j], 1);
6367 + if (i == depth - 1) {
6368 + /* i <= i' at dimension depth if source is textually before target. */
6369 + osl_int_set_si(precision, &system->m[constraint][0], 1);
6370 + /* If source is textually after target, this is obviously i < i'. */
6371 + if (before || depth < min_dim) // sub 1 for the Arr dim
6372 + osl_int_set_si(precision, &system->m[constraint][nb_columns - 1], -1);
6375 - CANDL_clear(temp) ;
6380 + system->nb_output_dims = nb_output_dims;
6381 + system->nb_input_dims = nb_input_dims;
6382 + system->nb_parameters = nb_par;
6383 + system->nb_local_dims = nb_local_dims;
6384 + system->type = OSL_UNDEFINED;
6386 + dependence->domain = system;
6388 + return dependence;
6392 @@ -1157,49 +720,53 @@ int ref_s, ref_t, depth, before, nb_par ;
6393 * - 18/09/2003: first version.
6394 * - 09/12/2005: few corrections and polishing.
6396 -candl_dependence_p candl_dependence_system(CandlStatement* source,
6397 - CandlStatement* target,
6398 - CandlMatrix* context,
6399 - CandlMatrix* array_s,
6400 - CandlMatrix* array_t,
6401 - int ref_s, int ref_t,
6402 - int type, int depth)
6404 - candl_dependence_p dependence = NULL;
6405 - CandlMatrix * system;
6406 +osl_dependence_p candl_dependence_system(osl_statement_p source,
6407 + osl_statement_p target,
6408 + osl_relation_p context,
6409 + osl_relation_p array_s,
6410 + osl_relation_p array_t,
6411 + int ref_s, int ref_t,
6412 + int type, int depth) {
6413 + candl_statement_usr_p s_usr = source->usr;
6414 + candl_statement_usr_p t_usr = target->usr;
6415 + osl_dependence_p dependence = NULL;
6417 /* First, a trivial case: for two different statements at depth 0, there is
6418 * a dependence only if the source is textually before the target.
6420 - if ((source != target) && (depth == 0) && (source->label > target->label))
6421 + if ((source != target) && (depth == 0) &&
6422 + (s_usr->label > t_usr->label))
6426 /* We build the system of constraints. */
6427 - system = candl_dependence_build_system(source, target,
6428 - array_s, array_t, ref_s, ref_t,
6430 - (source->label >= target->label),
6431 - context->NbColumns-2);
6432 + dependence = candl_dependence_build_system(source, target,
6438 /* We start by simple SIV/ZIV/GCD tests. */
6439 - if (! candl_dependence_gcd_test(source, target, system, depth))
6440 + if (!candl_dependence_gcd_test(source, target, dependence->domain, depth)) {
6441 + osl_dependence_free(dependence);
6445 - if (pip_has_rational_point (system, context, 1))
6447 - dependence = candl_dependence_malloc();
6449 - /* We set the various fields with corresponding values. */
6450 - dependence->type = type;
6451 - dependence->depth = depth;
6452 - dependence->source = source;
6453 - dependence->target = target;
6454 - dependence->ref_source = ref_s;
6455 - dependence->ref_target = ref_t;
6456 - dependence->domain = system;
6459 - candl_matrix_free(system);
6460 + if (pip_has_rational_point(dependence->domain, context, 1)) {
6461 + /* We set the various fields with corresponding values. */
6462 + dependence->ref_source = ref_s;
6463 + dependence->ref_target = ref_t;
6464 + dependence->label_source = ((candl_statement_usr_p)source->usr)->label;
6465 + dependence->label_target = ((candl_statement_usr_p)target->usr)->label;
6466 + dependence->type = type;
6467 + dependence->depth = depth;
6468 + dependence->stmt_source_ptr = source;
6469 + dependence->stmt_target_ptr = target;
6470 + dependence->ref_source_access_ptr = array_s;
6471 + dependence->ref_target_access_ptr = array_t;
6473 + osl_dependence_free(dependence);
6474 + dependence = NULL;
6479 @@ -1215,20 +782,25 @@ candl_dependence_p candl_dependence_system(CandlStatement* source,
6480 * - 07/12/2005: (debug) correction of depth bounds.
6481 * - 09/12/2005: We may take commutativity into consideration.
6483 -candl_dependence_p candl_dependence_between(CandlStatement* source,
6484 - CandlStatement* target,
6485 - CandlMatrix* context,
6486 - CandlOptions* options)
6488 - int i, j, k, min_depth, max_depth;
6489 - candl_dependence_p new;
6490 - candl_dependence_p dependence = NULL;
6491 - candl_dependence_p now;
6493 +osl_dependence_p candl_dependence_between(osl_statement_p source,
6494 + osl_statement_p target,
6495 + osl_relation_p context,
6496 + candl_options_p options) {
6497 + osl_dependence_p new;
6498 + osl_dependence_p dependence = NULL;
6499 + osl_dependence_p now;
6500 + osl_relation_list_p access_src, access_targ;
6501 + osl_relation_p elt_src, elt_targ;
6502 + candl_statement_usr_p s_usr = source->usr;
6503 + candl_statement_usr_p t_usr = target->usr;
6504 + int i, min_depth, max_depth;
6505 + int src_id, targ_id;
6508 /* If the statements commute and the user asks to use this information to
6509 * simplify the dependence graph, we return no dependences.
6511 - if (options->commute && candl_statement_commute(source, target))
6512 + if (options->commute && candl_util_statement_commute(source, target))
6515 /* In the case of a self-dependence, the dependence depth can be as low as 1
6516 @@ -1237,155 +809,209 @@ candl_dependence_p candl_dependence_between(CandlStatement* source,
6517 * In the case of different statements, the dependence depth can be as low
6518 * as 0 and as high as the number of shared loops.
6520 - if (source == target)
6523 - max_depth = source->depth;
6527 - /* Depth 0 is for statements that don't share any loop. */
6528 - min_depth = (source->index[0] == target->index[0]) ? 1 : 0;
6531 - while ((max_depth < source->depth) &&
6532 - (max_depth < target->depth) &&
6533 - (source->index[max_depth] == target->index[max_depth]))
6537 - /* Flow and output-dependences analysis. */
6538 - for (j = 0; j < source->written->NbRows; j++)
6539 - if (CANDL_notzero_p(source->written->p[j][0]))
6541 - /* Flow-dependences analysis. */
6543 - for (k = 0; k < target->read->NbRows; k++)
6544 - if (CANDL_eq(target->read->p[k][0], source->written->p[j][0]))
6545 - for (i = min_depth; i <= max_depth; i++)
6547 - new = candl_dependence_system(source, target, context,
6548 - source->written, target->read,
6549 - j, k, CANDL_RAW, i);
6550 - candl_dependence_add(&dependence, &now, new);
6552 - /* Output-dependences analysis. */
6554 - for (k = 0; k < target->written->NbRows; k++)
6555 - if (CANDL_eq(target->written->p[k][0], source->written->p[j][0]))
6556 - for (i = min_depth; i <= max_depth; i++)
6558 - new = candl_dependence_system(source, target, context,
6560 - target->written, j, k,
6562 - candl_dependence_add(&dependence, &now, new);
6566 - /* Anti and input-dependences analysis. */
6567 - for (j = 0; j < source->read->NbRows; j++)
6568 - if (source->read->p[j][0] != 0)
6570 - /* Anti-dependences analysis. */
6572 - for (k = 0; k < target->written->NbRows; k++)
6573 - if (CANDL_eq(target->written->p[k][0], source->read->p[j][0]))
6574 - for (i = min_depth; i <= max_depth; i++)
6576 - new = candl_dependence_system(source, target, context,
6577 - source->read, target->written,
6578 - j, k, CANDL_WAR, i);
6579 - candl_dependence_add(&dependence, &now, new);
6581 - /* Input-dependences analysis. */
6583 - for (k = 0; k < target->read->NbRows; k++)
6584 - if (CANDL_eq(target->read->p[k][0], source->read->p[j][0]))
6585 - for (i = min_depth; i <= max_depth; i++)
6587 - new = candl_dependence_system(source, target, context,
6588 - source->read, target->read,
6589 - j, k, CANDL_RAR, i);
6590 - candl_dependence_add(&dependence, &now, new);
6593 + if (source == target) {
6595 + max_depth = s_usr->depth;
6597 + /* Depth 0 is for statements that don't share any loop. */
6598 + if (s_usr->depth > 0 && t_usr->depth > 0)
6599 + min_depth = (s_usr->index[0] == t_usr->index[0]) ? 1 : 0;
6604 + while ((max_depth < s_usr->depth) &&
6605 + (max_depth < t_usr->depth) &&
6606 + (s_usr->index[max_depth] == t_usr->index[max_depth]))
6611 + access_src = source->access;
6613 + for (; access_src != NULL; access_src = access_src->next, ref_s++) {
6614 + elt_src = access_src->elt;
6615 + src_id = osl_relation_get_array_id(elt_src);
6617 + switch(elt_src->type) {
6619 + /* Anti and input-dependences analysis. */
6620 + case OSL_TYPE_READ: /* source READ */
6621 + if (!options->war && !options->rar)
6623 + access_targ = target->access;
6625 + for (; access_targ != NULL; access_targ = access_targ->next, ref_t++) {
6626 + elt_targ = access_targ->elt;
6627 + targ_id = osl_relation_get_array_id(elt_targ);
6629 + /* Anti-dependences analysis. */
6630 + if (elt_targ->type != OSL_TYPE_READ) { /* target WRITE | MAY_WRITE */
6631 + if (options->war && src_id == targ_id) {
6632 + for (i = min_depth; i <= max_depth; i++) {
6633 + new = candl_dependence_system(source, target, context,
6634 + elt_src, elt_targ,
6636 + OSL_DEPENDENCE_WAR, i);
6637 + osl_dependence_add(&dependence, &now, new);
6641 + /* Input-dependences analysis. */
6642 + else { /* target READ */
6643 + if (options->rar && src_id == targ_id) {
6644 + for (i = min_depth; i <= max_depth; i++) {
6645 + new = candl_dependence_system(source, target, context,
6646 + elt_src, elt_targ,
6648 + OSL_DEPENDENCE_RAR, i);
6649 + osl_dependence_add(&dependence, &now, new);
6656 + default: /* source WRITE | MAY-WRITE */
6657 + if (!options->raw && !options->waw)
6659 + access_targ = target->access;
6661 + for (; access_targ != NULL; access_targ = access_targ->next, ref_t++) {
6662 + elt_targ = access_targ->elt;
6663 + targ_id = osl_relation_get_array_id(elt_targ);
6665 + /* Anti-dependences analysis. */
6666 + if (elt_targ->type != OSL_TYPE_READ) { /* target WRITE | MAY_WRITE */
6667 + if (options->waw && src_id == targ_id) {
6668 + for (i = min_depth; i <= max_depth; i++) {
6669 + new = candl_dependence_system(source, target, context,
6670 + elt_src, elt_targ,
6672 + OSL_DEPENDENCE_WAW, i);
6673 + osl_dependence_add(&dependence, &now, new);
6677 + /* Input-dependences analysis. */
6678 + else { /* target READ */
6679 + if (options->raw && src_id == targ_id) {
6680 + for (i = min_depth; i <= max_depth; i++) {
6681 + new = candl_dependence_system(source, target, context,
6682 + elt_src, elt_targ,
6684 + OSL_DEPENDENCE_RAW, i);
6685 + osl_dependence_add(&dependence, &now, new);
6702 * candl_dependence function:
6703 - * this function builds the dependence graph of a program (program)
6704 + * this function builds the dependence graph of a scop
6705 * according to some user options (options).
6706 * - 18/09/2003: first version.
6708 -candl_dependence_p candl_dependence(candl_program_p program,
6709 - CandlOptions* options)
6712 - candl_dependence_p dependence = NULL;
6713 - candl_dependence_p new = NULL;
6714 - candl_dependence_p now;
6715 - CandlStatement ** statement;
6716 - CandlMatrix * context;
6718 - statement = program->statement;
6719 - context = program->context;
6720 +osl_dependence_p candl_dependence(osl_scop_p scop, candl_options_p options) {
6721 + if (scop == NULL) { return NULL; }
6723 + osl_dependence_p dependence = NULL;
6724 + osl_dependence_p new = NULL;
6725 + osl_dependence_p now;
6726 + osl_statement_p stmt_i, stmt_j;
6727 + osl_relation_p context = scop->context;
6729 if (options->scalar_privatization || options->scalar_expansion)
6730 - candl_dependence_analyze_scalars (program, options);
6732 - for (i = 0; i < program->nb_statements; i++)
6733 - { /* We add self dependence. */
6735 - new = candl_dependence_between(statement[i], statement[i],
6736 - context, options);
6737 - candl_dependence_add(&dependence, &now, new);
6739 - for (j = i + 1; j < program->nb_statements; j++)
6740 - { /* And dependences with other statements. */
6742 - new = candl_dependence_between(statement[i], statement[j],
6743 - context, options);
6744 - candl_dependence_add(&dependence, &now, new);
6747 - new = candl_dependence_between(statement[j], statement[i],
6748 - context, options);
6749 - candl_dependence_add(&dependence, &now, new);
6751 + candl_dependence_analyze_scalars(scop, options);
6753 + stmt_i = scop->statement;
6754 + for (; stmt_i != NULL; stmt_i = stmt_i->next) {
6755 + /* We add self dependence. */
6757 + new = candl_dependence_between(stmt_i, stmt_i, context, options);
6758 + osl_dependence_add(&dependence, &now, new);
6760 + stmt_j = stmt_i->next;
6761 + for (; stmt_j != NULL; stmt_j = stmt_j ->next) {
6762 + /* And dependences with other statements. */
6764 + new = candl_dependence_between(stmt_i, stmt_j, context, options);
6765 + osl_dependence_add(&dependence, &now, new);
6768 + new = candl_dependence_between(stmt_j, stmt_i, context, options);
6769 + osl_dependence_add(&dependence, &now, new);
6774 /* If scalar analysis is called, remove some useless dependences. */
6775 /* LNP: This is subsubmed by the updated prune-with-privatization function. */
6776 - /* if (options->scalar_privatization || options->scalar_expansion || */
6777 - /* options->scalar_renaming) */
6778 - /* candl_dependence_prune_scalar_waw (program, options, &dependence); */
6779 + /* if (options->scalar_privatization || options->scalar_expansion || */
6780 + /* options->scalar_renaming) */
6781 + /* candl_dependence_prune_scalar_waw(scop, options, &dependence); */
6783 /* Final treatment for scalar analysis. */
6785 if (options->scalar_renaming)
6786 - check = candl_dependence_scalar_renaming (program, options, &dependence);
6787 + check = candl_dependence_scalar_renaming(scop, options, &dependence);
6789 if (! check && options->scalar_privatization)
6790 - candl_dependence_prune_with_privatization (program, options, &dependence);
6791 + candl_dependence_prune_with_privatization(scop, options, &dependence);
6793 /* Compute the last writer */
6794 - if (options->lastwriter) {
6795 - candl_compute_last_writer(dependence, program);
6797 + if (options->lastwriter)
6798 + candl_compute_last_writer(dependence, scop);
6800 + #if defined(CANDL_COMPILE_PRUNNING_C)
6801 /* Remove some transitively covered dependences (experimental). */
6802 if (options->prune_dups)
6803 - dependence = candl_dependence_prune_transitively_covered (dependence);
6804 + dependence = candl_dependence_prune_transitively_covered(dependence);
6813 + * candl_dependence_add_extension function:
6814 + * this function builds the dependence graph for a scop list
6815 + * according to some user options (options).
6816 + * For each scop the dependence graph is added in the extension of the scop.
6817 + * Any old dependence graph in the extension is deleted.
6819 + * @param[in,out] scop A osl scop
6820 + * @param[in] options Candl options
6822 +void candl_dependence_add_extension(osl_scop_p scop, candl_options_p options) {
6825 + /* Calculating dependences. */
6826 + osl_dependence_p dep = osl_generic_lookup(scop->extension,
6827 + OSL_URI_DEPENDENCE);
6828 + if (dep != NULL) {
6829 + osl_generic_remove(&scop->extension, OSL_URI_DEPENDENCE);
6830 + CANDL_info("Deleting old dependences found in the options tag.");
6833 + dep = candl_dependence(scop, options);
6835 + osl_generic_p data = osl_generic_shell(dep, osl_dependence_interface());
6836 + data->next = scop->extension;
6837 + scop->extension = data;
6839 + scop = scop->next;
6843 /******************************************************************************
6844 * Scalar analysis functions *
6845 ******************************************************************************/
6846 @@ -1393,29 +1019,39 @@ candl_dependence_p candl_dependence(candl_program_p program,
6848 * candl_dependence_var_is_scalar function:
6849 * This function returns true if the variable indexed by 'var_index'
6850 - * is a scalar in the whole program.
6851 + * is a scalar in the whole scop.
6854 -candl_dependence_var_is_scalar (candl_program_p program, int var_index)
6859 - for (i = 0; i < program->nb_statements; ++i)
6860 - for (m = program->statement[i]->read, cpt = 0; cpt < 2; ++cpt,
6861 - m = program->statement[i]->written)
6862 - for (j = 0; j < m->NbRows; ++j)
6863 - if (CANDL_get_si(m->p[j][0]) == var_index)
6865 - /* Ensure it is not an array. */
6866 - if (j < m->NbRows - 1 && CANDL_get_si(m->p[j + 1][0]) == 0)
6868 - /* Ensure the access function is '0'. */
6869 - for (k = 1; k < m->NbColumns; ++k)
6870 - if (CANDL_get_si(m->p[j][k]) != 0)
6874 +int candl_dependence_var_is_scalar(osl_scop_p scop, int var_index) {
6875 + osl_statement_p statement;
6876 + osl_relation_list_p access;
6877 + osl_relation_p elt;
6878 + int precision = scop->context->precision;
6882 + statement = scop->statement;
6883 + while (statement != NULL) {
6884 + access = statement->access;
6885 + while (access != NULL) {
6886 + elt = access->elt;
6887 + id = osl_relation_get_array_id(elt);
6888 + row = candl_util_relation_get_line(elt, 0);
6889 + if (id == var_index) {
6890 + /* Ensure it is not an array. */
6891 + if (elt->nb_output_dims > 1)
6893 + /* Ensure the access function is '0'. */
6894 + if (!osl_int_zero(precision, elt->m[row][0]))
6896 + for (i = 2; i < elt->nb_columns-2; ++i) /* jmp the 'Arr' */
6897 + if (!osl_int_zero(precision, elt->m[row][i]))
6900 + access = access->next;
6902 + statement = statement->next;
6908 @@ -1427,61 +1063,33 @@ candl_dependence_var_is_scalar (candl_program_p program, int var_index)
6909 * variable in the statement list.
6914 -candl_dependence_expand_scalar(CandlStatement** sl,
6919 +static void candl_dependence_expand_scalar(osl_statement_p* sl,
6921 + osl_relation_list_p access;
6922 + osl_relation_p elt;
6924 + int precision = sl[0]->scattering->precision;
6927 /* Iterate on all statements of the list. */
6928 - for (i = 0; sl[i] != NULL; ++i)
6930 - /* Check if the scalar is referenced in the 'read' access
6932 - for (j = 0; j < sl[i]->read->NbRows &&
6933 - CANDL_get_si(sl[i]->read->p[j][0]) != scalar_idx; ++j)
6936 - if (j < sl[i]->read->NbRows)
6938 - /* Add a row to the 'read' matrix, just after the reference
6939 - to 'scalar_idx'. */
6940 - m = candl_matrix_malloc (sl[i]->read->NbRows +1,
6941 - sl[i]->read->NbColumns);
6942 - for (l = 0; l <= j; ++l)
6943 - for (n = 0; n < m->NbColumns; ++n)
6944 - CANDL_assign(m->p[l][n], sl[i]->read->p[l][n]);
6945 - for (++l; l < m->NbRows; ++l)
6946 - for (n = 0; n < m->NbColumns; ++n)
6947 - CANDL_assign(m->p[l][n], sl[i]->read->p[l - 1][n]);
6948 - for (n = 0; n < m->NbColumns; ++n)
6949 - CANDL_set_si(m->p[j + 1][n], 0);
6950 - candl_matrix_free (sl[i]->read);
6954 - /* Same for 'written' access function. */
6955 - for (j = 0; j < sl[i]->written->NbRows &&
6956 - CANDL_get_si(sl[i]->written->p[j][0]) != scalar_idx;++j)
6958 - if (j < sl[i]->written->NbRows)
6960 - m = candl_matrix_malloc (sl[i]->written->NbRows +1,
6961 - sl[i]->written->NbColumns);
6962 - for (l = 0; l <= j; ++l)
6963 - for (n = 0; n < m->NbColumns; ++n)
6964 - CANDL_assign(m->p[l][n], sl[i]->written->p[l][n]);
6965 - for (++l; l < m->NbRows; ++l)
6966 - for (n = 0; n < m->NbColumns; ++n)
6967 - CANDL_assign(m->p[l][n], sl[i]->written->p[l - 1][n]);
6968 - for (n = 0; n < m->NbColumns; ++n)
6969 - CANDL_set_si(m->p[j + 1][n], 0);
6970 - candl_matrix_free (sl[i]->written);
6971 - sl[i]->written = m;
6973 + for (i = 0; sl[i] != NULL; ++i) {
6975 + /* Check if the scalar is referenced in the 'read' access
6977 + access = sl[i]->access;
6978 + for (; access != NULL ; access = access->next) {
6979 + elt = access->elt;
6980 + id = osl_relation_get_array_id(elt);
6981 + row = candl_util_relation_get_line(elt, 0);
6982 + if (id == scalar_idx) {
6983 + row = elt->nb_rows;
6984 + osl_relation_insert_blank_row(elt, row);
6985 + osl_relation_insert_blank_column(elt, 1 + elt->nb_output_dims);
6986 + osl_int_set_si(precision, &elt->m[row][1 + elt->nb_output_dims], -1);
6987 + elt->nb_output_dims++;
6994 @@ -1490,51 +1098,70 @@ candl_dependence_expand_scalar(CandlStatement** sl,
6995 * This function returns a chain of statements as a feshly allocated
6996 * array of pointer on statements, of all statements reading or
6997 * writing the variable 'var_index', surrounded by the 'level' common
6998 - * loops of 'dom'. Output is a NULL-terminated array.
7000 + * Output is a NULL-terminated array. We don't create a chained list,
7001 + * because it demands to clone every statements each time, and we need
7002 + * to clone the field usr too.
7005 -candl_dependence_refvar_chain(candl_program_p program, CandlStatement* dom,
7006 - int var_index, int level)
7008 - /* No or empty program -> no chain! */
7009 - if (program == NULL || program->nb_statements == 0)
7010 +osl_statement_p* candl_dependence_refvar_chain(osl_scop_p scop,
7011 + osl_statement_p dom, int var_index, int level) {
7012 + /* No or empty scop -> no chain! */
7013 + if (scop == NULL || scop->statement == NULL)
7016 + osl_statement_p* res; /* not a chained list, but an array of statement */
7017 + osl_statement_p statement;
7018 + candl_statement_usr_p dom_usr;
7019 + candl_statement_usr_p stmt_usr;
7021 int buffer_size = 64;
7022 - CandlStatement** res =
7023 - (CandlStatement**) malloc(buffer_size * sizeof(CandlStatement*));
7024 - int i, j, count = 0;
7025 - CandlStatement* s;
7028 /* If no dominator is provided, assume we start with the first statement. */
7030 - dom = program->statement[0];
7031 - for (i = 0; i < program->nb_statements && program->statement[i] != dom; ++i)
7033 + dom = scop->statement;
7035 + dom_usr = dom->usr;
7037 + statement = scop->statement;
7038 + while (statement != NULL && statement != dom)
7039 + statement = statement->next;
7041 /* The dominator is not in the list of statements. */
7042 - if (i == program->nb_statements)
7043 + if (statement == NULL)
7045 - for (; i < program->nb_statements; ++i)
7047 - s = program->statement[i];
7048 - /* We look for exactly 'level' common loops. */
7049 - if (s->depth < level)
7051 - /* Ensure it has 'level' common loop(s) with the dominator. */
7052 - for (j = 0; j < level&& s->index[j] == dom->index[j]; ++j)
7056 - /* Ensure the variable is referenced. */
7057 - if (candl_dependence_var_is_ref (s, var_index) != CANDL_VAR_UNDEF)
7060 - if (count == buffer_size)
7061 - res = realloc(res, (buffer_size*=2) * sizeof(CandlStatement*));
7064 + CANDL_malloc(res, osl_statement_p*, sizeof(osl_statement_p) * buffer_size);
7066 + for (; statement != NULL; statement = statement->next) {
7067 + stmt_usr = statement->usr;
7069 + /* We look for exactly 'level' common loops. */
7070 + if (stmt_usr->depth < level)
7073 + /* Ensure it has 'level' common loop(s) with the dominator. */
7074 + for (i = 0; i < level &&
7075 + stmt_usr->index[i] == dom_usr->index[i];
7082 + /* Ensure the variable is referenced. */
7083 + if (candl_dependence_var_is_ref(statement, var_index) != CANDL_VAR_UNDEF) {
7084 + if (count == buffer_size) {
7086 + CANDL_realloc(res, osl_statement_p*,
7087 + sizeof(osl_statement_p) * buffer_size);
7089 + res[count++] = statement;
7093 - res = realloc(res, (count + 1) * sizeof(CandlStatement*));
7094 + CANDL_realloc(res, osl_statement_p*,
7095 + sizeof(osl_statement_p) * (count+1));
7099 @@ -1546,30 +1173,44 @@ candl_dependence_refvar_chain(candl_program_p program, CandlStatement* dom,
7100 * This function checks if a var 'var_index' is referenced (DEF or
7101 * USE) by the statement.
7104 -candl_dependence_var_is_ref(CandlStatement* s, int var_index)
7107 +int candl_dependence_var_is_ref(osl_statement_p s, int var_index) {
7108 + osl_relation_list_p access;
7109 + osl_relation_p elt;
7111 int ret = CANDL_VAR_UNDEF;
7115 - for (j = 0; s->read && j < s->read->NbRows; ++j)
7116 - if (CANDL_get_si(s->read->p[j][0]) == var_index)
7118 - ret = CANDL_VAR_IS_USED;
7121 - for (j = 0; s->written && j < s->written->NbRows; ++j)
7122 - if (CANDL_get_si(s->written->p[j][0]) == var_index)
7124 - if (ret == CANDL_VAR_IS_USED)
7125 - ret = CANDL_VAR_IS_DEF_USED;
7127 - ret = CANDL_VAR_IS_DEF;
7133 + access = s->access;
7134 + while (access != NULL) {
7135 + elt = access->elt;
7136 + if (elt->type == OSL_TYPE_READ) {
7137 + id = osl_relation_get_array_id(elt);
7138 + if (id == var_index) {
7139 + ret = CANDL_VAR_IS_USED;
7143 + access = access->next;
7146 + /* right access */
7147 + access = s->access;
7148 + while (access != NULL) {
7149 + elt = access->elt;
7150 + if (elt->type != OSL_TYPE_READ) {
7151 + id = osl_relation_get_array_id(elt);
7152 + if (id == var_index) {
7153 + if (ret == CANDL_VAR_IS_USED)
7154 + ret = CANDL_VAR_IS_DEF_USED;
7156 + ret = CANDL_VAR_IS_DEF;
7160 + access = access->next;
7166 @@ -1580,29 +1221,26 @@ candl_dependence_var_is_ref(CandlStatement* s, int var_index)
7167 * This function assigns to the Entier 'lb' the lexmin of variable
7168 * 'col'-1 in the polyhedron 'm'.
7172 -candl_dependence_compute_lb (CandlMatrix* m, Entier* lb, int col)
7174 +static void candl_dependence_compute_lb(osl_relation_p m, Entier* lb, int col) {
7175 PipOptions* options;
7178 - options = pip_options_init ();
7179 + options = pip_options_init();
7180 options->Simplify = 1;
7181 options->Urs_parms = -1;
7182 options->Urs_unknowns = -1;
7183 /* Compute lexmin. */
7184 - solution = pip_solve (m, NULL, -1, options);
7185 + solution = pip_solve_osl(m, NULL, -1, options);
7187 if ((solution != NULL) &&
7188 - ((solution->list != NULL) || (solution->condition != NULL)))
7190 - l = solution->list;
7193 - CANDL_assign(*lb, l->vector->the_vector[0]);
7195 - pip_options_free (options);
7196 - pip_quast_free (solution);
7197 + ((solution->list != NULL) || (solution->condition != NULL))) {
7198 + l = solution->list;
7201 + CANDL_assign(*lb, l->vector->the_vector[0]);
7203 + pip_options_free(options);
7204 + pip_quast_free(solution);
7208 @@ -1613,66 +1251,95 @@ candl_dependence_compute_lb (CandlMatrix* m, Entier* lb, int col)
7209 * considered iterator dimensions.
7213 -candl_dependence_check_domain_is_included(CandlStatement* s1,
7214 - CandlStatement* s2,
7215 - CandlMatrix* context,
7218 +int candl_dependence_check_domain_is_included(osl_statement_p s1,
7219 + osl_statement_p s2,
7220 + osl_relation_p context,
7222 + candl_statement_usr_p s1_usr = s1->usr;
7223 + candl_statement_usr_p s2_usr = s2->usr;
7224 + osl_relation_p matrix;
7226 - Entier lb; CANDL_init(lb);
7227 - max = s1->depth < max ? s1->depth : max;
7228 - max = s2->depth < max ? s2->depth : max;
7229 - CandlMatrix* m = candl_matrix_malloc(s2->domain->NbRows + s2->depth - max +1,
7230 - s2->domain->NbColumns);
7232 + int precision = s2->domain->precision;
7237 + osl_int_init(precision, &osl_lb);
7239 + if (s1_usr->depth < max) max = s1_usr->depth;
7240 + if (s2_usr->depth < max) max = s2_usr->depth;
7242 + matrix = osl_relation_pmalloc(precision,
7243 + s2->domain->nb_rows + s2_usr->depth - max + 1,
7244 + s2->domain->nb_columns);
7246 /* Duplicate s2 to the dest matrix. */
7247 - for (i = 0; i < s2->domain->NbRows; ++i)
7248 - for (j = 0; j < s2->domain->NbColumns; ++j)
7249 - CANDL_assign(m->p[i][j], s2->domain->p[i][j]);
7250 + for (i = 0; i < s2->domain->nb_rows; ++i) {
7251 + for (j = 0; j < s2->domain->nb_columns; ++j)
7252 + osl_int_assign(precision,
7253 + &matrix->m[i][j], s2->domain->m[i][j]);
7256 /* Make useless dimensions equal to 1. */
7257 - for (j = 0; j < s2->depth - max; ++j)
7259 - candl_dependence_compute_lb (s2->domain, &lb, j + 1 + max);
7260 - CANDL_assign(m->p[i][m->NbColumns - 1], lb);
7261 - CANDL_set_si(m->p[i++][j + 1 + max], -1);
7263 + for (j = 0; j < s2_usr->depth - max; ++j) {
7264 + candl_dependence_compute_lb(s2->domain, &lb, j + 1 + max);
7265 + #ifdef CANDL_LINEAR_VALUE_IS_INT
7267 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
7269 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
7270 + mpz_set(*((mpz_t*)osl_lb.mp), lb);
7272 + osl_int_assign(precision,
7273 + &matrix->m[i][matrix->nb_columns - 1], osl_lb);
7274 + osl_int_set_si(precision,
7275 + &matrix->m[i++][j+1+max], -1);
7278 /* Iterate on all constraints of s1, and check them. */
7279 - for (i = 0; i < s1->domain->NbRows; ++i)
7281 - /* Skip constraints defining other iterators. */
7282 - for (j = max + 1; j <= s1->depth; ++j)
7283 - if (CANDL_get_si(s1->domain->p[i][j]) != 0)
7285 - if (j <= s1->depth)
7287 - /* Invert the constraint, and add it to m. */
7288 - for (j = 0; j <= max; ++j)
7290 - CANDL_assign(m->p[m->NbRows - 1][j], s1->domain->p[i][j]);
7291 - CANDL_oppose(m->p[m->NbRows - 1][j], m->p[m->NbRows - 1][j]);
7293 - for (j = s1->depth + 1; j < s1->domain->NbColumns; ++j)
7295 - CANDL_assign(m->p[m->NbRows - 1][j - s1->depth + s2->depth],
7296 - s1->domain->p[i][j]);
7297 - CANDL_oppose(m->p[m->NbRows - 1][j - s1->depth + s2->depth],
7298 - m->p[m->NbRows - 1][j - s1->depth + s2->depth]);
7300 - /* Make the inequality strict. */
7301 - CANDL_decrement(m->p[m->NbRows - 1][m->NbColumns - 1],
7302 - m->p[m->NbRows - 1][m->NbColumns - 1]);
7303 - if (candl_matrix_check_point (m, context))
7305 - /* There is a point. dom(s1) - dom(s2) > 0. */
7307 - candl_matrix_free(m);
7310 + for (i = 0; i < s1->domain->nb_rows; ++i) {
7311 + /* Skip constraints defining other iterators. */
7312 + for (j = max + 1; j <= s1_usr->depth; ++j) {
7313 + if (!osl_int_zero(precision, s1->domain->m[i][j]))
7316 + if (j <= s1_usr->depth)
7318 + /* Invert the constraint, and add it to matrix. */
7319 + for (j = 0; j <= max; ++j) {
7320 + osl_int_assign(precision,
7321 + &matrix->m[matrix->nb_rows - 1][j],
7322 + s1->domain->m[i][j]);
7323 + osl_int_oppose(precision,
7324 + &matrix->m[matrix->nb_rows - 1][j],
7325 + matrix->m[matrix->nb_rows - 1][j]);
7327 + for (j = s1_usr->depth + 1; j < s1->domain->nb_columns; ++j) {
7328 + osl_int_assign(precision,
7329 + &matrix->m[matrix->nb_rows - 1][j - s1_usr->depth + s2_usr->depth],
7330 + s1->domain->m[i][j]);
7331 + osl_int_oppose(precision,
7332 + &matrix->m[matrix->nb_rows - 1][j - s1_usr->depth + s2_usr->depth],
7333 + matrix->m[matrix->nb_rows - 1][j - s1_usr->depth + s2_usr->depth]);
7335 + /* Make the inequality strict. */
7336 + osl_int_decrement(precision,
7337 + &matrix->m[matrix->nb_rows - 1][matrix->nb_columns - 1],
7338 + matrix->m[matrix->nb_rows - 1][matrix->nb_columns - 1]);
7340 + if (candl_matrix_check_point(matrix, context)) {
7341 + /* There is a point. dom(s1) - dom(s2) > 0. */
7343 + osl_int_clear(precision, &osl_lb);
7344 + osl_relation_free(matrix);
7350 - candl_matrix_free(m);
7351 + osl_int_clear(precision, &osl_lb);
7352 + osl_relation_free(matrix);
7356 @@ -1680,49 +1347,48 @@ candl_dependence_check_domain_is_included(CandlStatement* s1,
7359 * candl_dependence_extract_scalar_variables function:
7360 - * This functions returns a -1-terminated array of the program scalar
7361 + * This functions returns a -1-terminated array of the scop scalar
7365 -candl_dependence_extract_scalar_variables (candl_program_p program)
7367 - /* FIXME: implement a real buffer. */
7368 - int scalars[1024];
7369 +int* candl_dependence_extract_scalar_variables(osl_scop_p scop) {
7370 + osl_statement_p statement;
7371 + osl_relation_p elt;
7372 + osl_relation_list_p access;
7373 + int scalars[1024]; /* FIXME: implement a real buffer. */
7375 - int i, j, k, idx, cpt;
7377 int count_s = 0, count_c = 0;
7381 /* Detect all scalar variables. */
7382 - for (i = 0; i < program->nb_statements; ++i)
7383 - for (m = program->statement[i]->read, cpt = 0; cpt < 2; ++cpt,
7384 - m = program->statement[i]->written)
7385 - for (j = 0; j < m->NbRows; ++j)
7387 - idx = CANDL_get_si(m->p[j][0]);
7390 - for (k = 0; k < count_s && scalars[k] != idx; ++k)
7394 - for (k = 0; k < count_c && checked[k] != idx; ++k)
7398 - if (candl_dependence_var_is_scalar(program, idx))
7399 - scalars[count_s++] = idx;
7401 - checked[count_c++] = idx;
7403 - if (count_s == 1024 || count_c == 1024)
7404 - CANDL_FAIL("Error: Buffer size too small");
7409 + statement = scop->statement;
7410 + while (statement != NULL) {
7411 + access = statement->access;
7412 + while (access != NULL) {
7413 + elt = access->elt;
7414 + idx = osl_relation_get_array_id(elt);
7416 + for (i = 0; i < count_s && scalars[i] != idx; ++i)
7418 + if (i == count_s) {
7419 + for (i = 0; i < count_c && checked[i] != idx; ++i)
7421 + if (i == count_c) {
7422 + if (candl_dependence_var_is_scalar(scop, idx))
7423 + scalars[count_s++] = idx;
7425 + checked[count_c++] = idx;
7427 + if (count_s == 1024 || count_c == 1024)
7428 + CANDL_error("Error: Buffer size too small");
7430 + access = access->next;
7432 + statement = statement->next;
7435 /* Rearrange the array to the exact size. */
7436 - int* res = (int*) malloc((count_s + 1) * sizeof(int));
7438 + CANDL_malloc(res, int*, (count_s + 1) * sizeof(int));
7439 for (i = 0; i < count_s; ++i)
7440 res[i] = scalars[i];
7442 @@ -1732,88 +1398,46 @@ candl_dependence_extract_scalar_variables (candl_program_p program)
7446 - * candl_dependence_get_array_refs_in_dep function:
7447 - * This function return the array indices referenced in the
7452 -candl_dependence_get_array_refs_in_dep (CandlDependence* tmp, int* refs,
7457 - switch (tmp->type)
7460 - *refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
7461 - *reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
7464 - case CANDL_RAW_SCALPRIV:
7465 - *refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
7466 - *reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
7469 - *refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
7470 - *reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
7473 - *refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
7474 - *reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
7483 - * candl_dependence_prune_scalar_waw function:
7484 + * osl_dependence_prune_scalar_waw function:
7485 * This function removes all WAW dependences between the same scalar
7486 * (they are useless dependences).
7489 -candl_dependence_prune_scalar_waw (candl_program_p program,
7490 - CandlOptions* options,
7491 - CandlDependence** deps)
7493 +void osl_dependence_prune_scalar_waw(osl_scop_p scop,
7494 + candl_options_p options,
7495 + osl_dependence_p* deps) {
7499 - CandlDependence* tmp;
7500 - CandlDependence* next;
7501 - CandlDependence* pred = NULL;
7502 + osl_dependence_p tmp;
7503 + osl_dependence_p next;
7504 + osl_dependence_p pred = NULL;
7506 if (options->verbose)
7507 fprintf (stderr, "[Candl] Scalar Analysis: Remove all WAW between the same"
7510 - scalars = candl_dependence_extract_scalar_variables (program);
7512 - for (tmp = *deps; tmp; )
7514 - candl_dependence_get_array_refs_in_dep (tmp, &refs, &reft);
7515 - if (refs == reft && tmp->type == CANDL_WAW)
7517 - for (i = 0; scalars[i] != -1 && scalars[i] != refs; ++i)
7519 - if (scalars[i] != -1)
7521 - candl_matrix_free (tmp->domain);
7526 - pred->next = next;
7536 + scalars = candl_dependence_extract_scalar_variables(scop);
7538 + for (tmp = *deps; tmp; ) {
7539 + candl_dependence_get_array_refs_in_dep(tmp, &refs, &reft);
7540 + if (refs == reft && tmp->type == OSL_DEPENDENCE_WAW) {
7541 + for (i = 0; scalars[i] != -1 && scalars[i] != refs; ++i)
7543 + if (scalars[i] != -1) {
7544 + osl_relation_free(tmp->domain);
7549 + pred->next = next;
7561 @@ -1824,160 +1448,189 @@ candl_dependence_prune_scalar_waw (candl_program_p program,
7562 * This function renames scalars in the program. In case scalars have
7563 * been renamed, the dependence analysis is re-run.
7566 -candl_dependence_scalar_renaming (candl_program_p program,
7567 - CandlOptions* options,
7568 - CandlDependence** deps)
7570 +int candl_dependence_scalar_renaming(osl_scop_p scop,
7571 + candl_options_p options,
7572 + osl_dependence_p* deps) {
7573 + osl_statement_p *statement; /* not a chained list */
7574 + osl_statement_p iter;
7575 + osl_statement_p defs[1024];
7576 + osl_statement_p uses[1024];
7577 + osl_statement_p last_def;
7578 + osl_statement_p *current; /* not a chained list */
7579 + osl_relation_p elt;
7580 + osl_relation_list_p access;
7581 + candl_statement_usr_p usr;
7582 + candl_statement_usr_p last_usr;
7584 - CandlStatement** stmts;
7585 - CandlStatement* defs[1024];
7586 - CandlStatement* uses[1024];
7587 - CandlStatement* current[program->nb_statements];
7588 - int parts[program->nb_statements];
7589 - CandlStatement* s;
7590 - CandlStatement* last_def;
7592 + int nb_statements = 0;
7595 - int val, cpt, tmp, has_changed = 0;
7597 + int precision = scop->context->precision;
7599 + int tmp, has_changed = 0;
7602 - for (i = 0; i < program->nb_statements; ++i)
7603 - current[i] = NULL;
7605 if (options->verbose)
7606 fprintf (stderr, "[Candl] Scalar Analysis: Perform scalar renaming\n");
7609 /* Compute the first free variable index seed. */
7610 - for (i = 0; i < program->nb_statements; ++i)
7611 - for (m = program->statement[i]->read, cpt = 0; cpt < 2;
7612 - ++cpt, m = program->statement[i]->written)
7613 - for (j = 0; j < m->NbRows; ++j)
7614 - if (CANDL_get_si(m->p[j][0]) >= newvar)
7615 - newvar = CANDL_get_si(m->p[j][0]) + 1;
7616 + for (iter = scop->statement; iter != NULL; iter = iter->next) {
7617 + access = iter->access;
7618 + for (; access != NULL; access = access->next) {
7619 + elt = access->elt;
7620 + tmp = osl_relation_get_array_id(elt);
7621 + if (tmp >= newvar)
7628 + CANDL_malloc(current, osl_statement_p*, sizeof(osl_statement_p) * nb_statements);
7629 + CANDL_malloc(parts, int*, sizeof(int) * nb_statements);
7631 /* Get the list of scalars. */
7632 - int* scalars = candl_dependence_extract_scalar_variables (program);
7633 + scalars = candl_dependence_extract_scalar_variables(scop);
7635 /* Iterate on all scalars. */
7636 - for (i = 0; scalars[i] != -1; ++i)
7638 - /* Get all statements referencing the scalar. */
7639 - stmts = candl_dependence_refvar_chain (program, NULL, scalars[i], 0);
7641 - /* If the chain starts by a USE, we can't do anything. */
7642 - if (stmts[0] == NULL || candl_dependence_var_is_ref (stmts[0], scalars[i])
7643 - != CANDL_VAR_IS_DEF)
7649 - /* Get all defs. */
7650 - for (j = 0, defs_c = 0; stmts[j]; ++j)
7651 - if (candl_dependence_var_is_ref (stmts[j], scalars[i])
7652 - == CANDL_VAR_IS_DEF)
7653 - defs[defs_c++] = stmts[j];
7654 - /* Get all uses. */
7655 - for (j = 0, uses_c = 0; stmts[j]; ++j)
7657 - val = candl_dependence_var_is_ref (stmts[j], scalars[i]);
7658 - if (val == CANDL_VAR_IS_USED || val == CANDL_VAR_IS_DEF_USED)
7659 - uses[uses_c++] = stmts[j];
7662 - /* Clean buffer. */
7663 - for (j = 0; j < program->nb_statements; ++j)
7664 - current[j] = NULL;
7668 - /* Iterate on all DEFs. */
7669 - for (j = 0, last_def = NULL; j < defs_c; ++j)
7671 - if (last_def == NULL)
7672 - last_def = defs[j];
7675 - /* Ensure the current DEF covers all iterations covered
7676 - by the last checked one. */
7677 - for (k = 0; k < last_def->depth && k < defs[j]->depth &&
7678 - last_def->index[k] == defs[j]->index[k]; ++k)
7680 - /* We only need to check when there are common loops. */
7681 - if (k && ! candl_dependence_check_domain_is_included
7682 - (last_def, defs[j], program->context, k + 1))
7684 - current[defs[j]->label] = last_def;
7688 - last_def = defs[j];
7690 - /* Create DEF-USE table. */
7691 - for (k = 0; k < uses_c; ++k)
7692 - if (uses[k]->label > defs[j]->label)
7693 - current[uses[k]->label] = defs[j];
7696 - /* Initialize partition table. */
7697 - for (j = 0; j < program->nb_statements; ++j)
7700 - /* Create partitions. */
7701 - for (j = 0; j < defs_c; ++j)
7702 - for (k = 0; k < program->nb_statements; ++k)
7703 - if ((current[k] && current[k] == defs[j]) ||
7704 - (k == defs[j]->label && current[defs[j]->label] == NULL))
7707 - /* Check if it is needed to rename the scalar. */
7708 - for (j = 0, tmp = -1; j < program->nb_statements; ++j)
7711 - if (parts[j] != -1)
7715 - if (parts[j] != -1 && tmp != parts[j])
7718 - /* Rename scalar variable. */
7719 - if (j != program->nb_statements)
7720 - for (j = 0, tmp = -1; j < program->nb_statements; ++j)
7721 - if (parts[j] != -1)
7726 - if (tmp != parts[j])
7728 - s = program->statement[j];
7729 - for (m = s->read, cpt = 0; cpt < 2; ++cpt, m = s->written)
7730 - for (k = 0; k < m->NbRows; ++k)
7731 - if (CANDL_get_si(m->p[k][0]) == scalars[i])
7733 - if (options->verbose)
7734 - fprintf (stderr, "[Candl] Scalar analysis: Renamed "
7735 - "variable %d to %d at statement S%d\n",
7736 - scalars[i], newvar + parts[j], j);
7737 - CANDL_set_si(m->p[k][0], newvar + parts[j]);
7740 + for (i = 0; scalars[i] != -1; ++i) {
7741 + /* Get all statements referencing the scalar. */
7742 + statement = candl_dependence_refvar_chain(scop, NULL, scalars[i], 0);
7744 + /* If the chain starts by a USE, we can't do anything. */
7745 + if (statement[0] == NULL ||
7746 + candl_dependence_var_is_ref(statement[0], scalars[i])
7747 + != CANDL_VAR_IS_DEF) {
7752 - /* Redo the full dependence analysis, if needed. */
7755 - int bopt = options->scalar_renaming;
7756 - options->scalar_renaming = 0;
7757 - if (options->scalar_privatization)
7758 - free (program->scalars_privatizable);
7759 - candl_dependence_free (*deps);
7760 - *deps = candl_dependence (program, options);
7761 - options->scalar_renaming = bopt;
7762 + /* Get all defs and all uses. */
7765 + for (j = 0; statement[j]; ++j) {
7766 + tmp = candl_dependence_var_is_ref(statement[j], scalars[i]);
7768 + case CANDL_VAR_IS_USED:
7769 + case CANDL_VAR_IS_DEF_USED:
7770 + uses[uses_c++] = statement[j];
7772 + case CANDL_VAR_IS_DEF:
7773 + defs[defs_c++] = statement[j];
7778 + /* Clean buffer. */
7780 + for (iter = scop->statement; iter != NULL; iter = iter->next)
7781 + current[j++] = NULL;
7785 + /* Iterate on all DEFs. */
7787 + for (j = 0; j < defs_c; ++j) {
7788 + if (last_def == NULL) {
7789 + last_def = defs[j];
7791 + /* Ensure the current DEF covers all iterations covered
7792 + by the last checked one. */
7793 + last_usr = last_def->usr;
7794 + usr = defs[j]->usr;
7795 + for (k = 0; k < last_usr->depth && k < usr->depth &&
7796 + last_usr->index[k] == usr->index[k];
7799 + /* We only need to check when there are common loops. */
7800 + if (k && ! candl_dependence_check_domain_is_included
7801 + (last_def, defs[j], scop->context, k + 1)) {
7802 + usr = defs[j]->usr;
7803 + current[usr->label] = last_def;
7806 + last_def = defs[j];
7809 + /* Create DEF-USE table. */
7810 + for (k = 0; k < uses_c; ++k) {
7811 + usr = uses[k]->usr;
7812 + if (usr->label > ((candl_statement_usr_p)defs[j]->usr)->label)
7813 + current[usr->label] = defs[j];
7817 + /* Initialize partition table. */
7818 + for (j = 0; j < nb_statements; ++j)
7821 + /* Create partitions. */
7822 + for (j = 0; j < defs_c; ++j) {
7823 + usr = defs[j]->usr;
7824 + for (k = 0; k < nb_statements; ++k)
7825 + if ((current[k] && current[k] == defs[j]) ||
7826 + (k == usr->label && current[usr->label] == NULL))
7830 + /* Check if it is needed to rename the scalar. */
7832 + for (j = 0; j < nb_statements; ++j)
7834 + if (parts[j] != -1)
7837 + if (parts[j] != -1 && tmp != parts[j])
7841 + /* Rename scalar variable. */
7842 + if (j != nb_statements) {
7845 + for (iter = scop->statement ; iter != NULL ; iter = iter->next) {
7846 + if (parts[j] != -1) {
7849 + else if (tmp != parts[j])
7852 + access = iter->access;
7853 + for (; access != NULL; access = access->next) {
7854 + elt = access->elt;
7855 + row = candl_util_relation_get_line(elt, 0);
7856 + tmp = osl_relation_get_array_id(elt);
7857 + if (tmp == scalars[i]) {
7858 + if (options->verbose)
7859 + fprintf (stderr, "[Candl] Scalar analysis: Renamed "
7860 + "variable %d to %d at statement S%d\n",
7861 + scalars[i], newvar + parts[j], j);
7862 + osl_int_set_si(precision,
7863 + &elt->m[row][elt->nb_columns - 1],
7864 + newvar + parts[j]);
7872 + } /* end Iterate on all scalars */
7874 + /* Redo the full dependence analysis, if needed. */
7875 + if (has_changed) {
7876 + int bopt = options->scalar_renaming;
7877 + options->scalar_renaming = 0;
7878 + if (options->scalar_privatization)
7879 + free(((candl_scop_usr_p)scop->usr)->scalars_privatizable);
7880 + osl_dependence_free(*deps);
7881 + *deps = candl_dependence(scop, options);
7882 + options->scalar_renaming = bopt;
7891 @@ -1988,188 +1641,171 @@ candl_dependence_scalar_renaming (candl_program_p program,
7892 * This function returns true if the dependence 'dep' is loop-carried
7893 * for loop 'loop_index', false otherwise.
7896 -candl_dependence_is_loop_carried (candl_program_p program,
7897 - CandlDependence* dep,
7900 +int candl_dependence_is_loop_carried(osl_scop_p scop,
7901 + osl_dependence_p dep,
7903 + osl_relation_p msrc = NULL, mtarg = NULL;
7904 + candl_statement_usr_p s_usr = dep->stmt_source_ptr->usr;
7905 + candl_statement_usr_p t_usr = dep->stmt_target_ptr->usr;
7908 + int row_k, row_kp;
7909 + int precision = scop->context->precision;
7911 /* Ensure source and sink share common loop 'loop_index', and that
7912 dependence depth is consistent with the considered loop. */
7913 - for (i = 0; i < dep->source->depth; ++i)
7914 - if (dep->source->index[i] == loop_index)
7915 + for (i = 0; i < s_usr->depth; ++i)
7916 + if (s_usr->index[i] == loop_index)
7918 - if (i != dep->depth - 1 || i >= dep->target->depth)
7919 + if (i != dep->depth - 1 || i >= t_usr->depth)
7921 - for (j = 0; j < dep->target->depth; ++j)
7922 - if (dep->target->index[j] == loop_index)
7923 + for (j = 0; j < t_usr->depth; ++j)
7924 + if (t_usr->index[j] == loop_index)
7931 - CandlMatrix* mats;
7932 - if (dep->type == CANDL_WAR || dep->type == CANDL_RAR)
7933 - mats = dep->source->read;
7935 - mats = dep->source->written;
7936 - CandlMatrix* matt;
7937 - if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV
7938 - || dep->type == CANDL_RAR)
7939 - matt = dep->target->read;
7941 - matt = dep->target->written;
7943 - int src_ref_iter = 0;
7944 - int dst_ref_iter = 0;
7945 - for (k = 0; k == 0 ||
7946 - (dep->ref_source + k < mats->NbRows &&
7947 - CANDL_get_si(mats->p[dep->ref_source + k][0]) == 0); ++k)
7948 - if (CANDL_get_si(mats->p[dep->ref_source + k][i + 1]) != 0)
7953 - for (k = 0; k == 0 ||
7954 - (dep->ref_target + k < matt->NbRows &&
7955 - CANDL_get_si(matt->p[dep->ref_target + k][0]) == 0); ++k)
7956 - if (CANDL_get_si(matt->p[dep->ref_target + k][j + 1]) != 0)
7962 + msrc = candl_dependence_get_relation_ref_source_in_dep(dep);
7963 + mtarg = candl_dependence_get_relation_ref_target_in_dep(dep);
7965 + /* plus one for the Arr output dim */
7966 + int src_ref_iter = (candl_util_relation_get_line(msrc, i+1) != -1);
7967 + int dst_ref_iter = (candl_util_relation_get_line(mtarg,j+1) != -1);
7969 /* Ensure it is not a basic loop-independent dependence (pure
7970 equality of the access functions for the surrounding iterators +
7971 parameters + constant, no occurence of the inner loop iterators,
7972 and contain the current loop iterator. */
7977 - // Ensure the reference do reference the current loop iterator
7979 - if (CANDL_get_si(mats->p[dep->ref_source + k][i + 1]) != 0)
7984 - if (CANDL_get_si(matt->p[dep->ref_target + kp][j + 1]) != 0)
7986 - // Ensure the access functions are equal for the
7987 - // surrounding loop iterators, and no inner iterator
7989 - for (l = 0; l <= i + 1; ++l)
7990 - if (CANDL_get_si(mats->p[dep->ref_source + k][l]) !=
7991 - CANDL_get_si(matt->p[dep->ref_target + kp][l]))
7998 - for (; l <= dep->source->depth; ++l)
7999 - if (CANDL_get_si(mats->p[dep->ref_source + k][l]) != 0)
8005 - for (; m <= dep->target->depth; ++m)
8006 - if (CANDL_get_si(matt->p[dep->ref_target + kp][m]) != 0)
8012 - for (; l < mats->NbColumns; ++l, ++m)
8013 - if (CANDL_get_si(mats->p[dep->ref_source + k][l]) !=
8014 - CANDL_get_si(matt->p[dep->ref_target + kp][m]))
8022 - while (!must_test &&
8023 - dep->ref_target + kp < matt->NbRows &&
8024 - CANDL_get_si(matt->p[dep->ref_target + kp][0]) == 0);
8028 + k = 1; // start after the Arr column
8029 + row_k = candl_util_relation_get_line(msrc, k);
8030 while (!must_test &&
8031 - dep->ref_source + k < mats->NbRows &&
8032 - CANDL_get_si(mats->p[dep->ref_source + k][0]) == 0);
8033 + k < msrc->nb_output_dims &&
8034 + osl_int_zero(precision, msrc->m[row_k][0])) {
8036 + // Ensure the reference do reference the current loop iterator
8038 + if (!osl_int_zero(precision, msrc->m[row_k][i])) {
8040 + row_kp = candl_util_relation_get_line(mtarg, kp);
8042 + while (!must_test &&
8043 + kp < mtarg->nb_output_dims &&
8044 + osl_int_zero(precision, mtarg->m[row_kp][0])) {
8046 + if (!osl_int_zero(precision, mtarg->m[row_kp][j])) {
8047 + // Ensure the access functions are equal for the
8048 + // surrounding loop iterators, and no inner iterator
8050 + if (!osl_int_eq(precision,
8051 + msrc->m[row_k][0], mtarg->m[row_kp][0])) {
8054 + for (l = 1; l <= i; ++l)
8055 + if (!osl_int_eq(precision,
8056 + msrc->m[row_k][msrc->nb_output_dims + l],
8057 + mtarg->m[row_kp][mtarg->nb_output_dims + l])) {
8064 + for (; l <= s_usr->depth+1; ++l)
8065 + if (!osl_int_zero(precision, msrc->m[row_k][msrc->nb_output_dims + l])) {
8070 + for (; m <= t_usr->depth+1; ++m)
8071 + if (!osl_int_zero(precision, mtarg->m[row_kp][mtarg->nb_output_dims + m])) {
8076 + for (; l < msrc->nb_columns-1; ++l, ++m)
8077 + if (!osl_int_eq(precision,
8078 + msrc->m[row_k][msrc->nb_output_dims + l],
8079 + mtarg->m[row_kp][mtarg->nb_output_dims + m])) {
8085 + row_kp = candl_util_relation_get_line(mtarg, kp);
8089 + row_k = candl_util_relation_get_line(msrc, k);
8092 if (src_ref_iter && dst_ref_iter && !must_test)
8096 /* Final check. For loop i, the dependence is loop carried if there exists
8097 x_i^R != x_i^S in the dependence polyhedron, with
8098 x_{1..i-1}^R = x_{1..i-1}^S
8102 - CandlMatrix* mat = dep->domain;
8103 - CandlStatement* src = dep->source;
8104 - CandlMatrix* testsyst =
8105 - candl_matrix_malloc(mat->NbRows + 1 + dep->source->depth, mat->NbColumns);
8106 - for (pos = 0; pos < mat->NbRows; ++pos)
8107 - for (j = 0; j < mat->NbColumns; ++j)
8108 - CANDL_assign(testsyst->p[pos][j], mat->p[pos][j]);
8109 - for (j = 0; j < i; ++j)
8111 - CANDL_set_si(testsyst->p[pos + j + 1][0], 0);
8112 - CANDL_set_si(testsyst->p[pos + j + 1][1 + j], -1);
8113 - CANDL_set_si(testsyst->p[pos + j + 1][1 + j + dep->source->depth], 1);
8115 + osl_relation_p mat = dep->domain;
8117 + osl_relation_p testsyst = osl_relation_pmalloc(precision,
8118 + mat->nb_rows + 1 + s_usr->depth,
8120 + for (pos = 0; pos < mat->nb_rows; ++pos)
8121 + for (j = 0; j < mat->nb_columns; ++j)
8122 + osl_int_assign(precision,
8123 + &testsyst->m[pos][j], mat->m[pos][j]);
8124 + for (j = 0; j < i; ++j) {
8125 + osl_int_set_si(precision, &testsyst->m[pos+j+1][0], 0);
8126 + osl_int_set_si(precision, &testsyst->m[pos+j+1][1+j], -1);
8127 + osl_int_set_si(precision, &testsyst->m[pos+j+1][1+j+mat->nb_output_dims], 1);
8132 - CANDL_set_si(testsyst->p[pos][0], 1);
8133 - CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1);
8134 - CANDL_set_si(testsyst->p[pos][1 + i], 1);
8135 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
8136 - has_pt = pip_has_rational_point (testsyst, NULL, 1);
8140 - CANDL_set_si(testsyst->p[pos][1 + i], -1);
8141 - CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1);
8142 - has_pt = pip_has_rational_point (testsyst, NULL, 1);
8145 - candl_matrix_free (testsyst);
8147 + osl_int_set_si(precision, &testsyst->m[pos][0], 1);
8148 + osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1);
8149 + osl_int_set_si(precision, &testsyst->m[pos][1+i], 1);
8150 + osl_int_set_si(precision, &testsyst->m[pos][1+i+mat->nb_output_dims], -1);
8152 + has_pt = pip_has_rational_point(testsyst, NULL, 1);
8155 + osl_int_set_si(precision, &testsyst->m[pos][1+i], -1);
8156 + osl_int_set_si(precision, &testsyst->m[pos][1+i+mat->nb_output_dims], 1);
8157 + has_pt = pip_has_rational_point(testsyst, NULL, 1);
8162 - /* LNP: OLD VERSION. The above is more robust. */
8163 -/* /\* Final check. The dependence exists only because the loop */
8164 -/* iterates. Make the loop not iterate and check if there's still */
8165 -/* dependent iterations. *\/ */
8166 -/* CandlMatrix* m = candl_matrix_malloc(dep->domain->NbRows + 2, */
8167 -/* dep->domain->NbColumns); */
8168 -/* CANDL_set_si(m->p[m->NbRows - 2][i + 1], -1); */
8169 -/* CANDL_set_si(m->p[m->NbRows - 1][dep->source->depth + 1 + j], -1); */
8170 -/* /\* Copy the rest of the matrix. *\/ */
8172 -/* for (ii = 0; ii < dep->domain->NbRows; ++ii) */
8173 -/* for (jj = 0; jj < dep->domain->NbColumns; ++jj) */
8174 -/* CANDL_assign(m->p[ii][jj], dep->domain->p[ii][jj]); */
8175 -/* /\* Compute real lb of loops. *\/ */
8176 -/* Entier lb; CANDL_init(lb); */
8177 -/* candl_dependence_compute_lb (m, &lb, i + 1); */
8178 -/* CANDL_assign(m->p[m->NbRows - 2][m->NbColumns - 1], lb); */
8179 -/* candl_dependence_compute_lb (m, &lb, dep->source->depth + 1 + j); */
8180 -/* CANDL_assign(m->p[m->NbRows - 1][m->NbColumns - 1], lb); */
8181 -/* int ret = candl_matrix_check_point(m, program->context); */
8182 -/* CANDL_clear(lb); */
8184 -/* /\* Be clean. *\/ */
8185 -/* candl_matrix_free(m); */
8188 + /* LNP: OLD VERSION */
8189 + /* The above is more robust. */
8190 + /* /\* Final check. The dependence exists only because the loop */
8191 + /* iterates. Make the loop not iterate and check if there's still */
8192 + /* dependent iterations. *\/ */
8193 + /* CandlMatrix* m = candl_matrix_malloc(dep->domain->NbRows + 2, */
8194 + /* dep->domain->NbColumns); */
8195 + /* CANDL_set_si(m->p[m->NbRows - 2][i + 1], -1); */
8196 + /* CANDL_set_si(m->p[m->NbRows - 1][dep->source->depth + 1 + j], -1); */
8197 + /* /\* Copy the rest of the matrix. *\/ */
8199 + /* for (ii = 0; ii < dep->domain->NbRows; ++ii) */
8200 + /* for (jj = 0; jj < dep->domain->NbColumns; ++jj) */
8201 + /* CANDL_assign(m->p[ii][jj], dep->domain->p[ii][jj]); */
8202 + /* /\* Compute real lb of loops. *\/ */
8203 + /* Entier lb; CANDL_init(lb); */
8204 + /* candl_dependence_compute_lb (m, &lb, i + 1); */
8205 + /* CANDL_assign(m->p[m->NbRows - 2][m->NbColumns - 1], lb); */
8206 + /* candl_dependence_compute_lb (m, &lb, dep->source->depth + 1 + j); */
8207 + /* CANDL_assign(m->p[m->NbRows - 1][m->NbColumns - 1], lb); */
8208 + /* int ret = candl_matrix_check_point(m, program->context); */
8209 + /* CANDL_clear(lb); */
8211 + /* /\* Be clean. *\/ */
8212 + /* candl_matrix_free(m); */
8214 + /* return !ret; */
8218 @@ -2178,98 +1814,100 @@ candl_dependence_is_loop_carried (candl_program_p program,
8219 * prunes the dependence graph 'deps' by removing loop-carried
8220 * dependences involving a scalar variable privatizable for that loop.
8223 -candl_dependence_prune_with_privatization (candl_program_p program,
8224 - CandlOptions* options,
8225 - CandlDependence** deps)
8227 - CandlDependence* next;
8228 - CandlDependence* tmp;
8229 - CandlDependence* pred = NULL;
8230 +void candl_dependence_prune_with_privatization(osl_scop_p scop,
8231 + candl_options_p options,
8232 + osl_dependence_p* deps) {
8233 + osl_dependence_p next;
8234 + osl_dependence_p tmp;
8235 + osl_dependence_p pred = NULL;
8236 + candl_statement_usr_p s_usr;
8237 + candl_statement_usr_p t_usr;
8238 + candl_scop_usr_p scop_usr = scop->usr;
8247 + int precision = scop->context->precision;
8249 if (options->verbose)
8250 fprintf (stderr, "[Candl] Scalar Analysis: Remove loop-carried dependences"
8251 - " on privatizable scalars\n");
8252 + " on privatizable scalars\n");
8254 - if (program->nb_statements == 0)
8255 + if (scop->statement == NULL)
8258 /* Perform the scalar analysis, if not done before. */
8259 - if (program->scalars_privatizable == NULL)
8261 - CandlOptions* options = candl_options_malloc ();
8262 - options->scalar_privatization = 1;
8263 - candl_dependence_analyze_scalars (program, options);
8264 - candl_options_free (options);
8265 + if (scop_usr->scalars_privatizable == NULL) {
8266 + candl_options_p options = candl_options_malloc();
8267 + options->scalar_privatization = 1;
8268 + candl_dependence_analyze_scalars(scop, options);
8269 + candl_options_free(options);
8272 + for (tmp = *deps; tmp; ) {
8273 + s_usr = tmp->stmt_source_ptr->usr;
8274 + t_usr = tmp->stmt_target_ptr->usr;
8276 + /* Check if the dependence is involving a privatizable scalar. */
8278 + candl_dependence_get_array_refs_in_dep(tmp, &refs, &reft);
8279 + for (i = 0; i < s_usr->depth; ++i) {
8280 + if (candl_dependence_scalar_is_privatizable_at(scop, refs,
8285 - for (tmp = *deps; tmp; )
8287 - /* Check if the dependence is involving a privatizable scalar. */
8289 - candl_dependence_get_array_refs_in_dep (tmp, &refs, &reft);
8290 - for (i = 0; i < tmp->source->depth; ++i)
8291 - if (candl_dependence_scalar_is_privatizable_at (program, refs,
8292 - tmp->source->index[i]))
8294 - if (i == tmp->source->depth)
8296 - for (i = 0; i < tmp->target->depth; ++i)
8297 - if (candl_dependence_scalar_is_privatizable_at
8298 - (program, reft, tmp->target->index[i]))
8300 - if (i == tmp->target->depth)
8303 - loop_idx = tmp->target->index[i];
8305 + if (i == s_usr->depth) {
8306 + for (i = 0; i < t_usr->depth; ++i) {
8307 + if (candl_dependence_scalar_is_privatizable_at
8308 + (scop, reft, t_usr->index[i]))
8311 + if (i == t_usr->depth)
8314 - loop_idx = tmp->source->index[i];
8315 - loop_pos_priv = i;
8316 - /* Check if the dependence is loop-carried at loop i. */
8317 - if (is_priv && candl_dependence_is_loop_carried (program, tmp, loop_idx))
8319 - /* If so, make the dependence loop-independent. */
8320 - CandlMatrix* m = candl_matrix_malloc (tmp->domain->NbRows + 1,
8321 - tmp->domain->NbColumns);
8322 - for (i = 0; i < tmp->domain->NbRows; ++i)
8323 - for (j = 0; j < tmp->domain->NbColumns; ++j)
8324 - CANDL_assign(m->p[i][j], tmp->domain->p[i][j]);
8325 - candl_matrix_free (tmp->domain);
8327 - CANDL_set_si(tmp->domain->p[tmp->domain->NbRows - 1]
8328 - [1 + loop_pos_priv], 1);
8329 - CANDL_set_si(tmp->domain->p[tmp->domain->NbRows - 1]
8330 - [1 + loop_pos_priv + tmp->source->depth], -1);
8331 - /* Set the type of the dependence as special
8332 - scalar-privatization one. */
8333 - if (tmp->type == CANDL_RAW)
8334 - tmp->type = CANDL_RAW_SCALPRIV;
8336 - if (!candl_matrix_check_point (tmp->domain, NULL))
8338 - /* It is, the dependence can be removed. */
8339 - candl_matrix_free (tmp->domain);
8343 - pred->next = next;
8351 - /* Go to the next victim. */
8352 + loop_idx = t_usr->index[i];
8354 + loop_idx = s_usr->index[i];
8356 + loop_pos_priv = i;
8358 + /* Check if the dependence is loop-carried at loop i. */
8359 + if (is_priv && candl_dependence_is_loop_carried(scop, tmp, loop_idx)) {
8360 + /* If so, make the dependence loop-independent. */
8361 + row = tmp->domain->nb_rows;
8362 + osl_relation_insert_blank_row(tmp->domain, row);
8363 + osl_int_set_si(precision,
8364 + &tmp->domain->m[row][1 + loop_pos_priv],
8366 + osl_int_set_si(precision,
8367 + &tmp->domain->m[row][1 + loop_pos_priv + s_usr->depth],
8370 + /* Set the type of the dependence as special
8371 + scalar-privatization one. */
8372 + if (tmp->type == OSL_DEPENDENCE_RAW)
8373 + tmp->type = OSL_DEPENDENCE_RAW_SCALPRIV;
8375 + if (!candl_matrix_check_point(tmp->domain, NULL)) {
8376 + /* It is, the dependence can be removed. */
8377 + osl_relation_free(tmp->domain);
8381 + pred->next = next;
8390 + /* Go to the next victim. */
8397 @@ -2278,27 +1916,29 @@ candl_dependence_prune_with_privatization (candl_program_p program,
8398 * This function checks if a given scalar 'var_index' is privatizable
8399 * for loop 'loop_index'.
8402 -candl_dependence_scalar_is_privatizable_at (candl_program_p program,
8406 +int candl_dependence_scalar_is_privatizable_at(osl_scop_p scop,
8409 + candl_scop_usr_p scop_usr = scop->usr;
8412 /* If the scalar analysis wasn't performed yet, do it. */
8413 - if (program->scalars_privatizable == NULL)
8415 - CandlOptions* options = candl_options_malloc();
8416 - options->scalar_privatization = 1;
8417 - candl_dependence_analyze_scalars (program, options);
8418 - candl_options_free (options);
8420 + if (scop_usr->scalars_privatizable == NULL) {
8421 + candl_options_p options = candl_options_malloc();
8422 + options->scalar_privatization = 1;
8423 + candl_dependence_analyze_scalars(scop, options);
8424 + candl_options_free(options);
8428 + while (scop_usr->scalars_privatizable[i] != -1)
8431 /* Check in the array of privatizable scalar variables for the tuple
8433 - for (i = 0; program->scalars_privatizable[i] != -1; i += 2)
8434 - if (program->scalars_privatizable[i] == var_index &&
8435 - program->scalars_privatizable[i + 1] == loop_index)
8436 + for (i = 0; scop_usr->scalars_privatizable[i] != -1; i += 2)
8437 + if (scop_usr->scalars_privatizable[i] == var_index &&
8438 + scop_usr->scalars_privatizable[i + 1] == loop_index)
8442 @@ -2307,320 +1947,222 @@ candl_dependence_scalar_is_privatizable_at (candl_program_p program,
8445 * candl_dependence_analyze_scalars function:
8446 - * This function checks, for all scalar variables of the program, and
8447 + * This function checks, for all scalar variables of the scop, and
8448 * all loop levels, if the scalar can be privatized at that level.
8451 -candl_dependence_analyze_scalars(candl_program_p program,
8452 - CandlOptions* options)
8454 +int candl_dependence_analyze_scalars(osl_scop_p scop,
8455 + candl_options_p options) {
8457 - CandlStatement** stmts;
8458 - CandlStatement** fullchain = NULL;
8459 - int i, j, k, l, n;
8461 - int max, is_priv, cpt, offset, was_priv;
8462 - CandlStatement* curlast;
8463 - CandlStatement* last;
8464 + osl_statement_p* statement; /* not a chained list, but an array of */
8465 + osl_statement_p* fullchain; /* statement to not realloc the usr field */
8466 + osl_statement_p s;
8467 + osl_statement_p curlast;
8468 + osl_statement_p last;
8469 + osl_statement_p iter; /* used to iterate on the scop */
8470 + osl_relation_list_p access;
8471 + osl_relation_p elt;
8472 + candl_scop_usr_p scop_usr = scop->usr;
8473 + candl_statement_usr_p stmt_usr;
8475 + int max, is_priv, offset, was_priv;
8477 int priv_buff_size = 64;
8480 /* Initialize the list of privatizable scalars to empty. */
8481 - if (options->scalar_privatization)
8483 - program->scalars_privatizable = (int*) malloc(2 * sizeof(int));
8484 - program->scalars_privatizable[0] = program->scalars_privatizable[1] = -1;
8486 + if (options->scalar_privatization) {
8487 + CANDL_malloc(scop_usr->scalars_privatizable, int*, 2 * sizeof(int));
8488 + scop_usr->scalars_privatizable[0] = -1;
8489 + scop_usr->scalars_privatizable[1] = -1;
8492 /* Retrieve all scalar variables. */
8493 - scalars = candl_dependence_extract_scalar_variables (program);
8494 + scalars = candl_dependence_extract_scalar_variables(scop);
8496 /* For each of those, detect (at any level) if it can be privatized
8497 / expanded / renamed. */
8498 - for (i = 0; scalars[i] != -1; ++i)
8500 - /* Go to the first statement referencing the scalar. */
8501 - for (j = 0; j < program->nb_statements; ++j)
8502 - if (candl_dependence_var_is_ref (program->statement[j], scalars[i])
8503 - != CANDL_VAR_UNDEF)
8505 - /* A weird error occured. */
8506 - if (j == program->nb_statements)
8509 - /* Take all statements referencing the scalar. */
8510 - fullchain = candl_dependence_refvar_chain (program, program->statement[j],
8512 - /* Compute the maximum loop depth of the chain. */
8513 - for (k = 0, max = 0; fullchain[k]; ++k)
8514 - max = max < fullchain[k]->depth ? fullchain[k]->depth : max;
8515 - last = fullchain[k - 1];
8516 - /* Initialize the offset for expansion. */
8519 - /* Iterate on all possible depth for analysis. */
8520 - for (k = 1; k <= max; ++k)
8522 - CandlStatement* s = fullchain[0];
8530 - /* Take all statements dominated by s referencing the
8531 - current scalar variable. */
8532 - stmts = candl_dependence_refvar_chain (program, s, scalars[i], k);
8533 - /* No more statement in the chain, exit. */
8534 - if (stmts[0] == NULL)
8537 - is_priv = candl_dependence_var_is_ref (stmts[c], scalars[i])
8538 - == CANDL_VAR_IS_DEF;
8539 - /* Ensure we have a use in the chain. */
8540 - for (l = c + 1; stmts[l - 1] && stmts[l]; ++l)
8541 - if (candl_dependence_var_is_ref (stmts[l], scalars[i]) ==
8542 - CANDL_VAR_IS_USED)
8544 - if (stmts[l - 1] == NULL || stmts[l] == NULL)
8546 - /* Check for privatization, while the entry of the chain
8548 - while (stmts[c] && candl_dependence_var_is_ref
8549 - (stmts[c], scalars[i]) == CANDL_VAR_IS_DEF)
8551 - /* From the current DEF node, ensure the rest of the
8552 - chain covers not more than the iteration domain
8554 - for (l = c + 1; stmts[l - 1] && stmts[l]; ++l)
8555 - /* FIXME: we should deal with
8556 - def_1->use->def_2->use chains where dom(def_2)
8558 - if (! candl_dependence_check_domain_is_included
8559 - (stmts[c], stmts[l], program->context, k))
8561 - /* dom(use) - dom(def) > 0. Check if there is
8562 - another DEF to test at the entry of the
8565 - if (candl_dependence_var_is_ref
8566 - (stmts[c + 1], scalars[i]) != CANDL_VAR_IS_DEF)
8567 - /* No. The variable is not privatizable. */
8571 - if (! is_priv || ! stmts[l])
8573 - /* The chain dominated by stmts[c] is not
8574 - privatizable. Go for the next DEF at the
8575 - beginning of the block, if any. */
8580 - /* Perform the privatization / expansion. */
8581 - if (options->verbose)
8582 - fprintf (stderr, "[Candl] Scalar Analysis: The variable %d"
8583 - " can be privatized at loop %d\n",
8584 - scalars[i], stmts[0]->index[k - 1]);
8585 - if (options->scalar_expansion)
8586 - /* Traverse all statements in the chain. */
8587 - for (l = c; stmts[l]; ++l)
8589 - /* It's not the first expansion of the scalar,
8590 - we need to increase its dimension all along
8592 - if (offset && !was_priv)
8593 - candl_dependence_expand_scalar (fullchain,
8595 - /* Perform scalar expansion in the array
8596 - access functions. */
8597 - for (cpt = 0, m = stmts[l]->read; cpt < 2;
8598 - ++cpt, m = stmts[l]->written)
8599 - for (n = 0; n < m->NbRows; ++n)
8600 - if (CANDL_get_si(m->p[n][0]) == scalars[i])
8601 - CANDL_set_si(m->p[n + offset][k], 1);
8604 - if (options->scalar_privatization)
8606 - /* Memory management for the array of
8607 - privatizable scalars. */
8610 - free (program->scalars_privatizable);
8611 - program->scalars_privatizable =
8612 - (int*)malloc(priv_buff_size * sizeof(int));
8613 - for (l = 0; l < priv_buff_size; ++l)
8614 - program->scalars_privatizable[l] = -1;
8616 - if (nb_priv == priv_buff_size)
8618 - program->scalars_privatizable =
8619 - realloc(program->scalars_privatizable,
8620 - (priv_buff_size *= 2) * sizeof(int));
8621 - for (l = nb_priv; l < priv_buff_size; ++l)
8622 - program->scalars_privatizable[l] = -1;
8624 - /* Memorize the scalar information in the
8625 - privatizable list. */
8626 - program->scalars_privatizable[nb_priv++] = scalars[i];
8627 - program->scalars_privatizable[nb_priv++] =
8628 - stmts[0]->index[k - 1];
8631 - /* Go to the next block, if any. */
8632 - for (l = 0; stmts[l]; ++l)
8634 - curlast = stmts[l - 1];
8635 - if (curlast != last)
8637 - for (l = 0; fullchain[l]; ++l)
8638 - if (fullchain[l] == curlast)
8639 - s = fullchain[l + 1];
8643 - while (curlast != last);
8646 + for (i = 0; scalars[i] != -1; ++i) {
8647 + /* Go to the first statement referencing the scalar in the scop. */
8648 + for (iter = scop->statement; iter != NULL; iter = iter->next) {
8649 + if (candl_dependence_var_is_ref(iter, scalars[i])
8650 + != CANDL_VAR_UNDEF)
8659 - * candl_num_dependences function:
8660 - * This function returns the number of dependences in the dependence
8662 - * \param dependence The first dependence of the dependence list.
8666 -candl_num_dependences(CandlDependence *candl_deps)
8668 - CandlDependence *candl_dep = candl_deps;
8671 - while (candl_dep != NULL)
8674 - candl_dep = candl_dep->next;
8676 + /* A weird error occured. */
8680 + /* Take all statements referencing the scalar. */
8681 + fullchain = candl_dependence_refvar_chain(scop, iter, scalars[i], 0);
8683 + /* Compute the maximum loop depth of the chain. */
8685 + for (k = 0; fullchain[k]; ++k) {
8686 + stmt_usr = fullchain[k]->usr;
8687 + if (max < stmt_usr->depth)
8688 + max = stmt_usr->depth;
8695 - * Convert a PIP quast to a union of polyhedra (Pip matrices)
8697 - * num: number of Pip matrices returned
8701 -PipMatrix **quast_to_polyhedra (PipQuast *quast, int *num,
8702 - int nvar, int npar)
8709 - if (quast == NULL)
8715 - if (quast->condition != NULL)
8717 - tp = quast_to_polyhedra(quast->next_then, &num1, nvar, npar);
8718 - ep = quast_to_polyhedra(quast->next_else, &num2, nvar, npar);
8720 - /* Each of the matrices in the then tree needs to be augmented with
8721 - * the condition */
8722 - for (i = 0; i < num1; i++)
8724 - int nrows = tp[i]->NbRows;
8725 - CANDL_set_si(tp[i]->p[nrows][0], 1);
8726 - for (j = 1; j < 1 + nvar; j++)
8727 - CANDL_set_si(tp[i]->p[nrows][j], 0);
8728 - for (j = 0; j < npar + 1; j++)
8729 - CANDL_assign(tp[i]->p[nrows][1+nvar+j],
8730 - quast->condition->the_vector[j]);
8731 - (tp[i]->NbRows)++;
8734 - for (i = 0; i < num2; i++)
8736 - int nrows = ep[i]->NbRows;
8738 - CANDL_set_si(ep[i]->p[nrows][0], 1);
8739 - for (j = 1; j < 1 + nvar; j++)
8740 - CANDL_set_si(ep[i]->p[nrows][j], 0);
8741 - for (j = 0; j < npar + 1; j++)
8742 - CANDL_set_si(ep[i]->p[nrows][1+nvar+j],
8743 - -CANDL_get_si(quast->condition->the_vector[j]));
8744 - (ep[i]->NbRows)++;
8747 - qp = (PipMatrix **) malloc((num1 + num2) * sizeof(PipMatrix*));
8748 - for (i = 0; i < num1; ++i)
8750 - for (i = 0; i < num2; ++i)
8751 - qp[i + num1] = ep[i];
8753 - *num = num1 + num2;
8757 + last = fullchain[k-1];
8759 + /* Initialize the offset for expansion. */
8763 + /* Iterate on all possible depth for analysis. */
8764 + for (j = 1; j <= max; ++j) {
8773 - /* quast condition is NULL */
8774 - PipMatrix *lwmatrix = pip_matrix_alloc(nvar+npar+1, nvar+npar+2);
8776 - PipList *vecList = quast->list;
8779 - while (vecList != NULL) {
8781 - CANDL_set_si(lwmatrix->p[count][0], 0);
8782 - for (j=0; j<nvar; j++)
8784 - CANDL_set_si(lwmatrix->p[count][j+1], 1);
8786 - CANDL_set_si(lwmatrix->p[count][j+1], 0);
8788 - for (j=0; j<npar; j++)
8789 - CANDL_set_si(lwmatrix->p[count][j+1+nvar],
8790 - -CANDL_get_si(vecList->vector->the_vector[j]));
8791 - /* Constant portion */
8792 - if (quast->newparm != NULL)
8793 - /* Don't handle newparm for now */
8794 - CANDL_set_si(lwmatrix->p[count][npar+1+nvar],
8795 - -CANDL_get_si(vecList->vector->the_vector[npar+1]));
8797 - CANDL_set_si(lwmatrix->p[count][npar+1+nvar],
8798 - -CANDL_get_si(vecList->vector->the_vector[npar]));
8802 - vecList = vecList->next;
8805 + /* Take all statements dominated by s referencing the
8806 + current scalar variable. */
8807 + statement = candl_dependence_refvar_chain(scop, s, scalars[i], j);
8809 + /* No more statement in the chain, exit. */
8810 + if (statement[0] == NULL) {
8814 - lwmatrix->NbRows = count;
8823 + is_priv = candl_dependence_var_is_ref(statement[0], scalars[i]) ==
8826 + /* Ensure we have a use in the chain. */
8827 + /* here statement[c] is not NULL */
8828 + for (k = c + 1; statement[k]; ++k) {
8829 + if (candl_dependence_var_is_ref(statement[k], scalars[i]) ==
8830 + CANDL_VAR_IS_USED)
8834 + if (statement[k] == NULL)
8837 + /* Check for privatization, while the entry of the chain
8839 + while (statement[c] && candl_dependence_var_is_ref
8840 + (statement[c], scalars[i]) == CANDL_VAR_IS_DEF) {
8841 + /* From the current DEF node, ensure the rest of the
8842 + chain covers not more than the iteration domain
8844 + for (k = c + 1; statement[k]; ++k) {
8845 + /* FIXME: we should deal with
8846 + def_1->use->def_2->use chains where dom(def_2)
8848 + if (! candl_dependence_check_domain_is_included
8849 + (statement[c], statement[k], scop->context, j)) {
8850 + /* dom(use) - dom(def) > 0. Check if there is
8851 + another DEF to test at the entry of the
8853 + if (candl_dependence_var_is_ref
8854 + (statement[c+1], scalars[i]) != CANDL_VAR_IS_DEF)
8855 + /* No. The variable is not privatizable. */
8861 + if (! is_priv || ! statement[k])
8864 + /* The chain dominated by statement is not
8865 + privatizable. Go for the next DEF at the
8866 + beginning of the block, if any. */
8871 + /* Perform the privatization / expansion. */
8872 + if (options->verbose)
8873 + fprintf(stderr, "[Candl] Scalar Analysis: The variable %d"
8874 + " can be privatized at loop %d\n",
8876 + ((candl_statement_usr_p)statement[0]->usr)->index[j-1]);
8878 + if (options->scalar_expansion) {
8879 + int precision = scop->context->precision;
8880 + /* Traverse all statements in the chain. */
8881 + for (k = c; statement[k]; ++k) {
8882 + /* It's not the first expansion of the scalar,
8883 + we need to increase its dimension all along
8885 + if (!offset && !was_priv)
8886 + candl_dependence_expand_scalar(fullchain,
8888 + /* Perform scalar expansion in the array
8889 + access functions. */
8890 + access = statement[k]->access;
8891 + for (; access != NULL; access = access->next) {
8892 + elt = access->elt;
8893 + id = osl_relation_get_array_id(elt);
8894 + if (scalars[i] == id) {
8895 + row = candl_util_relation_get_line(elt, offset+1);
8896 + osl_int_set_si(precision, &elt->m[row][elt->nb_output_dims + j], 1);
8903 + if (options->scalar_privatization) {
8904 + /* Memory management for the array of
8905 + privatizable scalars. */
8906 + if (nb_priv == 0) {
8907 + free(scop_usr->scalars_privatizable);
8908 + CANDL_malloc(scop_usr->scalars_privatizable,
8909 + int*, priv_buff_size * sizeof(int));
8910 + for (k = 0; k < priv_buff_size; ++k)
8911 + scop_usr->scalars_privatizable[k] = -1;
8914 + if (nb_priv == priv_buff_size) {
8915 + CANDL_realloc(scop_usr->scalars_privatizable,
8916 + int*, (priv_buff_size *= 2) * sizeof(int));
8917 + for (k = nb_priv; k < priv_buff_size; ++k)
8918 + scop_usr->scalars_privatizable[k] = -1;
8921 + /* Memorize the scalar information in the
8922 + privatizable list. */
8923 + scop_usr->scalars_privatizable[nb_priv++] = scalars[i];
8924 + scop_usr->scalars_privatizable[nb_priv++] =
8925 + ((candl_statement_usr_p)statement[0]->usr)->index[j - 1];
8931 + /* Go to the next block, if any. */
8932 + for (k = 0; statement[k]; ++k)
8934 + curlast = statement[k-1];
8936 + if (curlast != last) {
8937 + for (k = 0; fullchain[k]; ++k) {
8938 + if (fullchain[k] == curlast) {
8939 + s = fullchain[k+1];
8946 + } while (curlast != last);
8948 + } // end iterate all possible depth
8952 + } // end iterate scalars
8954 - PipMatrix** ret = (PipMatrix**) malloc(sizeof(PipMatrix*));
8955 - ret[0] = lwmatrix;
8962 @@ -2631,119 +2173,142 @@ PipMatrix **quast_to_polyhedra (PipQuast *quast, int *num,
8963 * Returns 0 if lastwriter is computed successfully and dep domain updated,
8964 * returns 1 otherwise
8967 -int candl_dep_compute_lastwriter (CandlDependence **dep, CandlProgram *prog)
8970 - PipMatrix *new_domain;
8974 - int npar = prog->context->NbColumns-2;
8976 - PipOptions *pipOptions = pip_options_init();
8978 - /* We do a parametric lexmax on the source iterators
8979 - * keeping the target iterators as parameters */
8980 - pipOptions->Maximize = 1;
8981 - pipOptions->Simplify = 1;
8982 - // pipOptions->Deepest_cut = 1;
8983 - // pipOptions->Urs_unknowns = -1;
8984 - // pipOptions->Urs_parms = -1;
8986 - /* Build a context with equalities /inequalities only on the target
8988 - PipMatrix *context = pip_matrix_alloc((*dep)->domain->NbRows,
8989 - (*dep)->target->depth + npar + 2);
8992 - for (i = 0; i < (*dep)->domain->NbRows; i++)
8994 - for (j = 1; j < (*dep)->source->depth+1; j++)
8996 - if ((*dep)->domain->p[i][j] != 0)
8999 - if (j == (*dep)->source->depth+1)
9001 - /* Include this in the context */
9002 - CANDL_assign(context->p[nrows][0], (*dep)->domain->p[i][0]);
9003 - for (j = 1; j < 1 + (*dep)->target->depth + npar + 1; j++)
9004 - CANDL_assign(context->p[nrows][j],
9005 - (*dep)->domain->p[i][(*dep)->source->depth+j]);
9010 - context->NbRows = nrows;
9012 +int candl_dep_compute_lastwriter(osl_dependence_p *dep, osl_scop_p scop) {
9014 + PipOptions *pipOptions = pip_options_init();
9015 + candl_statement_usr_p s_usr = (*dep)->stmt_source_ptr->usr;
9016 + candl_statement_usr_p t_usr = (*dep)->stmt_target_ptr->usr;
9017 + osl_relation_p new_domain;
9019 + int npar = scop->context->nb_parameters;
9022 + #if defined(CANDL_LINEAR_VALUE_IS_INT)
9023 + precision = OSL_PRECISION_SP;
9024 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
9025 + precision = OSL_PRECISION_DP;
9026 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
9027 + precision = OSL_PRECISION_MP;
9030 + if (precision != scop->context->precision) {
9031 + CANDL_error("Precision not compatible with piplib ! (pip_relation2matrix)");
9034 - /* Parameteric lexmax */
9035 - lexmax = pip_solve((*dep)->domain, context, -1, pipOptions);
9036 + /* We do a parametric lexmax on the source iterators
9037 + * keeping the target iterators as parameters */
9038 + pipOptions->Maximize = 1;
9039 + pipOptions->Simplify = 1;
9040 + // pipOptions->Deepest_cut = 1;
9041 + // pipOptions->Urs_unknowns = -1;
9042 + // pipOptions->Urs_parms = -1;
9044 + /* Build a context with equalities /inequalities only on the target
9046 + osl_relation_p context = osl_relation_pmalloc(precision,
9047 + (*dep)->domain->nb_rows,
9048 + (*dep)->stmt_target_ptr->domain->nb_columns);
9050 + for (i = 0; i < (*dep)->domain->nb_rows; i++) {
9051 + for (j = 1; j < s_usr->depth+1; j++) {
9053 + // FIXME : new domain structure for dependence
9055 + if (!osl_int_zero(precision, (*dep)->domain->m[i][j]))
9059 + if (j == t_usr->depth+1) {
9060 + /* Include this in the context */
9061 + osl_int_assign(precision,
9062 + &context->m[nrows][0], (*dep)->domain->m[i][0]);
9064 + for (j = 1; j < (*dep)->stmt_target_ptr->domain->nb_columns; j++)
9065 + osl_int_assign(precision,
9066 + &context->m[nrows][j],
9067 + (*dep)->domain->m[i][s_usr->depth+j]);
9073 - pip_options_free(pipOptions);
9074 + /* Parameteric lexmax */
9075 + lexmax = pip_solve_osl((*dep)->domain, context, -1, pipOptions);
9077 - if (lexmax == NULL)
9079 - printf("WARNING: last writer failed (mostly invalid dependence): %s\n",
9080 - "bailing out safely without modification");
9081 - pip_matrix_print(stdout, (*dep)->domain);
9082 - pip_matrix_print(stdout, context);
9085 + pip_options_free(pipOptions);
9087 + if (lexmax == NULL) {
9088 + CANDL_warning("last writer failed (mostly invalid dependence): bailing out"
9089 + "safely without modification");
9090 + osl_relation_print(stderr, context);
9091 + osl_relation_print(stderr, (*dep)->domain);
9096 - PipMatrix **qp = quast_to_polyhedra(lexmax, &num, (*dep)->source->depth,
9097 - (*dep)->target->depth + npar);
9099 - /* Update the dependence domains */
9103 - PipMatrix* original_domain = (*dep)->domain;
9104 - for (it_mat = 0; it_mat < num; ++it_mat)
9106 - new_domain = pip_matrix_alloc(original_domain->NbRows +
9107 - qp[it_mat]->NbRows,
9108 - original_domain->NbColumns);
9109 - for (i = 0; i < original_domain->NbRows; i++)
9110 - for (j = 0; j < original_domain->NbColumns; j++)
9111 - CANDL_assign(new_domain->p[i][j], original_domain->p[i][j]);
9113 - for (i = 0; i < qp[it_mat]->NbRows; i++)
9114 - for (j = 0; j < original_domain->NbColumns; j++)
9115 - CANDL_assign(new_domain->p[i+original_domain->NbRows][j],
9116 - qp[it_mat]->p[i][j]);
9118 - (*dep)->domain = new_domain;
9119 - /* More than 1 pipmatrix from the quast, we need to insert
9120 - new dependences to have the union of domains. */
9121 - if (it_mat < num - 1)
9123 - CandlDependence* newdep = candl_dependence_malloc ();
9124 - newdep->source = (*dep)->source;
9125 - newdep->target = (*dep)->target;
9126 - newdep->depth = (*dep)->depth;
9127 - newdep->type = (*dep)->type;
9128 - newdep->ref_source = (*dep)->ref_source;
9129 - newdep->ref_target = (*dep)->ref_target;
9130 - newdep->usr = (*dep)->usr;
9131 - newdep->next = (*dep)->next;
9132 - (*dep)->next = newdep;
9137 - pip_matrix_free(original_domain);
9138 - for (i = 0; i < num; ++i)
9139 - pip_matrix_free(qp[i]);
9140 + osl_relation_p qp = pip_quast_to_polyhedra(lexmax, s_usr->depth,
9141 + t_usr->depth + npar);
9143 + /* Update the dependence domains */
9144 + if (osl_relation_nb_components(qp) > 0) {
9145 + osl_relation_p iter;
9146 + osl_relation_p original_domain = (*dep)->domain;
9147 + for (iter = qp ; iter != NULL ; iter = iter->next) {
9149 + new_domain = osl_relation_pmalloc(precision,
9150 + original_domain->nb_rows +
9152 + original_domain->nb_columns);
9154 + for (i = 0; i < original_domain->nb_rows; i++)
9155 + for (j = 0; j < original_domain->nb_columns; j++)
9156 + osl_int_assign(precision,
9157 + &new_domain->m[i][j],
9158 + original_domain->m[i][j]);
9160 + for (i = 0; i < qp->nb_rows; i++)
9161 + for (j = 0; j < original_domain->nb_columns; j++)
9162 + osl_int_assign(precision,
9163 + &new_domain->m[i+original_domain->nb_rows][j],
9166 + (*dep)->domain = new_domain;
9167 + /* More than 1 pipmatrix from the quast, we need to insert
9168 + new dependences to have the union of domains. */
9169 + if (qp->next != NULL) {
9170 + osl_dependence_p newdep = osl_dependence_malloc();
9171 + newdep->stmt_source_ptr = (*dep)->stmt_source_ptr;
9172 + newdep->stmt_target_ptr = (*dep)->stmt_target_ptr;
9173 + newdep->depth = (*dep)->depth;
9174 + newdep->type = (*dep)->type;
9175 + newdep->label_source = (*dep)->label_source;
9176 + newdep->label_target = (*dep)->label_target;
9177 + newdep->ref_source = (*dep)->ref_source;
9178 + newdep->ref_target = (*dep)->ref_target;
9179 + newdep->usr = (*dep)->usr;
9180 + newdep->source_nb_output_dims_domain = (*dep)->source_nb_output_dims_domain;
9181 + newdep->source_nb_output_dims_access = (*dep)->source_nb_output_dims_access;
9182 + newdep->target_nb_output_dims_domain = (*dep)->target_nb_output_dims_domain;
9183 + newdep->target_nb_output_dims_access = (*dep)->target_nb_output_dims_access;
9184 + newdep->source_nb_local_dims_domain = (*dep)->source_nb_local_dims_domain;
9185 + newdep->source_nb_local_dims_access = (*dep)->source_nb_local_dims_access;
9186 + newdep->target_nb_local_dims_domain = (*dep)->target_nb_local_dims_domain;
9187 + newdep->target_nb_local_dims_access = (*dep)->target_nb_local_dims_access;
9188 + newdep->next = (*dep)->next;
9189 + (*dep)->next = newdep;
9196 - pip_quast_free(lexmax);
9197 - pip_matrix_free(context);
9198 + osl_relation_free(original_domain);
9199 + osl_relation_free(qp);
9203 + pip_quast_free(lexmax);
9204 + osl_relation_free(qp);
9205 + osl_relation_free(context);
9211 @@ -2751,16 +2316,15 @@ int candl_dep_compute_lastwriter (CandlDependence **dep, CandlProgram *prog)
9212 * modify the dependence polyhedra. Be careful of any references to the old
9213 * dependence polyhedra. They are freed and new ones allocated.
9215 -void candl_compute_last_writer (CandlDependence *dep, CandlProgram *prog)
9217 +void candl_compute_last_writer(osl_dependence_p dep, osl_scop_p scop) {
9219 - while (dep != NULL) {
9220 - if (dep->type != CANDL_WAR) {
9221 - // printf("Last writer for dep %d: %d %d\n", count++, dep->source->depth, dep->target->depth);
9222 - // candl_matrix_print(stdout, dep->domain);
9223 - candl_dep_compute_lastwriter(&dep, prog);
9224 - // candl_matrix_print(stdout, dep->domain);
9227 + while (dep != NULL) {
9228 + if (dep->type != OSL_DEPENDENCE_WAR) {
9229 + // printf("Last writer for dep %d: %d %d\n", count++, dep->source->usr->depth, dep->target->usr->depth);
9230 + // candl_matrix_print(stdout, dep->domain);
9231 + candl_dep_compute_lastwriter(&dep, scop);
9232 + // candl_matrix_print(stdout, dep->domain);
9237 diff --git a/source/isl-wrapper.c b/source/isl-wrapper.c
9238 index 870c9c9..36d9b05 100644
9239 --- a/source/isl-wrapper.c
9240 +++ b/source/isl-wrapper.c
9242 **---- \#/ --------------------------------------------------------**
9243 ** .-"#'-. First version: January 31st 2011 **
9244 **--- |"-.-"| -------------------------------------------------------**
9249 ******** | | *************************************************************
9250 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
9251 ******************************************************************************
9256 -#include <candl/candl.h>
9257 +#include <osl/relation.h>
9259 -# ifdef CANDL_SUPPORTS_ISL
9262 -# include <isl/constraint.h>
9263 -# include <isl/map.h>
9264 -# include <isl/map.h>
9265 -# include <isl/set.h>
9266 -# include <isl/dim.h>
9267 -# include <isl/seq.h>
9268 -# include <isl/ctx.h>
9269 +#ifdef CANDL_SUPPORTS_ISL
9272 +#include <isl/constraint.h>
9273 +#include <isl/map.h>
9274 +#include <isl/map.h>
9275 +#include <isl/set.h>
9276 +#include <isl/dim.h>
9277 +#include <isl/seq.h>
9278 +#include <isl/ctx.h>
9281 /// WARNING: This is hard-coding that ISL uses GMP.
9285 struct isl_constraint*
9286 -isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row)
9288 +isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row) {
9289 struct isl_constraint* constraint;
9291 int nvariables = isl_dim_size(dim, isl_dim_set);
9292 @@ -79,17 +77,15 @@ isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row)
9294 constraint = isl_inequality_alloc(dim);
9296 - for (j = 0; j < nvariables; ++j)
9298 - mpz_set_si(val, CANDL_get_si(row[1 + j]));
9299 - isl_constraint_set_coefficient(constraint, isl_dim_out, j, val);
9301 + for (j = 0; j < nvariables; ++j) {
9302 + mpz_set_si(val, CANDL_get_si(row[1 + j]));
9303 + isl_constraint_set_coefficient(constraint, isl_dim_out, j, val);
9306 - for (j = 0; j < nparam; ++j)
9308 - mpz_set_si(val, CANDL_get_si(row[1 + nvariables + j]));
9309 - isl_constraint_set_coefficient(constraint, isl_dim_param, j, val);
9311 + for (j = 0; j < nparam; ++j) {
9312 + mpz_set_si(val, CANDL_get_si(row[1 + nvariables + j]));
9313 + isl_constraint_set_coefficient(constraint, isl_dim_param, j, val);
9316 mpz_set_si(val, CANDL_get_si(row[1 + nvariables + nparam]));
9317 isl_constraint_set_constant(constraint, val);
9318 @@ -102,16 +98,16 @@ isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row)
9321 isl_set_from_piplib_matrix(struct isl_ctx* ctx,
9322 - PipMatrix* matrix,
9325 + osl_relation_p matrix,
9327 + PipMatrix* pmatrix = pip_relation2matrix(matrix);
9328 struct isl_dim* dim;
9329 struct isl_basic_set* bset;
9331 unsigned nrows, ncolumns;
9333 - nrows = matrix->NbRows;
9334 - ncolumns = matrix->NbColumns;
9335 + nrows = pmatrix->NbRows;
9336 + ncolumns = pmatrix->NbColumns;
9337 int nvariables = ncolumns - 2 - nparam;
9339 dim = isl_dim_set_alloc(ctx, nparam, nvariables);
9340 @@ -119,36 +115,33 @@ isl_set_from_piplib_matrix(struct isl_ctx* ctx,
9341 bset = isl_basic_set_universe(isl_dim_copy(dim));
9343 for (i = 0; i < nrows; ++i) {
9344 - Entier* row = matrix->p[i];
9345 + Entier* row = pmatrix->p[i];
9346 struct isl_constraint* constraint =
9347 - isl_constraint_read_from_matrix(isl_dim_copy(dim), row);
9348 + isl_constraint_read_from_matrix(isl_dim_copy(dim), row);
9349 bset = isl_basic_set_add_constraint(bset, constraint);
9354 - return isl_set_from_basic_set(bset);;
9355 + return isl_set_from_basic_set(bset);
9360 -int count_cst(__isl_take isl_constraint *c, void *user)
9362 +int count_cst(__isl_take isl_constraint *c, void *user) {
9371 -int copy_cst_to_mat(__isl_take isl_constraint *c, void *user)
9373 +int copy_cst_to_mat(__isl_take isl_constraint *c, void *user) {
9374 // 1- Get the first free row of the matrix.
9376 PipMatrix* mat = (PipMatrix*)user;
9377 for (pos = 0; pos < mat->NbRows &&
9378 - CANDL_get_si(mat->p[pos][0]) != -1; ++pos)
9379 + CANDL_get_si(mat->p[pos][0]) != -1; ++pos)
9382 // 2- Set the eq/ineq bit.
9383 @@ -161,17 +154,15 @@ int copy_cst_to_mat(__isl_take isl_constraint *c, void *user)
9384 isl_int val; isl_int_init(val);
9386 int nb_vars = isl_constraint_dim(c, isl_dim_set);
9387 - for (j = 0; j < nb_vars; ++j)
9389 - isl_constraint_get_coefficient(c, isl_dim_set, j, &val);
9390 - CANDL_set_si(mat->p[pos][j + 1], isl_int_get_si(val));
9392 + for (j = 0; j < nb_vars; ++j) {
9393 + isl_constraint_get_coefficient(c, isl_dim_set, j, &val);
9394 + CANDL_set_si(mat->p[pos][j + 1], isl_int_get_si(val));
9396 int nb_param = isl_constraint_dim(c, isl_dim_param);
9397 - for (j = 0; j < nb_param; ++j)
9399 - isl_constraint_get_coefficient(c, isl_dim_param, j, &val);
9400 - CANDL_set_si(mat->p[pos][j + nb_vars + 1], isl_int_get_si(val));
9402 + for (j = 0; j < nb_param; ++j) {
9403 + isl_constraint_get_coefficient(c, isl_dim_param, j, &val);
9404 + CANDL_set_si(mat->p[pos][j + nb_vars + 1], isl_int_get_si(val));
9406 isl_constraint_get_constant(c, &val);
9407 CANDL_set_si(mat->p[pos][mat->NbColumns - 1], isl_int_get_si(val));
9409 @@ -181,19 +172,17 @@ int copy_cst_to_mat(__isl_take isl_constraint *c, void *user)
9413 -int bset_get(__isl_take isl_basic_set *bset, void *user)
9415 +int bset_get(__isl_take isl_basic_set *bset, void *user) {
9416 *((struct isl_basic_set**)user) = bset;
9424 isl_set_to_piplib_matrix(struct isl_ctx* ctx,
9425 - struct isl_set* set,
9428 + struct isl_set* set,
9430 struct isl_basic_set* bset = NULL;
9431 // There is only one basic set in this set.
9432 isl_set_foreach_basic_set(set, bset_get, &bset);
9433 @@ -215,8 +204,11 @@ isl_set_to_piplib_matrix(struct isl_ctx* ctx,
9435 // 4- Convert each constraint to a row of the matrix.
9436 isl_basic_set_foreach_constraint(bset, copy_cst_to_mat, res);
9440 + osl_relation_p tmp = pip_matrix2relation(res);
9441 + pip_matrix_free(res);
9447 diff --git a/source/matrix.c b/source/matrix.c
9448 index 03c8546..8c3a1aa 100644
9449 --- a/source/matrix.c
9450 +++ b/source/matrix.c
9452 **---- \#/ --------------------------------------------------------**
9453 ** .-"#'-. First version: december 9th 2005 **
9454 **--- |"-.-"| -------------------------------------------------------**
9459 ******** | | *************************************************************
9460 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
9461 ******************************************************************************
9462 @@ -36,298 +36,18 @@
9463 * please feel free to correct and improve it !
9466 -# include <stdlib.h>
9467 -# include <stdio.h>
9468 -# include <ctype.h>
9469 -# include <string.h>
9470 -# include <candl/candl.h>
9472 -/******************************************************************************
9473 - * Structure display function *
9474 - ******************************************************************************/
9478 - * candl_matrix_print_structure function:
9479 - * Displays a CandlMatrix structure (matrix) into a file (file, possibly stdout)
9480 - * in a way that trends to be understandable without falling in a deep
9481 - * depression or, for the lucky ones, getting a headache... It includes an
9482 - * indentation level (level) in order to work with others print_structure
9484 - * - 09/12/2005: first version (from CLooG 0.14.0).
9486 -void candl_matrix_print_structure(FILE * file, CandlMatrix * matrix, int level)
9489 - if (matrix != NULL)
9490 - { /* Go to the right level. */
9491 - for(j=0; j<level; j++)
9492 - fprintf(file,"|\t") ;
9493 - fprintf(file,"+-- CandlMatrix\n") ;
9495 - for(j=0; j<=level; j++)
9496 - fprintf(file,"|\t") ;
9497 - fprintf(file,"%d %d\n",matrix->NbRows,matrix->NbColumns) ;
9499 - /* Display the matrix. */
9500 - for (i=0; i<matrix->NbRows; i++)
9501 - { for(j=0; j<=level; j++)
9502 - fprintf(file,"|\t") ;
9504 - fprintf(file,"[ ") ;
9506 - for (j=0; j<matrix->NbColumns; j++)
9507 - { CANDL_print(file,CANDL_FMT,matrix->p[i][j]) ;
9508 - fprintf(file," ") ;
9511 - fprintf(file,"]\n") ;
9515 - { /* Go to the right level. */
9516 - for(j=0; j<level; j++)
9517 - fprintf(file,"|\t") ;
9518 - fprintf(file,"+-- NULL matrix\n") ;
9521 - /* The last line. */
9522 - for(j=0; j<=level; j++)
9523 - fprintf(file,"|\t") ;
9524 - fprintf(file,"\n") ;
9529 - * candl_matrix_print function:
9530 - * This function prints the content of a CandlMatrix structure (matrix) into a
9531 - * file (file, possibly stdout).
9532 - * - 09/12/2005: first version (from CLooG 0.14.0).
9534 -void candl_matrix_print(FILE * file, CandlMatrix * matrix)
9535 -{ candl_matrix_print_structure(file,matrix,0) ;
9541 - * candl_matrix_print_data function:
9542 - * This function prints the content of a CandlMatrix data (matrix) into a
9543 - * file (file, possibly stdout).
9545 -void candl_matrix_print_data(FILE * file, CandlMatrix * matrix)
9549 - fprintf (file, "%d %d\n", matrix->NbRows, matrix->NbColumns);
9550 - for (i = 0; i < matrix->NbRows; ++i)
9552 - for (j = 0; j < matrix->NbColumns; ++j)
9553 - CANDL_print(file,CANDL_FMT,matrix->p[i][j]);
9554 - fprintf (file, "\n");
9560 - * candl_matrix_list_print_structure function:
9561 - * Displays a CandlMatrixList structure (list) into a file (file, possibly
9562 - * stdout) in a way that trends to be understandable without falling in a deep
9563 - * depression or, for the lucky ones, getting a headache... It includes an
9564 - * indentation level (level) in order to work with others print_structure
9566 - * - 11/12/2005: first version.
9568 -void candl_matrix_list_print_structure(file, list, level)
9570 -CandlMatrixList *list ;
9572 -{ int i, j, first=1 ;
9575 - { /* Go to the right level. */
9576 - for(j=0; j<level; j++)
9577 - fprintf(file,"|\t") ;
9578 - fprintf(file,"+-- CandlMatrixList\n") ;
9581 - { /* Go to the right level. */
9582 - for(j=0; j<level; j++)
9583 - fprintf(file,"|\t") ;
9584 - fprintf(file,"+-- NULL matrix list\n") ;
9587 - while (list != NULL)
9589 - { /* Go to the right level. */
9590 - for(j=0; j<level; j++)
9591 - fprintf(file,"|\t") ;
9592 - fprintf(file,"| CandlMatrixList\n") ;
9597 - /* A blank line. */
9598 - for(j=0; j<=level+1; j++)
9599 - fprintf(file,"|\t") ;
9600 - fprintf(file,"\n") ;
9602 - /* Print the matrix. */
9603 - candl_matrix_print_structure(file,list->matrix,level+1) ;
9606 - if (list->next != NULL)
9607 - { for(i=0; i<=level; i++)
9608 - fprintf(file,"|\t") ;
9609 - fprintf(file,"V\n") ;
9611 - list = list->next ;
9614 - /* The last line. */
9615 - for(j=0; j<=level; j++)
9616 - fprintf(file,"|\t") ;
9617 - fprintf(file,"\n") ;
9622 - * candl_matrix_list_print function:
9623 - * This function prints the content of a CandlMatrixList structure (list) into a
9624 - * file (file, possibly stdout).
9625 - * - 11/12/2005: first version.
9627 -void candl_matrix_list_print(FILE * file, CandlMatrixList * list)
9628 -{ candl_matrix_list_print_structure(file,list,0) ;
9632 -/******************************************************************************
9633 - * Memory deallocation function *
9634 - ******************************************************************************/
9638 - * candl_matrix_free function:
9639 - * This function frees the allocated memory for a CandlMatrix structure.
9640 - * - 09/12/2005: first version.
9642 -void candl_matrix_free(CandlMatrix * matrix)
9643 -{ pip_matrix_free(matrix) ;
9648 - * candl_matrix_list_free function:
9649 - * This function frees the allocated memory for a CandlMatrixList structure.
9650 - * - 11/12/2005: first version.
9652 -void candl_matrix_list_free(CandlMatrixList * list)
9653 -{ CandlMatrixList * next ;
9655 - while (list != NULL)
9656 - { next = list->next ;
9657 - pip_matrix_free(list->matrix) ;
9664 -/******************************************************************************
9665 - * Reading functions *
9666 - ******************************************************************************/
9670 - * candl_matrix_read function:
9671 - * This function reads a matrix into a file (foo, posibly stdin) and returns a
9672 - * pointer to a CandlMatrix containing the read informations.
9673 - * - 09/12/2005: first version.
9675 -CandlMatrix * candl_matrix_read(FILE * file)
9676 -{ return pip_matrix_read(file) ;
9681 - * cloog_domain_list_read function:
9682 - * This function reads a list of matrices into a file (foo, posibly stdin) and
9683 - * returns a pointer to a CandlMatrixList containing the read information.
9684 - * - 11/12/2005: first version (from CLooG 0.14.0's cloog_domain_list_read).
9686 -CandlMatrixList * candl_matrix_list_read(FILE * file)
9687 -{ int i, nb_matrices ;
9688 - char s[CANDL_MAX_STRING] ;
9689 - CandlMatrixList * list, * now, * next ;
9691 - /* We read first the number of matrices in the list. */
9692 - while (fgets(s,CANDL_MAX_STRING,file) == 0) ;
9693 - while ((*s=='#' || *s=='\n') || (sscanf(s," %d",&nb_matrices)<1))
9694 - fgets(s,CANDL_MAX_STRING,file) ;
9696 - /* Then we read the matrices. */
9698 - if (nb_matrices > 0)
9699 - { list = (CandlMatrixList *)malloc(sizeof(CandlMatrixList)) ;
9700 - list->matrix = candl_matrix_read(file) ;
9701 - list->next = NULL ;
9703 - for (i=1;i<nb_matrices;i++)
9704 - { next = (CandlMatrixList *)malloc(sizeof(CandlMatrixList)) ;
9705 - next->matrix = candl_matrix_read(file) ;
9706 - next->next = NULL ;
9707 - now->next = next ;
9716 -/******************************************************************************
9717 - * Processing functions *
9718 - ******************************************************************************/
9722 - * candl_matrix_malloc function:
9723 - * This function allocates the memory space for a CandlMatrix structure and
9724 - * sets its fields with default values. Then it returns a pointer to the
9725 - * allocated space.
9726 - * - 09/12/2005: first version.
9728 -CandlMatrix * candl_matrix_malloc(int nb_rows, int nb_columns)
9729 -{ return pip_matrix_alloc(nb_rows,nb_columns) ;
9734 - * candl_matrix_list_malloc function:
9735 - * This function allocates the memory space for a CandlMatrixList structure and
9736 - * sets its fields with default values. Then it returns a pointer to the
9737 - * allocated space.
9738 - * - 11/12/2005: first version.
9740 -CandlMatrixList * candl_matrix_list_malloc()
9741 -{ CandlMatrixList * list ;
9743 - /* Memory allocation for the CandlDependence structure. */
9744 - list = (CandlMatrixList *)malloc(sizeof(CandlMatrixList)) ;
9746 - { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
9750 - /* We set the various fields with default values. */
9751 - list->matrix = NULL ;
9752 - list->next = NULL ;
9758 +#include <stdlib.h>
9761 +#include <string.h>
9762 +#include <osl/macros.h>
9763 +#include <osl/relation.h>
9764 +#include <osl/extensions/dependence.h>
9765 +#include <candl/macros.h>
9766 +#include <candl/matrix.h>
9767 +#include <candl/violation.h>
9768 +#include <candl/piplib.h>
9769 +#include <candl/piplib-wrapper.h>
9773 @@ -335,7 +55,7 @@ CandlMatrixList * candl_matrix_list_malloc()
9774 * this function builds the constraint system corresponding to a violation of a
9775 * dependence, for a given transformation couple at a given depth.
9776 * - dependence is the constraint system of a dependence between two
9779 * - t_source is the transformation function for the source statement,
9780 * - t_target is the transformation function for the target statement,
9781 * - dimension is the transformation dimension checked for legality,
9782 @@ -343,116 +63,249 @@ CandlMatrixList * candl_matrix_list_malloc()
9784 * - 13/12/2005: first version (extracted from candl_violation).
9786 -CandlMatrix * candl_matrix_violation(dependence,t_source,t_target,
9788 -CandlMatrix * dependence, * t_source, * t_target ;
9789 -int dimension, nb_par ;
9790 -{ int i, j, nb_rows, nb_columns, constraint, s_dims, t_dims ;
9791 - CandlMatrix * system ;
9794 - CANDL_init(temp) ;
9796 - /* The number of dimensions of the source and target domains. */
9797 - s_dims = t_source->NbColumns - nb_par - 2 ;
9798 - t_dims = t_target->NbColumns - nb_par - 2 ;
9800 - /* Size of the constraint system. */
9801 - nb_rows = dependence->NbRows + dimension + 1 ;
9802 - nb_columns = dependence->NbColumns ;
9804 - /* We allocate memory space for the constraint system. */
9805 - system = candl_matrix_malloc(nb_rows, nb_columns) ;
9807 - /* We fill the constraint system (there is no need to put zeros in the
9808 - * empty zones since candl_matrix_alloc initialized all to 0):
9811 - /* 1. We copy the constraints of the dependence polyhedron. */
9812 - for (i = 0; i < dependence->NbRows; i++)
9813 - for (j = 0; j < dependence->NbColumns; j++)
9814 - CANDL_assign(system->p[i][j],dependence->p[i][j]) ;
9816 - constraint = dependence->NbRows ;
9818 - /* 2. We set the equality constraints (equality tag is already 0). */
9819 - for (i = 0; i < dimension; i++)
9820 - { /* The source dimension part. */
9821 - for (j = 1; j <= s_dims; j++)
9822 - CANDL_assign(system->p[constraint][j],t_source->p[i][j]) ;
9823 +candl_violation_p candl_matrix_violation(osl_dependence_p dependence,
9824 + osl_relation_p source,
9825 + osl_relation_p target,
9826 + int dimension, int nb_par) {
9827 + candl_violation_p violation;
9828 + osl_relation_p system;
9830 + int constraint = 0;
9831 + int precision = dependence->domain->precision;
9832 + int nb_rows, nb_columns;
9833 + int nb_output_dims, nb_input_dims, nb_local_dims;
9834 + int ind_source_output_scatt;
9835 + int ind_target_output_scatt;
9836 + int ind_source_local_scatt;
9837 + int ind_target_local_scatt;
9840 + /* Create a new violation structure */
9841 + violation = candl_violation_malloc();
9843 + violation->source_nb_output_dims_scattering = source->nb_output_dims;
9844 + violation->target_nb_output_dims_scattering = target->nb_output_dims;
9845 + violation->source_nb_local_dims_scattering = source->nb_local_dims;
9846 + violation->target_nb_local_dims_scattering = target->nb_local_dims;
9848 + /* Compute the system size */
9849 + nb_local_dims = dependence->domain->nb_local_dims +
9850 + violation->source_nb_local_dims_scattering +
9851 + violation->target_nb_local_dims_scattering;
9852 + nb_output_dims = dependence->domain->nb_output_dims +
9853 + violation->source_nb_output_dims_scattering;
9854 + nb_input_dims = dependence->domain->nb_input_dims +
9855 + violation->target_nb_output_dims_scattering;
9857 + nb_columns = nb_output_dims + nb_input_dims + nb_local_dims + nb_par + 2;
9858 + nb_rows = dependence->domain->nb_rows +
9859 + source->nb_rows + target->nb_rows +
9862 + system = osl_relation_pmalloc(precision, nb_rows, nb_columns);
9864 + /* Compute some indexes */
9865 + ind_source_output_scatt = 1 + dependence->domain->nb_output_dims;
9866 + ind_target_output_scatt = ind_source_output_scatt + source->nb_output_dims +
9867 + dependence->domain->nb_input_dims;
9868 + ind_source_local_scatt = ind_target_output_scatt + target->nb_output_dims +
9869 + dependence->domain->nb_local_dims;
9870 + ind_target_local_scatt = ind_source_local_scatt + source->nb_local_dims +
9871 + dependence->domain->nb_local_dims;
9872 + ind_params = ind_target_local_scatt + target->nb_local_dims;
9874 + /* 1. Copy the dependence domain */
9875 + for (i = 0 ; i < dependence->domain->nb_rows ; i++) {
9877 + osl_int_assign(precision,
9878 + &system->m[constraint][0],
9879 + dependence->domain->m[i][0]);
9883 + for (c = dependence->domain->nb_output_dims ; c > 0 ; c--, k++, j++)
9884 + osl_int_assign(precision,
9885 + &system->m[constraint][k],
9886 + dependence->domain->m[i][j]);
9888 + k += source->nb_output_dims;
9889 + for (c = dependence->domain->nb_input_dims ; c > 0 ; c--, k++, j++)
9890 + osl_int_assign(precision,
9891 + &system->m[constraint][k],
9892 + dependence->domain->m[i][j]);
9893 + /* source local dims */
9894 + k += target->nb_output_dims;
9895 + for (c = dependence->source_nb_local_dims_domain +
9896 + dependence->source_nb_local_dims_access ; c > 0 ; c--, k++, j++)
9897 + osl_int_assign(precision,
9898 + &system->m[constraint][k],
9899 + dependence->domain->m[i][j]);
9900 + /* target local dims */
9901 + k += source->nb_local_dims;
9902 + for (c = dependence->target_nb_local_dims_domain +
9903 + dependence->target_nb_local_dims_access ; c > 0 ; c--, k++, j++)
9904 + osl_int_assign(precision,
9905 + &system->m[constraint][k],
9906 + dependence->domain->m[i][j]);
9907 + /* params + const */
9909 + for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
9910 + osl_int_assign(precision,
9911 + &system->m[constraint][k],
9912 + dependence->domain->m[i][j]);
9916 + /* 2. Copy the source scattering */
9917 + for (i = 0 ; i < source->nb_rows ; i++) {
9919 + osl_int_assign(precision,
9920 + &system->m[constraint][0],
9923 + k = ind_source_output_scatt;
9925 + for (c = source->nb_output_dims ; c > 0 ; c--, k++, j++)
9926 + osl_int_assign(precision,
9927 + &system->m[constraint][k],
9929 + /* input dims (linked with the output dims of domain) */
9931 + for (c = source->nb_input_dims ; c > 0 ; c--, k++, j++)
9932 + osl_int_assign(precision,
9933 + &system->m[constraint][k],
9936 + k = ind_source_local_scatt;
9937 + for (c = source->nb_local_dims ; c > 0 ; c--, k++, j++)
9938 + osl_int_assign(precision,
9939 + &system->m[constraint][k],
9941 + /* params + const */
9943 + for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
9944 + osl_int_assign(precision,
9945 + &system->m[constraint][k],
9950 - /* The -target dimension part. */
9951 - for (; j <= s_dims + t_dims; j++)
9952 - { CANDL_oppose(temp,t_target->p[i][j - s_dims]) ;
9953 - CANDL_assign(system->p[constraint][j], temp) ;
9954 + /* 2. Copy the target scattering */
9955 + for (i = 0 ; i < target->nb_rows ; i++) {
9957 + osl_int_assign(precision,
9958 + &system->m[constraint][0],
9961 + k = ind_target_output_scatt;
9963 + for (c = target->nb_output_dims ; c > 0 ; c--, k++, j++) {
9964 + osl_int_assign(precision,
9965 + &system->m[constraint][k],
9967 + osl_int_oppose(precision,
9968 + &system->m[constraint][k],
9969 + system->m[constraint][k]);
9972 - /* The source-target parameter/scalar part. */
9973 - for (; j < nb_columns; j++)
9974 - CANDL_subtract(system->p[constraint][j],
9975 - t_source->p[i][j - t_dims],
9976 - t_target->p[i][j - s_dims]) ;
9978 + /* input dims (linked with the output dims of domain) */
9979 + k = 1 + nb_output_dims;
9980 + for (c = target->nb_input_dims ; c > 0 ; c--, k++, j++) {
9981 + osl_int_assign(precision,
9982 + &system->m[constraint][k],
9984 + osl_int_oppose(precision,
9985 + &system->m[constraint][k],
9986 + system->m[constraint][k]);
9989 + k = ind_target_local_scatt;
9990 + for (c = target->nb_local_dims ; c > 0 ; c--, k++, j++) {
9991 + osl_int_assign(precision,
9992 + &system->m[constraint][k],
9994 + osl_int_oppose(precision,
9995 + &system->m[constraint][k],
9996 + system->m[constraint][k]);
9998 + /* params + const */
10000 + for (c = nb_par+1 ; c > 0 ; c--, k++, j++) {
10001 + osl_int_assign(precision,
10002 + &system->m[constraint][k],
10003 + target->m[i][j]);
10004 + osl_int_oppose(precision,
10005 + &system->m[constraint][k],
10006 + system->m[constraint][k]);
10011 - /* 3. We set the target < source constraint. */
10012 - /* This is an inequality. */
10013 - CANDL_set_si(system->p[constraint][0], 1) ;
10015 - /* The source dimension part. */
10016 - for (j = 1; j<= s_dims; j++)
10017 - CANDL_assign(system->p[constraint][j],t_source->p[dimension][j]) ;
10019 - /* The -target dimension part. */
10020 - for (; j<= s_dims + t_dims; j++)
10021 - { CANDL_oppose(temp,t_target->p[dimension][j - s_dims]) ;
10022 - CANDL_assign(system->p[constraint][j],temp) ;
10024 + /* 3. We set the equality constraints */
10025 + k = ind_source_output_scatt;
10026 + j = ind_target_output_scatt;
10027 + for (i = 1; i < dimension; i++, k++, j++) {
10029 + osl_int_set_si(precision, &system->m[constraint][k], 1);
10031 + osl_int_set_si(precision, &system->m[constraint][j], -1);
10035 - /* The source-target parameter/scalar part. */
10036 - for (; j < nb_columns; j++)
10037 - CANDL_subtract(system->p[constraint][j],
10038 - t_source->p[dimension][j - t_dims],
10039 - t_target->p[dimension][j - s_dims]) ;
10040 + /* 4. We set the target < source constraint. */
10041 + osl_int_set_si(precision, &system->m[constraint][0], 1);
10043 + osl_int_set_si(precision, &system->m[constraint][k], 1);
10045 + osl_int_set_si(precision, &system->m[constraint][j], -1);
10046 /* We subtract 1 to the scalar to achieve >0 constraint. */
10047 - CANDL_decrement(system->p[constraint][nb_columns - 1],
10048 - system->p[constraint][nb_columns - 1]) ;
10050 - CANDL_clear(temp) ;
10052 + osl_int_decrement(precision,
10053 + &system->m[constraint][nb_columns - 1],
10054 + system->m[constraint][nb_columns - 1]);
10056 + system->nb_output_dims = nb_output_dims;
10057 + system->nb_input_dims = nb_input_dims;
10058 + system->nb_parameters = nb_par;
10059 + system->nb_local_dims = nb_local_dims;
10060 + system->type = OSL_UNDEFINED;
10062 + violation->domain = system;
10064 + return violation;
10071 * candl_matrix_check_point function:
10072 * This function checks if there is an integral point in the set of
10073 * constraints, provided a given domain (possibly NULL).
10075 + * FIXME : is it the same as pip_has_rational_point ?
10076 + * here options->Nq = 1 (default)
10079 -candl_matrix_check_point (CandlMatrix* domain,
10080 - CandlMatrix* context)
10082 -#ifdef CANDL_HAS_PIPLIB_HYBRID
10083 - return piplib_hybrid_has_integer_point (domain, context, 0);
10085 +candl_matrix_check_point(osl_relation_p domain,
10086 + osl_relation_p context) {
10087 +// FIXME : compatibility with osl
10088 +//#ifdef CANDL_HAS_PIPLIB_HYBRID
10089 +// return piplib_hybrid_has_integer_point (domain, context, 0);
10091 PipOptions* options;
10092 PipQuast* solution;
10094 - options = pip_options_init ();
10095 + options = pip_options_init();
10096 options->Simplify = 1;
10097 options->Urs_parms = -1;
10098 options->Urs_unknowns = -1;
10099 - solution = pip_solve (domain, context, -1, options);
10101 + solution = pip_solve_osl(domain, context, -1, options);
10103 if ((solution != NULL) &&
10104 ((solution->list != NULL) || (solution->condition != NULL)))
10106 - pip_options_free (options);
10107 - pip_quast_free (solution);
10108 + pip_options_free(options);
10109 + pip_quast_free(solution);
10116 diff --git a/source/options.c b/source/options.c
10117 index fea449f..91a738a 100644
10118 --- a/source/options.c
10119 +++ b/source/options.c
10121 **---- \#/ --------------------------------------------------------**
10122 ** .-"#'-. First version: september 8th 2003 **
10123 **--- |"-.-"| -------------------------------------------------------**
10128 ******** | | *************************************************************
10129 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
10130 ******************************************************************************
10132 #include <stdlib.h>
10134 #include <string.h>
10135 -#include <candl/candl.h>
10136 +#include <candl/macros.h>
10137 #include <candl/options.h>
10140 @@ -48,12 +48,11 @@
10143 * candl_option_print function:
10144 - * This function prints the content of a CandlOptions structure (program) into
10145 + * This function prints the content of a candl_options_t structure (program) into
10146 * a file (foo, possibly stdout).
10147 * April 19th 2003: first version.
10149 -void candl_options_print(FILE * foo, CandlOptions * options)
10151 +void candl_options_print(FILE * foo, candl_options_p options) {
10152 fprintf(foo, "Options:\n");
10155 @@ -65,11 +64,10 @@ void candl_options_print(FILE * foo, CandlOptions * options)
10158 * candl_options_free function:
10159 - * This function frees the allocated memory for a CandlOptions structure.
10160 + * This function frees the allocated memory for a candl_options_t structure.
10161 * April 19th 2003: first version.
10163 -void candl_options_free(CandlOptions * options)
10165 +void candl_options_free(candl_options_p options) {
10169 @@ -81,19 +79,17 @@ void candl_options_free(CandlOptions * options)
10172 * candl_options_malloc function:
10173 - * This functions allocate the memory space for a CandlOptions structure and
10174 + * This functions allocate the memory space for a candl_options_t structure and
10175 * fill its fields with the defaults values. It returns a pointer to the
10176 - * allocated CandlOptions structure.
10177 + * allocated candl_options_t structure.
10178 * April 19th 2003: first version.
10180 -CandlOptions * candl_options_malloc(void)
10182 - CandlOptions * options;
10184 - /* Memory allocation for the CandlOptions structure. */
10185 - options = (CandlOptions *) malloc(sizeof(CandlOptions));
10186 - if (options == NULL)
10188 +candl_options_p candl_options_malloc(void) {
10189 + candl_options_p options;
10191 + /* Memory allocation for the candl_options_t structure. */
10192 + options = (candl_options_p) malloc(sizeof(candl_options_t));
10193 + if (options == NULL) {
10194 fprintf(stderr, "[Candl]ERROR: memory overflow.\n");
10197 @@ -106,16 +102,13 @@ CandlOptions * candl_options_malloc(void)
10198 options->rar = 0; /* RAR (input) dependences don't matter. */
10199 options->commute = 0; /* Don't use commutativity to simplify dependences.*/
10200 options->fullcheck = 0; /* Don't compute all violations.*/
10201 - options->depgraph = 0; /* Don't print the dependence graph.*/
10202 - options->violgraph = 0; /* Don' compute the violation graph.*/
10203 options->scalar_renaming = 0; /* Don't enable scalar renaming. */
10204 options->scalar_privatization = 0; /* Don't enable scalar privatization. */
10205 options->scalar_expansion = 0; /* Don't enable scalar expansion. */
10206 options->lastwriter = 0; /* Compute the last writer for RAW and WAW dependences */
10207 - options->readscop = 0; /* Don't read a .scop format for the input. */
10208 - options->writescop = 0; /* Don't write a .scop format for the output. */
10209 - options->scoptocandl = 0; /* Don't act as a .scop to candl converter. */
10210 options->verbose = 0; /* Don't be verbose. */
10211 + options->outscop = 0; /* Don't print the scop. */
10212 + options->autocorrect = 0; /* Don't correct violations. */
10213 /* UNDOCUMENTED OPTIONS FOR THE AUTHOR ONLY */
10214 options->view = 0; /* Do not visualize the graph with dot and gv.*/
10215 options->structure = 0; /* Don't print internal dependence structure. */
10216 @@ -132,54 +125,54 @@ CandlOptions * candl_options_malloc(void)
10217 * limitation of the ISO C 89 compilers.
10218 * August 5th 2002: first version.
10220 -void candl_options_help()
10222 - "Usage: candl [ options | file ] ...\n"
10223 - "Options for data dependence computation:\n"
10224 - " -waw <boolean> Consider WAW (output) dependences (1) or not (0)\n"
10225 - " (default setting: 1).\n"
10226 - " -raw <boolean> Consider RAW (flow) dependences (1) or not (0)\n"
10227 - " (default setting: 1).\n"
10228 - " -war <boolean> Consider WAR (anti) dependences (1) or not (0)\n"
10229 - " (default setting: 1).\n"
10230 - " -rar <boolean> Consider RAR (input) dependences (1) or not (0)\n"
10231 - " (default setting: 0).\n");
10232 +void candl_options_help() {
10234 + "Usage: candl [ options | file ] ...\n"
10235 + "Options for data dependence computation:\n"
10236 + " -waw <boolean> Consider WAW (output) dependences (1) or not (0)\n"
10237 + " (default setting: 1).\n"
10238 + " -raw <boolean> Consider RAW (flow) dependences (1) or not (0)\n"
10239 + " (default setting: 1).\n"
10240 + " -war <boolean> Consider WAR (anti) dependences (1) or not (0)\n"
10241 + " (default setting: 1).\n"
10242 + " -rar <boolean> Consider RAR (input) dependences (1) or not (0)\n"
10243 + " (default setting: 0).\n");
10245 - " -commute <boolean> Consider commutativity (1) or not (0)\n"
10246 - " (default setting: 0).\n"
10247 - " -fullcheck <boolean> Compute all legality violation (1) or only one (0)\n"
10248 - " (default setting: 0).\n"
10249 - " -depgraph <boolean> Ask to print the dependence graph (1) or not (0)\n"
10250 - " (default setting: 0 but 1 if no transformation).\n"
10251 - " -violgraph <boolean> Ask to print the violation graph (1) or not (0)\n"
10252 - " (default setting: 1 but 0 if no transformation).\n"
10253 - " -scalren <boolean> Ask to enable scalar renaming (1) or not (0)\n"
10254 - " (default setting: 0).\n"
10255 - " -scalpriv <boolean> Ask to enable scalar privatization (1) or not (0)\n"
10256 - " (default setting: 0).\n"
10257 - " -scalexp <boolean> Ask to enable scalar expansion (1) or not (0)\n"
10258 - " (default setting: 0).\n");
10259 + " -commute <boolean> Consider commutativity (1) or not (0)\n"
10260 + " (default setting: 0).\n"
10261 + " -fullcheck <boolean> Compute all legality violation (1) or just the\n"
10263 + " (default setting: 0, or 1 if autocorrect is set).\n"
10264 + " -scalren <boolean> Ask to enable scalar renaming (1) or not (0)\n"
10265 + " (default setting: 0).\n"
10266 + " -scalpriv <boolean> Ask to enable scalar privatization (1) or not (0)\n"
10267 + " (default setting: 0).\n"
10268 + " -scalexp <boolean> Ask to enable scalar expansion (1) or not (0)\n"
10269 + " (default setting: 0).\n");
10271 - " -view Ask to display the graphs (1) or not (0)\n"
10272 - " (requires dot -graphviz- and gv tools).\n");
10273 + " -view Ask to display the graphs (1) or not (0)\n"
10274 + " (requires dot -graphviz- and gv tools).\n");
10276 - "\nGeneral options:\n"
10277 -#ifdef CANDL_SUPPORTS_SCOPLIB
10278 - " -inscop Read a .scop formatted file as the input.\n"
10279 - " -outscop Output a .scop formatted file as the output.\n"
10280 - " -scoptocandl Output a .candl formatted file from a .scop input.\n"
10282 - " -o <output> Name of the output file; 'stdout' is a special\n"
10283 - " value: when used, output is standard output\n"
10284 - " (default setting: stdout).\n"
10285 - " -verbose Display a verbose output.\n"
10286 - " -v, --version Display the version information.\n"
10287 - " -h, --help Display this information.\n\n"
10288 - "The special value 'stdin' for 'file' makes Candl to read data on\n"
10289 - "standard input.\n\n"
10290 - "For bug reporting or any suggestions, please send an email to the author\n"
10291 - "<cedric.bastoul@inria.fr> or to the maintainer of Candl:\n"
10292 - "<pouchet@cse.ohio-state.edu>.\n");
10293 + "\nGeneral options:\n"
10294 + " -test <origscop> Test violations with the original scop.\n"
10295 + //" -autocorrect <boolean> Correct violations with a shifting (1) or not(0)\n"
10296 + " -test must be set\n"
10297 + " (default setting: 0).\n"
10298 + " -outscop Output a .scop formatted file as the output.\n"
10299 + " -o <output> Name of the output file; 'stdout' is a special\n"
10300 + " value: when used, output is standard output\n"
10301 + " (default setting: stdout).\n"
10302 + " -verbose Display a verbose output.\n"
10303 + " -v, --version Display the version information.\n"
10304 + " -h, --help Display this information.\n\n"
10305 + "The special value 'stdin' for 'file' makes Candl to read data on standard\n"
10307 + "If the -test is not given, the dependences graph of the input 'file' will\n"
10308 + "be computed, otherwise it's the violation graph between 'origscop' and 'file'"
10310 + "For bug reporting or any suggestions, please send an email to the author\n"
10311 + "<cedric.bastoul@inria.fr> or to the maintainer of Candl:\n"
10312 + "<pouchet@cse.ohio-state.edu>.\n");
10316 @@ -190,32 +183,31 @@ void candl_options_help()
10317 * characters limitation of the ISO C 89 compilers.
10318 * August 5th 2002: first version.
10320 -void candl_options_version()
10321 -{ printf("Candl %s %s bits The Chunky Dependence Analyzer\n",
10322 +void candl_options_version() { printf("Candl %s %s bits The Chunky Dependence Analyzer\n",
10323 CANDL_RELEASE,CANDL_VERSION);
10326 - "Candl is a dependence analyzer for static control programs, coming from \n"
10327 - "the CHUNKY project: a research tool for data-locality improvement. This \n"
10328 - "program is distributed under the terms of the GNU Lesser General Public\n"
10329 - "License (details at http://www.gnu.org/copyleft/gpl.html).\n"
10332 + "Candl is a dependence analyzer for static control programs, coming from \n"
10333 + "the CHUNKY project: a research tool for data-locality improvement. This \n"
10334 + "program is distributed under the terms of the GNU Lesser General Public\n"
10335 + "License (details at http://www.gnu.org/copyleft/gpl.html).\n"
10338 - "It would be kind to refer the following paper in any publication "
10339 - "resulting \nfrom the use of this software or its library:\n"
10340 - "@Article{Bas05,\n"
10341 - "author = {Cedric Bastoul and Paul Feautrier},\n"
10342 - "title = {Adjusting a program transformation for legality},\n"
10343 - "journal = {Parallel Processing Letters},\n"
10347 - "pages = {3--17},\n"
10348 - "month = {March},\n"
10351 - "For bug reporting or any suggestions, please send an email to the author\n"
10352 - "<cedric.bastoul@inria.fr>.\n");
10353 + "It would be kind to refer the following paper in any publication "
10354 + "resulting \nfrom the use of this software or its library:\n"
10355 + "@Article{Bas05,\n"
10356 + "author = {Cedric Bastoul and Paul Feautrier},\n"
10357 + "title = {Adjusting a program transformation for legality},\n"
10358 + "journal = {Parallel Processing Letters},\n"
10362 + "pages = {3--17},\n"
10363 + "month = {March},\n"
10366 + "For bug reporting or any suggestions, please send an email to the author\n"
10367 + "<cedric.bastoul@inria.fr>.\n");
10371 @@ -229,20 +221,17 @@ void candl_options_version()
10372 * August 5th 2002: first version.
10373 * June 29th 2003: (debug) lack of argument now detected.
10375 -void candl_options_set(int * option, int argc, char ** argv, int * number)
10377 +void candl_options_set(int * option, int argc, char ** argv, int * number) {
10380 - if (*number+1 >= argc)
10382 + if (*number+1 >= argc) {
10383 fprintf(stderr, "[Candl]ERROR: an option lacks of argument.\n");
10388 *option = strtol(argv[*number+1],endptr,10);
10389 - if (endptr != NULL)
10391 + if (endptr != NULL) {
10392 fprintf(stderr, "[Candl]ERROR: %s option value is not valid.\n",
10395 @@ -254,155 +243,167 @@ void candl_options_set(int * option, int argc, char ** argv, int * number)
10397 * candl_options_read function:
10398 * This functions reads all the options and the input/output files thanks
10399 - * the the user's calling line elements (in argc). It fills a CandlOptions
10400 + * the the user's calling line elements (in argc). It fills a candl_options_t
10401 * structure and the FILE structure corresponding to input and output files.
10402 * August 5th 2002: first version.
10403 - * April 19th 2003: now in options.c and support of the CandlOptions structure.
10404 + * April 19th 2003: now in options.c and support of the candl_options_t structure.
10406 void candl_options_read(int argc, char** argv, FILE** input, FILE** output,
10407 - CandlOptions** options)
10409 - int i, infos = 0, input_is_set = 0;
10410 + FILE **input_test, candl_options_p* options) {
10411 + int i, infos = 0, input_is_set = 0, testscop_is_set = 0;
10413 - /* CandlOptions structure allocation and initialization. */
10414 + /* candl_options_t structure allocation and initialization. */
10415 *options = candl_options_malloc();
10416 /* The default output is the standard output. */
10419 - for (i = 1; i < argc; i++)
10420 - if (argv[i][0] == '-')
10422 - if (!strcmp(argv[i], "-waw"))
10423 - candl_options_set(&(*options)->waw, argc, argv, &i);
10425 - if (!strcmp(argv[i], "-raw"))
10426 - candl_options_set(&(*options)->raw, argc, argv, &i);
10428 - if (!strcmp(argv[i], "-war"))
10429 - candl_options_set(&(*options)->war, argc, argv, &i);
10431 - if (!strcmp(argv[i], "-rar"))
10432 - candl_options_set(&(*options)->rar, argc, argv, &i);
10434 - if (!strcmp(argv[i], "-commute"))
10435 - candl_options_set(&(*options)->commute, argc, argv, &i);
10437 - if (!strcmp(argv[i], "-fullcheck"))
10438 - candl_options_set(&(*options)->fullcheck, argc, argv, &i);
10440 - if (!strcmp(argv[i], "-depgraph"))
10441 - candl_options_set(&(*options)->depgraph, argc, argv, &i);
10443 - if (!strcmp(argv[i], "-violgraph"))
10444 - candl_options_set(&(*options)->violgraph, argc, argv, &i);
10446 - if (!strcmp(argv[i], "-scalren"))
10447 - candl_options_set(&(*options)->scalar_renaming, argc, argv, &i);
10449 - if (!strcmp(argv[i], "-scalpriv"))
10450 - candl_options_set(&(*options)->scalar_privatization, argc, argv, &i);
10452 - if (!strcmp(argv[i], "-scalexp"))
10453 - candl_options_set(&(*options)->scalar_expansion, argc, argv, &i);
10455 - if (!strcmp(argv[i], "-lastwriter"))
10456 - candl_options_set(&(*options)->lastwriter, argc, argv, &i);
10458 - if (!strcmp(argv[i], "-view"))
10459 - (*options)->view = 1;
10461 - if (!strcmp(argv[i], "-verbose"))
10462 - (*options)->verbose = 1;
10464 - if (!strcmp(argv[i], "-inscop"))
10465 - (*options)->readscop = 1;
10467 - if (!strcmp(argv[i], "-outscop"))
10468 - (*options)->writescop = 1;
10470 - if (!strcmp(argv[i], "-scoptocandl"))
10471 - (*options)->scoptocandl = 1;
10473 - if (!strcmp(argv[i], "-prune-dups"))
10474 - (*options)->prune_dups = 1;
10476 - if ((!strcmp(argv[i], "-struct")) ||
10477 - (!strcmp(argv[i], "-structure")))
10478 - (*options)->structure = 1;
10480 - if ((!strcmp(argv[i], "--help")) || (!strcmp(argv[i], "-h")))
10482 - candl_options_help();
10486 - if ((!strcmp(argv[i], "--version")) || (!strcmp(argv[i], "-v")))
10488 - candl_options_version();
10492 - if (!strcmp(argv[i], "-o"))
10497 - "[Candl]ERROR: no output name for -o option.\n");
10501 - /* stdout is a special value, when used, we set output to standard
10504 - if (!strcmp(argv[i+1], "stdout"))
10505 - *output = stdout;
10508 - *output = fopen(argv[i+1], "w");
10509 - if (*output == NULL)
10512 - "[Candl]ERROR: can't create output file %s.\n",
10520 - fprintf(stderr, "[Candl]ERROR: unknown %s option.\n", argv[i]);
10521 + *input_test = NULL;
10523 + for (i = 1; i < argc; i++) {
10524 + if (argv[i][0] == '-') {
10525 + if (!strcmp(argv[i], "-waw")) {
10526 + candl_options_set(&(*options)->waw, argc, argv, &i);
10528 + if (!strcmp(argv[i], "-raw")) {
10529 + candl_options_set(&(*options)->raw, argc, argv, &i);
10531 + if (!strcmp(argv[i], "-war")) {
10532 + candl_options_set(&(*options)->war, argc, argv, &i);
10534 + if (!strcmp(argv[i], "-rar")) {
10535 + candl_options_set(&(*options)->rar, argc, argv, &i);
10537 + if (!strcmp(argv[i], "-commute")) {
10538 + candl_options_set(&(*options)->commute, argc, argv, &i);
10540 + if (!strcmp(argv[i], "-fullcheck")) {
10541 + candl_options_set(&(*options)->fullcheck, argc, argv, &i);
10543 + if (!strcmp(argv[i], "-scalren")) {
10544 + candl_options_set(&(*options)->scalar_renaming, argc, argv, &i);
10546 + if (!strcmp(argv[i], "-scalpriv")) {
10547 + candl_options_set(&(*options)->scalar_privatization, argc, argv, &i);
10549 + if (!strcmp(argv[i], "-scalexp")) {
10550 + candl_options_set(&(*options)->scalar_expansion, argc, argv, &i);
10552 + if (!strcmp(argv[i], "-lastwriter")) {
10553 + candl_options_set(&(*options)->lastwriter, argc, argv, &i);
10555 + if (!strcmp(argv[i], "-autocorrect")) {
10556 + candl_options_set(&(*options)->autocorrect, argc, argv, &i);
10558 + if (!strcmp(argv[i], "-view")) {
10559 + (*options)->view = 1;
10561 + if (!strcmp(argv[i], "-verbose")) {
10562 + (*options)->verbose = 1;
10564 + if (!strcmp(argv[i], "-outscop")) {
10565 + (*options)->outscop = 1;
10567 + if (!strcmp(argv[i], "-prune-dups")) {
10568 + (*options)->prune_dups = 1;
10570 + if ((!strcmp(argv[i], "-struct")) ||
10571 + (!strcmp(argv[i], "-structure"))) {
10572 + (*options)->structure = 1;
10574 + if ((!strcmp(argv[i], "--help")) || (!strcmp(argv[i], "-h"))) {
10575 + candl_options_help();
10578 + if ((!strcmp(argv[i], "--version")) || (!strcmp(argv[i], "-v"))) {
10579 + candl_options_version();
10582 + if (!strcmp(argv[i], "-o")) {
10586 + "[Candl]ERROR: no output name for -o option.\n");
10590 + /* stdout is a special value, when used, we set output to standard
10593 + if (!strcmp(argv[i], "stdout")) {
10594 + *output = stdout;
10596 + *output = fopen(argv[i], "w");
10597 + if (*output == NULL) {
10599 + "[Candl]ERROR: can't create output file %s.\n",
10605 + if (!strcmp(argv[i], "-test")) {
10607 + if (!testscop_is_set) {
10608 + testscop_is_set = i;
10609 + /* stdin is a special value, when used, we set input to
10610 + standard input. */
10611 + if (!strcmp(argv[i], "stdin")) {
10612 + *input_test = stdin;
10614 + *input_test = fopen(argv[i], "r");
10615 + if (*input_test == NULL) {
10617 + "[Candl]ERROR: %s file does not exist.\n", argv[i]);
10622 + fprintf(stderr, "[Candl]ERROR: multiple input files.\n");
10626 + fprintf(stderr, "[Candl]ERROR: unknown %s option.\n", argv[i]);
10630 - if (!input_is_set)
10632 - input_is_set = 1;
10633 - /* stdin is a special value, when used, we set input to
10634 - standard input. */
10635 - if (!strcmp(argv[i], "stdin"))
10639 - *input = fopen(argv[i], "r");
10640 - if (*input == NULL)
10643 - "[Candl]ERROR: %s file does not exist.\n", argv[i]);
10648 + else { /* open a file */
10649 + if (!input_is_set) {
10650 + input_is_set = i;
10651 + /* stdin is a special value, when used, we set input to
10652 + standard input. */
10653 + if (!strcmp(argv[i], "stdin")) {
10656 + *input = fopen(argv[i], "r");
10657 + if (*input == NULL) {
10659 + "[Candl]ERROR: %s file does not exist.\n", argv[i]);
10664 + CANDL_error("multiple input files.\n");
10668 - fprintf(stderr, "[Candl]ERROR: multiple input files.\n");
10672 - if (!input_is_set)
10675 - fprintf(stderr, "[Candl]ERROR: no input file (-h for help).\n");
10679 + if ((*options)->autocorrect) {
10680 + (*options)->fullcheck = 1;
10681 + if (!*input_test)
10682 + CANDL_error("no test file (-h for help).\n");
10685 + if (!input_is_set) {
10687 + CANDL_error("no input file (-h for help).\n");
10691 + if (*input_test && !strcmp(argv[input_is_set], argv[testscop_is_set])) {
10693 + CANDL_error("the input file and the test scop can't be the same file.\n");
10701 diff --git a/source/piplib-wrapper.c b/source/piplib-wrapper.c
10702 index 2ff4bb7..cdd44f3 100644
10703 --- a/source/piplib-wrapper.c
10704 +++ b/source/piplib-wrapper.c
10707 - /**------ ( ----------------------------------------------------------**
10709 - **----- / ) --------------------------------------------------------**
10710 - ** ( * ( piplib-wrapper.c **
10711 - **---- \#/ --------------------------------------------------------**
10712 - ** .-"#'-. First version: January 31st 2012 **
10713 - **--- |"-.-"| -------------------------------------------------------**
10716 +/**------ ( ----------------------------------------------------------**
10718 + **----- / ) --------------------------------------------------------**
10719 + ** ( * ( piplib-wrapper.c **
10720 + **---- \#/ --------------------------------------------------------**
10721 + ** .-"#'-. First version: January 31st 2012 **
10722 + **--- |"-.-"| -------------------------------------------------------**
10725 ******** | | *************************************************************
10726 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
10727 ******************************************************************************
10728 @@ -42,16 +42,99 @@
10730 #include <string.h>
10731 #include <candl/candl.h>
10732 +#include <osl/macros.h> /* Need OSL_PRECISION for compatibility with piplib */
10733 +#include <osl/relation.h>
10734 +#include <candl/macros.h>
10735 +#include <candl/piplib.h>
10739 -pip_has_rational_point(PipMatrix* system,
10740 - PipMatrix* context,
10741 - int conservative)
10743 -#ifdef CANDL_HAS_PIPLIB_HYBRID
10744 - return piplib_hybrid_has_rational_point(system, context, conservative);
10747 + * pip_relation2matrix function :
10748 + * This function is used to keep the compatibility with Piplib
10750 +PipMatrix* pip_relation2matrix(osl_relation_p in) {
10751 + int i, j, precision;
10757 + #ifdef CANDL_LINEAR_VALUE_IS_INT
10758 + precision = OSL_PRECISION_SP;
10759 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
10760 + precision = OSL_PRECISION_DP;
10761 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
10762 + precision = OSL_PRECISION_MP;
10765 + if (precision != in->precision)
10766 + CANDL_error("Precision not compatible with piplib ! (pip_relation2matrix)");
10768 + out = pip_matrix_alloc(in->nb_rows, in->nb_columns);
10770 + for (i = 0 ; i < in->nb_rows ; i++) {
10771 + for (j = 0 ; j < in->nb_columns ; j++) {
10772 + #if defined(CANDL_LINEAR_VALUE_IS_INT)
10773 + CANDL_assign(out->p[i][j], in->m[i][j].sp);
10774 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
10775 + CANDL_assign(out->p[i][j], in->m[i][j].dp);
10776 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
10777 + CANDL_assign(out->p[i][j], *((mpz_t*)in->m[i][j].mp));
10787 + * pip_matrix2relation function :
10788 + * This function is used to keep the compatibility with Piplib
10790 +osl_relation_p pip_matrix2relation(PipMatrix* in) {
10791 + int i, j, precision;
10792 + osl_relation_p out;
10798 + #if defined(CANDL_LINEAR_VALUE_IS_INT)
10799 + precision = OSL_PRECISION_SP;
10800 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
10801 + precision = OSL_PRECISION_DP;
10802 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
10803 + precision = OSL_PRECISION_MP;
10806 + out = osl_relation_pmalloc(precision, in->NbRows, in->NbColumns);
10807 + osl_int_init(precision, &temp);
10809 + for (i = 0 ; i < in->NbRows ; i++) {
10810 + for (j = 0 ; j < in->NbColumns ; j++) {
10811 + #ifdef CANDL_LINEAR_VALUE_IS_INT
10812 + temp.sp = in->p[i][j];
10813 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
10814 + temp.dp = in->p[i][j];
10815 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
10816 + mpz_set(*((mpz_t*)temp.mp), in->p[i][j]);
10818 + osl_int_assign(precision, &out->m[i][j], temp);
10822 + osl_int_clear(precision, &temp);
10826 +int pip_has_rational_point(osl_relation_p system,
10827 + osl_relation_p context,
10828 + int conservative) {
10829 +// FIXME : compatibility with osl
10830 +//#ifdef CANDL_HAS_PIPLIB_HYBRID
10831 +// return piplib_hybrid_has_rational_point(system, context, conservative);
10833 PipOptions* options;
10835 options = pip_options_init ();
10836 @@ -59,13 +142,256 @@ pip_has_rational_point(PipMatrix* system,
10837 options->Urs_parms = -1;
10838 options->Urs_unknowns = -1;
10840 - PipQuast* solution = pip_solve (system, context, -1, options);
10841 + PipQuast* solution = pip_solve_osl(system, context, -1, options);
10842 if ((solution != NULL) &&
10843 ((solution->list != NULL) || (solution->condition != NULL)))
10845 - pip_options_free (options);
10846 - pip_quast_free (solution);
10847 + pip_options_free(options);
10848 + pip_quast_free(solution);
10856 + * pip_solve_osl function :
10857 + * A pip_solve with osl_relation_p instead of PipMatrix
10859 +PipQuast* pip_solve_osl(osl_relation_p inequnk, osl_relation_p ineqpar,
10860 + int Bg, PipOptions *options) {
10861 + PipMatrix *pip_unk = pip_relation2matrix(inequnk);
10862 + PipMatrix *pip_par = pip_relation2matrix(ineqpar);
10863 + PipQuast *solution = pip_solve(pip_unk, pip_par, Bg, options);
10864 + if (pip_unk) pip_matrix_free(pip_unk);
10865 + if (pip_par) pip_matrix_free(pip_par);
10871 + * Return true if the 'size' first elements of 'l1' and 'l2' are equal.
10873 +int piplist_are_equal(PipList* l1, PipList* l2, int size) {
10874 + if (l1 == NULL && l2 == NULL)
10876 + if (l1 == NULL || l2 == NULL)
10878 + if (l1->vector == NULL && l2->vector == NULL)
10880 + if (l1->vector == NULL || l2->vector == NULL)
10884 + for (; l1 && l2 && count < size; l1 = l1->next, l2 = l2->next, ++count) {
10885 + if (l1->vector == NULL && l2->vector == NULL)
10887 + if (l1->vector == NULL || l2->vector == NULL)
10889 + if (l1->vector->nb_elements != l2->vector->nb_elements)
10892 + for (j = 0; j < l1->vector->nb_elements; ++j)
10893 + if (! CANDL_eq(l1->vector->the_vector[j],
10894 + l2->vector->the_vector[j]) ||
10895 + ! CANDL_eq(l1->vector->the_deno[j],
10896 + l2->vector->the_deno[j]))
10905 + * Converts all conditions where the path does not lead to a solution
10906 + * The return is a upip_quast_to_polyhedranion of polyhedra
10907 + * extracted from pip_quast_to_polyhedra
10909 +osl_relation_p pip_quast_no_solution_to_polyhedra(PipQuast *quast, int nvar,
10911 + osl_relation_p ep;
10912 + osl_relation_p tp;
10913 + osl_relation_p qp;
10914 + osl_relation_p iter;
10917 + if (quast == NULL)
10920 + #if defined(CANDL_LINEAR_VALUE_IS_INT)
10921 + precision = OSL_PRECISION_SP;
10922 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
10923 + precision = OSL_PRECISION_DP;
10924 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
10925 + precision = OSL_PRECISION_MP;
10928 + if (quast->condition != NULL) {
10929 + tp = pip_quast_no_solution_to_polyhedra(quast->next_then, nvar, npar);
10930 + ep = pip_quast_no_solution_to_polyhedra(quast->next_else, nvar, npar);
10932 + /* Each of the matrices in the then tree needs to be augmented with
10933 + * the condition */
10934 + for (iter = tp ; iter != NULL ; iter = iter->next) {
10935 + int nrows = iter->nb_rows;
10936 + osl_int_set_si(precision, &iter->m[nrows][0], 1);
10937 + for (j = 1; j < 1 + nvar; j++)
10938 + osl_int_set_si(precision, &iter->m[nrows][j], 0);
10939 + for (j = 0; j < npar + 1; j++)
10940 + osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
10941 + CANDL_get_si(quast->condition->the_vector[j]));
10942 + (iter->nb_rows)++;
10945 + for (iter = ep; iter != NULL ; iter = iter->next) {
10946 + int nrows = iter->nb_rows;
10948 + osl_int_set_si(precision, &iter->m[nrows][0], 1);
10949 + for (j = 1; j < 1 + nvar; j++)
10950 + osl_int_set_si(precision, &iter->m[nrows][j], 0);
10951 + for (j = 0; j < npar + 1; j++)
10952 + osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
10953 + -CANDL_get_si(quast->condition->the_vector[j]));
10954 + osl_int_decrement(precision,
10955 + &iter->m[nrows][iter->nb_columns - 1],
10956 + iter->m[nrows][iter->nb_columns - 1]);
10957 + (iter->nb_rows)++;
10960 + /* union of tp and ep */
10963 + for (iter = tp ; iter->next != NULL ; iter = iter->next)
10974 + if (quast->list != NULL)
10977 + /* quast condition is NULL */
10978 + osl_relation_p lwmatrix = osl_relation_pmalloc(precision, nvar+npar+1,
10980 + lwmatrix->nb_rows = 0;
10981 + lwmatrix->nb_parameters = npar;
10988 + * Converts a PIP quast to a union of polyhedra
10990 +osl_relation_p pip_quast_to_polyhedra(PipQuast *quast, int nvar, int npar) {
10991 + // originaly used for lastwriter
10992 + // july 5th 2012 : extracted from dependence.c
10994 + osl_relation_p ep;
10995 + osl_relation_p tp;
10996 + osl_relation_p qp;
10997 + osl_relation_p iter;
11000 + if (quast == NULL)
11003 + #if defined(CANDL_LINEAR_VALUE_IS_INT)
11004 + precision = OSL_PRECISION_SP;
11005 + #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
11006 + precision = OSL_PRECISION_DP;
11007 + #elif defined(CANDL_LINEAR_VALUE_IS_MP)
11008 + precision = OSL_PRECISION_MP;
11011 + if (quast->condition != NULL) {
11012 + tp = pip_quast_to_polyhedra(quast->next_then, nvar, npar);
11013 + ep = pip_quast_to_polyhedra(quast->next_else, nvar, npar);
11015 + /* Each of the matrices in the then tree needs to be augmented with
11016 + * the condition */
11017 + for (iter = tp ; iter != NULL ; iter = iter->next) {
11018 + int nrows = iter->nb_rows;
11019 + osl_int_set_si(precision, &iter->m[nrows][0], 1);
11020 + for (j = 1; j < 1 + nvar; j++)
11021 + osl_int_set_si(precision, &iter->m[nrows][j], 0);
11022 + for (j = 0; j < npar + 1; j++)
11023 + osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
11024 + CANDL_get_si(quast->condition->the_vector[j]));
11025 + (iter->nb_rows)++;
11028 + /* JP : july 5th 2012:
11029 + * Fix negation of a constraint in adding -1 to the constant
11032 + for (iter = ep; iter != NULL ; iter = iter->next) {
11033 + int nrows = iter->nb_rows;
11035 + osl_int_set_si(precision, &iter->m[nrows][0], 5);
11036 + for (j = 1; j < 1 + nvar; j++)
11037 + osl_int_set_si(precision, &iter->m[nrows][j], 0);
11038 + for (j = 0; j < npar + 1; j++)
11039 + osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
11040 + -CANDL_get_si(quast->condition->the_vector[j]));
11041 + osl_int_decrement(precision,
11042 + &iter->m[nrows][iter->nb_columns - 1],
11043 + iter->m[nrows][iter->nb_columns - 1]);
11044 + (iter->nb_rows)++;
11047 + /* union of tp and ep */
11050 + for (iter = tp ; iter->next != NULL ; iter = iter->next)
11060 + /* quast condition is NULL */
11061 + osl_relation_p lwmatrix = osl_relation_pmalloc(precision, nvar+npar+1,
11063 + PipList *vecList = quast->list;
11066 + while (vecList != NULL) {
11068 + osl_int_set_si(precision, &lwmatrix->m[count][0], 0);
11069 + for (j=0; j < nvar; j++)
11071 + osl_int_set_si(precision, &lwmatrix->m[count][j + 1], 1);
11073 + osl_int_set_si(precision, &lwmatrix->m[count][j + 1], 0);
11075 + for (j=0; j < npar; j++)
11076 + osl_int_set_si(precision, &lwmatrix->m[count][j + 1 + nvar],
11077 + -CANDL_get_si(vecList->vector->the_vector[j]));
11078 + /* Constant portion */
11079 + if (quast->newparm != NULL)
11080 + /* Don't handle newparm for now */
11081 + osl_int_set_si(precision, &lwmatrix->m[count][npar + 1 + nvar],
11082 + -CANDL_get_si(vecList->vector->the_vector[npar+1]));
11084 + osl_int_set_si(precision, &lwmatrix->m[count][npar + 1 + nvar],
11085 + -CANDL_get_si(vecList->vector->the_vector[npar]));
11089 + vecList = vecList->next;
11091 + lwmatrix->nb_rows = count;
11092 + lwmatrix->nb_parameters = npar;
11097 diff --git a/source/program.c b/source/program.c
11098 deleted file mode 100644
11099 index 003e753..0000000
11100 --- a/source/program.c
11104 - /**------ ( ----------------------------------------------------------**
11106 - **----- / ) --------------------------------------------------------**
11107 - ** ( * ( program.c **
11108 - **---- \#/ --------------------------------------------------------**
11109 - ** .-"#'-. First version: september 9th 2003 **
11110 - **--- |"-.-"| -------------------------------------------------------**
11113 - ******** | | *************************************************************
11114 - * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
11115 - ******************************************************************************
11117 - * Copyright (C) 2003-2008 Cedric Bastoul *
11119 - * This is free software; you can redistribute it and/or modify it under the *
11120 - * terms of the GNU Lesser General Public License as published by the Free *
11121 - * Software Foundation; either version 3 of the License, or (at your option) *
11122 - * any later version. *
11124 - * This software is distributed in the hope that it will be useful, but *
11125 - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
11126 - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
11127 - * for more details. *
11129 - * You should have received a copy of the GNU Lesser General Public License *
11130 - * along with software; if not, write to the Free Software Foundation, Inc., *
11131 - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
11133 - * CAnDL, the Chunky Dependence Analyzer *
11134 - * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
11136 - ******************************************************************************/
11139 -#include <sys/types.h>
11140 -#include <sys/time.h>
11141 -#include <sys/resource.h>
11142 -#include <stdlib.h>
11143 -#include <stdio.h>
11144 -#include <string.h>
11145 -#include <ctype.h>
11147 -#include <candl/candl.h>
11148 -#include <candl/program.h>
11151 -/******************************************************************************
11152 - * Structure display function *
11153 - ******************************************************************************/
11156 - * candl_program_print_structure function:
11157 - * Displays a candl_program_t structure (program) into a file (file,
11158 - * possibly stdout) in a way that trends to be understandable without falling
11159 - * in a deep depression or, for the lucky ones, getting a headache... It
11160 - * includes an indentation level (level) in order to work with others
11161 - * print_structure functions.
11162 - * - 09/09/2003: first version.
11164 -void candl_program_print_structure(FILE* file, candl_program_p program,
11169 - if (program != NULL)
11171 - /* Go to the right level. */
11172 - for (j = 0; j < level; j++)
11173 - fprintf(file,"|\t");
11174 - fprintf(file,"+-- candl_program_t\n");
11176 - /* A blank line. */
11177 - for (j = 0; j <= level + 1; j++)
11178 - fprintf(file,"|\t");
11179 - fprintf(file,"\n");
11181 - /* Print the context. */
11182 - candl_matrix_print_structure(file, program->context, level+1);
11184 - /* A blank line. */
11185 - for (j = 0; j <= level+1; j++)
11186 - fprintf(file, "|\t");
11187 - fprintf(file, "\n");
11189 - /* Go to the right level and print the statement number. */
11190 - for (j = 0; j <= level; j++)
11191 - fprintf(file, "|\t");
11192 - fprintf(file, "Statement number: %d\n", program->nb_statements);
11194 - /* A blank line. */
11195 - for (j = 0; j <= level+1; j++)
11196 - fprintf(file, "|\t");
11197 - fprintf(file, "\n");
11199 - /* Print the statements. */
11200 - for (i = 0; i < program->nb_statements; ++i)
11201 - candl_statement_print_structure(file, program->statement[i], level+1);
11203 - /* Print the transformation candidate. */
11204 - if (program->transformation != NULL)
11205 - for (i = 0; i < program->nb_statements; i++)
11206 - candl_matrix_print_structure(file, program->transformation[i], level+1);
11209 - /* Go to the right level. */
11210 - for (j = 0; j <= level; j++)
11211 - fprintf(file, "|\t");
11212 - fprintf(file, "+-- No transformation candidate\n");
11214 - /* A blank line. */
11215 - for (j = 0; j <= level+1; j++)
11216 - fprintf(file, "|\t");
11217 - fprintf(file, "\n");
11222 - /* Go to the right level. */
11223 - for (j = 0; j < level; j++)
11224 - fprintf(file, "|\t");
11225 - fprintf(file, "+-- NULL candl_program_t\n");
11228 - /* The last line. */
11229 - for (j = 0; j <= level; j++)
11230 - fprintf(file, "|\t");
11231 - fprintf(file, "\n");
11236 - * candl_program_print function:
11237 - * This function prints the content of a candl_program_t structure
11238 - * (program) into a file (file, possibly stdout).
11240 -void candl_program_print(FILE * file, candl_program_p program)
11242 - candl_program_print_structure(file, program,0);
11248 - * candl_program_print function:
11249 - * This function prints a candl_program_t structure (program) into a
11250 - * candl-formatted file (file, possibly stdout).
11252 -void candl_program_print_candl_file(FILE * file, candl_program_p program)
11256 - fprintf (file, "# -------------------\n");
11257 - fprintf (file, "# Context\n");
11258 - candl_matrix_print_data(file, program->context);
11259 - fprintf (file, "\n");
11260 - fprintf (file, "# Number of statements\n");
11261 - fprintf (file, "%d\n", program->nb_statements);
11262 - for (i = 0; i < program->nb_statements; ++i)
11264 - fprintf (file, "# -------------------\n");
11265 - fprintf (file, "# Statement %d\n", i + 1);
11266 - fprintf (file, "# Statement type\n");
11267 - /* All types set to Assignment. */
11268 - fprintf (file, "A\n");
11269 - fprintf (file, "\n");
11270 - fprintf (file, "# Iteration domain\n");
11271 - candl_matrix_print_data(file, program->statement[i]->domain);
11272 - fprintf (file, "\n");
11273 - fprintf (file, "# Loop labels\n");
11274 - for (j = 0; j < program->statement[i]->depth; ++j)
11275 - fprintf (file, "%d ", program->statement[i]->index[j]);
11276 - fprintf (file, "\n");
11277 - fprintf (file, "# Written items\n");
11278 - candl_matrix_print_data(file, program->statement[i]->written);
11279 - fprintf (file, "\n");
11280 - fprintf (file, "# Read items\n");
11281 - candl_matrix_print_data(file, program->statement[i]->read);
11282 - fprintf (file, "\n");
11284 - fprintf (file, "# -------------------\n");
11285 - fprintf (file, "# Transformation candidate\n");
11286 - fprintf (file, "0\n");
11290 -/******************************************************************************
11291 - * Memory alloc/dealloc function *
11292 - ******************************************************************************/
11296 - * candl_program_malloc function:
11297 - * This function allocates the memory space for a candl_program_t structure and
11298 - * sets its fields with default values. Then it returns a pointer to the
11299 - * allocated space.
11300 - * - 09/12/2005: first version.
11302 -candl_program_p candl_program_malloc()
11304 - candl_program_p program;
11306 - /* Memory allocation for the candl_program_t structure. */
11307 - program = (candl_program_p)malloc(sizeof(candl_program_t));
11308 - if (program == NULL)
11309 - CANDL_FAIL("Error: memory overflow");
11311 - /* We set the various fields with default values. */
11312 - program->context = NULL;
11313 - program->nb_statements = 0;
11314 - program->statement = NULL;
11315 - program->transformation = NULL;
11316 - program->scalars_privatizable = NULL;
11323 - * candl_program_free function:
11324 - * This function frees the allocated memory for a candl_program_t structure, it
11325 - * recursively frees everything inside.
11327 -void candl_program_free(candl_program_p program)
11331 - candl_matrix_free(program->context);
11333 - if (program->statement != NULL)
11335 - for (i = 0; i < program->nb_statements; i++)
11336 - candl_statement_free(program->statement[i]);
11337 - free(program->statement);
11340 - if (program->transformation != NULL)
11342 - for (i = 0; i < program->nb_statements; i++)
11343 - candl_matrix_free(program->transformation[i]);
11344 - free(program->transformation);
11347 - if (program->scalars_privatizable != NULL)
11348 - free(program->scalars_privatizable);
11354 -/******************************************************************************
11355 - * Reading function *
11356 - ******************************************************************************/
11360 - * candl_program_read function:
11361 - * This function reads the informations to put in a candl_program_t
11362 - * structure from a file (file, possibly stdin). It returns a pointer
11363 - * to a candl_program_t structure containing the read informations.
11364 - * September 10th 2003: first version.
11366 -candl_program_p candl_program_read(FILE * file)
11368 - int i, nb_statements, nb_parameters, nb_functions;
11369 - char s[CANDL_MAX_STRING];
11370 - CandlStatement ** statement;
11371 - CandlMatrix ** transformation;
11372 - candl_program_p program;
11374 - /* Memory allocation for the candl_program_t structure. */
11375 - program = candl_program_malloc();
11377 - /* First of all, we read the context data. */
11378 - program->context = candl_matrix_read(file);
11379 - nb_parameters = program->context->NbColumns - 2;
11381 - /* We read the number of statements. */
11382 - while (fgets(s, CANDL_MAX_STRING, file) == 0)
11384 - while ((*s=='#'||*s=='\n') || (sscanf(s, " %d", &nb_statements) < 1))
11385 - fgets(s, CANDL_MAX_STRING, file);
11387 - program->nb_statements = nb_statements;
11389 - /* Reading of each statement. */
11390 - if (nb_statements > 0)
11392 - /* Memory allocation for the array of pointers to the statements. */
11393 - statement = (CandlStatement**) malloc(nb_statements *
11394 - sizeof(CandlStatement*));
11395 - if (statement == NULL)
11396 - CANDL_FAIL("Error: memory overflow");
11398 - for (i = 0; i < nb_statements; i++)
11399 - statement[i] = candl_statement_read(file, i, nb_parameters);
11401 - program->statement = statement;
11404 - /* We read the number of transformation functions. */
11405 - while (fgets(s, CANDL_MAX_STRING, file) == 0)
11407 - while ((*s=='#' || *s=='\n') || (sscanf(s, " %d", &nb_functions) < 1))
11408 - fgets(s, CANDL_MAX_STRING, file);
11410 - /* Reading of each transformation function. */
11411 - if (nb_functions > 0)
11413 - /* The function number must be the same as statement number. */
11414 - if (nb_functions != nb_statements)
11417 - "[Candl]ERROR: the numbers of transformations (%d) and "
11418 - "statements (%d) differ.\n", nb_functions, nb_statements);
11422 - /* Memory allocation for the array of pointers to the functions. */
11423 - transformation = (CandlMatrix **)malloc(nb_functions *
11424 - sizeof(CandlMatrix *));
11425 - if (transformation == NULL)
11426 - CANDL_FAIL("Error: memory overflow");
11428 - for (i = 0; i < nb_functions; i++)
11429 - transformation[i] = candl_matrix_read(file);
11431 - program->transformation = transformation;
11439 - * This function reads the .scop formatted file 'file', check for the
11440 - * existence of the <candl> tag in the file, and retrieve the loop
11441 - * index information, if any.
11442 - * This function is built only if candl was configured with ScopLib support.
11445 -#ifdef CANDL_SUPPORTS_SCOPLIB
11447 -int** candl_program_scop_get_opt_indices(scoplib_scop_p scop)
11449 - /* Get the <candl></candl> tag content. */
11450 - char* candl_opts = scoplib_scop_tag_content(scop, "<candl>", "</candl>");
11451 - if (! candl_opts)
11453 - /* Get the <candl><indices></indices></candl> tag content. */
11454 - char* indices = scoplib_scop_tag_content_from_string(candl_opts, "<indices>",
11456 - free (candl_opts);
11460 - /* Tag was found. Scan it. */
11461 - int buffer_size = 128;
11462 - /* Assume maximum loop nest depth of 128. */
11465 - int** res = malloc(buffer_size * sizeof(int*));
11467 - int count, idx = 0;
11468 - int line_added = 0;
11469 - char* s = indices;
11471 - while (s && *s != '\0')
11473 - for (i = 0; i < 128; ++i)
11475 - while (*s != '\0' && *s != '\n' && isspace(*s))
11477 - if (*s != '\0' && *s != '#' && *s != '\n')
11479 - for (count = 0; *s >= '0' && *s <= '9'; ++count)
11480 - buff[count] = *(s++);
11481 - buff[count] = '\0';
11482 - line[i] = atoi(buff);
11490 - if (idx == buffer_size)
11491 - res = realloc(res, (buffer_size *= 2) * sizeof(int*));
11492 - res[idx] = (int*) malloc(i * sizeof(int));
11493 - for (j = 0; j < i; ++j)
11494 - res[idx][j] = line[j];
11498 - while (s && *s != '\0' && *s != '\n')
11500 - if (s && *s != '\0' && *s == '\n')
11503 - res = realloc(res, idx * sizeof(int*));
11512 - * candl_program_read_scop function:
11513 - * This function reads the informations to put in a candl_program_t
11514 - * structure from a file (file, possibly stdin) following the .scop
11515 - * format. It returns a pointer to a candl_program_t structure
11516 - * containing the read informations.
11517 - * This function is built only if candl was configured with ScopLib support.
11520 -#ifdef CANDL_SUPPORTS_SCOPLIB
11521 -candl_program_p candl_program_read_scop(FILE * file)
11525 - /* Read the scop. */
11526 - scoplib_scop_p scop = scoplib_scop_read(file);
11527 - /* Check for the <candl> tag in the options of the .scop file. */
11528 - int** indices = candl_program_scop_get_opt_indices(scop);
11529 - /* Convert the scop. */
11530 - candl_program_p res = candl_program_convert_scop(scop, indices);
11532 - /* Clean temporary data. */
11535 - for (i = 0; i < res->nb_statements; ++i)
11536 - free(indices[i]);
11539 - scoplib_scop_free(scop);
11546 -/******************************************************************************
11547 - * Processing functions *
11548 - ******************************************************************************/
11552 - * candl_program_convert_scop function:
11553 - * This function extracts the useful information of a scoplib_scop_t
11554 - * structure to a fresh, independent candl_program_t structure.
11555 - * This function is built only if candl was configured with ScopLib support.
11558 -#ifdef CANDL_SUPPORTS_SCOPLIB
11559 -candl_program_p candl_program_convert_scop(scoplib_scop_p scop, int** indices)
11562 - candl_program_p res = candl_program_malloc();
11563 - scoplib_statement_p s = scop->statement;
11565 - /* Duplicate the context. */
11566 - res->context = (CandlMatrix*) scoplib_matrix_copy(scop->context);
11567 - if (res->context == NULL)
11568 - res->context = candl_matrix_malloc(0, 2);
11570 - /* Count the number of statements. */
11571 - for (res->nb_statements = 0; s; s = s->next, res->nb_statements++)
11574 - /* Allocate the statements array. */
11575 - res->statement = (CandlStatement**) malloc(res->nb_statements *
11576 - sizeof(CandlStatement*));
11578 - /* Initialize structures used in iterator indices computation. */
11580 - int max_loop_depth = 128;
11581 - int cur_index[max_loop_depth];
11582 - int last[max_loop_depth];
11583 - for (i = 0; i < max_loop_depth; ++i)
11585 - cur_index[i] = i;
11588 - /* Create the statements. */
11589 - for (i = 0, s = scop->statement; s; s = s->next, ++i)
11591 - CandlStatement* statement = candl_statement_malloc();
11592 - statement->label = i;
11593 - statement->ref = s;
11594 - if (s->domain->next != NULL)
11595 - CANDL_FAIL("Error: union of domains not supported");
11597 - statement->domain = (CandlMatrix*) scoplib_matrix_copy(s->domain->elt);
11598 - /* For the moment, we do not parse the statement to extract its type. */
11599 - statement->type = CANDL_ASSIGNMENT;
11600 - statement->depth = statement->domain->NbColumns - 2 - scop->nb_parameters;
11601 - statement->written = (CandlMatrix*) scoplib_matrix_copy(s->write);
11602 - if (statement->written == NULL)
11603 - statement->written =
11604 - candl_matrix_malloc(0, statement->domain->NbColumns);
11605 - statement->read = (CandlMatrix*) scoplib_matrix_copy(s->read);
11606 - if (statement->read == NULL)
11607 - statement->read = candl_matrix_malloc(0, statement->domain->NbColumns);
11608 - statement->index = (int*) malloc(statement->depth * sizeof(int));
11609 - if (indices != NULL)
11610 - /* Iterator indices are provided. */
11611 - for (j = 0; j < statement->depth; ++j)
11612 - statement->index[j] = indices[i][j];
11615 - /* Iterator indices must be computed from the scattering matrix. */
11616 - scoplib_matrix_p m = s->schedule;
11618 - CANDL_FAIL("Error: No scheduling matrix and no loop "
11619 - "indices specification");
11621 - /* FIXME: Sort the statements in their execution order. */
11622 - /* It must be a 2d+1 identity scheduling matrix, and
11623 - statements must be sorted in their execution order. */
11624 - /* Check that it is a identity matrix. */
11626 - if (m->NbRows != 2 * statement->depth + 1)
11629 - for (l = 0; l < m->NbRows; ++l)
11631 - for (k = 1; k < m->NbColumns - 1; ++k)
11632 - switch (CANDL_get_si(m->p[l][k]))
11635 - if (l % 2 && k == (l / 2) + 1) error = 1;
11638 - if ((l % 2 && k != (l / 2) + 1) || (! l % 2)) error = 1;
11644 - if (l % 2 && CANDL_get_si(m->p[l][k]))
11648 - CANDL_FAIL("Error: schedule is not identity 2d+1 shaped.\n"
11649 - "Consider using the <indices> option tag to declare "
11650 - " iterator indices");
11652 - /* Compute the value of the iterator indices. */
11653 - for (j = 0; j < statement->depth; ++j)
11655 - int val = CANDL_get_si(m->p[2 * j][m->NbColumns - 1]);
11656 - if (last[j] < val)
11659 - for (k = j + 1; k < max_loop_depth; ++k)
11661 - for (k = j; k < max_loop_depth; ++k)
11662 - cur_index[k] = max + (k - j) + 1;
11666 - for (j = 0; j < statement->depth; ++j)
11667 - statement->index[j] = cur_index[j];
11668 - max = max < cur_index[j - 1] ? cur_index[j - 1] : max;
11670 - /* Store the statement. */
11671 - res->statement[i] = statement;
11677 diff --git a/source/pruning.c b/source/pruning.c
11678 index 2b0cf49..db4a90f 100644
11679 --- a/source/pruning.c
11680 +++ b/source/pruning.c
11682 **---- \#/ --------------------------------------------------------**
11683 ** .-"#'-. First version: July 17th 2011 **
11684 **--- |"-.-"| -------------------------------------------------------**
11689 ******** | | *************************************************************
11690 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
11691 ******************************************************************************
11692 @@ -40,35 +40,15 @@
11693 #include <stdlib.h>
11695 #include <string.h>
11696 -#include <candl/candl.h>
11698 #include <assert.h>
11699 +#include <osl/statement.h>
11700 +#include <osl/relation.h>
11701 +#include <candl/statement.h>
11702 +#include <candl/dependence.h>
11706 - * Return true if the 2 matrices are strictly identical.
11709 -int candl_matrix_equal(CandlMatrix* m1, CandlMatrix* m2)
11712 +#if defined(CANDL_COMPILE_PRUNNING_C)
11721 - if (m1->NbRows != m2->NbRows || m1->NbColumns != m2->NbColumns)
11724 - for (i = 0; i < m1->NbRows; ++i)
11725 - for (j = 0; j < m1->NbColumns; ++j)
11726 - if (! CANDL_eq(m1->p[i][j], m2->p[i][j]))
11731 #define BUFF_SIZE 1024
11733 @@ -79,79 +59,69 @@ int candl_matrix_equal(CandlMatrix* m1, CandlMatrix* m2)
11734 * Paths are stored as list of lists of dependences in 'paths_list'.
11737 -void find_paths_rec (int tgt_id, int cur_length, int max_length,
11739 - CandlDependence** alldeps,
11740 - CandlDependence** cur_path,
11741 - CandlDependence**** paths_list)
11743 +void find_paths_rec(int tgt_id, int cur_length, int max_length,
11745 + osl_dependence_p* alldeps,
11746 + osl_dependence_p* cur_path,
11747 + osl_dependence_p*** paths_list) {
11750 - for (i = 0; alldeps[i]; ++i)
11752 - if (alldeps[i]->usr == NULL)
11754 - if (alldeps[i]->source->label == tgt_id)
11756 - // Ensure the path flow is consistent.
11757 - if (cur_length > 1)
11759 - if (cur_path[cur_length - 1]->type == CANDL_RAW ||
11760 - cur_path[cur_length - 1]->type == CANDL_RAW_SCALPRIV ||
11761 - cur_path[cur_length - 1]->type == CANDL_RAR)
11764 - if (alldeps[i]->type != CANDL_RAR &&
11765 - alldeps[i]->type != CANDL_WAR)
11771 - if (alldeps[i]->type != CANDL_WAW &&
11772 - alldeps[i]->type != CANDL_RAW)
11776 - if (cur_length + 1 == max_length)
11778 - if (alldeps[i]->target->label == final_id)
11782 - for (pos = 0; (*paths_list)[pos]; ++pos)
11784 - if (pos + 1 % BUFF_SIZE == 0)
11786 - *paths_list = (CandlDependence***)
11787 - realloc(*paths_list, sizeof(CandlDependence**) *
11788 - (BUFF_SIZE + pos + 1));
11789 - *paths_list[pos + 1] = NULL;
11791 - (*paths_list)[pos] = (CandlDependence**)
11792 - malloc((max_length + 1) * sizeof(CandlDependence*));
11793 - for (j = 0; j < max_length - 1; ++j)
11794 - (*paths_list)[pos][j] = cur_path[j];
11795 - (*paths_list)[pos][j++] = alldeps[i];
11796 - (*paths_list)[pos][j] = NULL;
11801 - // Store the current node in the path.
11802 - cur_path[cur_length] = alldeps[i];
11803 - // Mark the dependence as processed.
11804 - alldeps[i]->usr = alldeps[i];
11805 - // Look for the next node.
11806 - find_paths_rec (alldeps[i]->target->label, cur_length + 1,
11807 - max_length, final_id, alldeps, cur_path,
11809 - // Reset the dependence.
11810 - alldeps[i]->usr = NULL;
11814 + for (i = 0; alldeps[i]; ++i) {
11815 + if (alldeps[i]->usr == NULL) {
11816 + ((candl_statement_usr_p)target->usr)->label
11817 + if (alldeps[i]->((candl_statement_usr_p)source->usr)->label == tgt_id) {
11818 + // Ensure the path flow is consistent.
11819 + if (cur_length > 1) {
11820 + if (cur_path[cur_length - 1]->type == CANDL_RAW ||
11821 + cur_path[cur_length - 1]->type == CANDL_RAW_SCALPRIV ||
11822 + cur_path[cur_length - 1]->type == CANDL_RAR) {
11824 + if (alldeps[i]->type != CANDL_RAR &&
11825 + alldeps[i]->type != CANDL_WAR)
11830 + if (alldeps[i]->type != CANDL_WAW &&
11831 + alldeps[i]->type != CANDL_RAW)
11835 + if (cur_length + 1 == max_length) {
11836 + if (alldeps[i]->((candl_statement_usr_p)target->usr)->label == final_id) {
11839 + for (pos = 0; (*paths_list)[pos]; ++pos)
11841 + if (pos + 1 % BUFF_SIZE == 0) {
11842 + *paths_list = (osl_dependence_p**)
11843 + realloc(*paths_list, sizeof(osl_dependence_p*) *
11844 + (BUFF_SIZE + pos + 1));
11845 + *paths_list[pos + 1] = NULL;
11847 + (*paths_list)[pos] = (osl_dependence_p*)
11848 + malloc((max_length + 1) * sizeof(osl_dependence_p));
11849 + for (j = 0; j < max_length - 1; ++j)
11850 + (*paths_list)[pos][j] = cur_path[j];
11851 + (*paths_list)[pos][j++] = alldeps[i];
11852 + (*paths_list)[pos][j] = NULL;
11856 + // Store the current node in the path.
11857 + cur_path[cur_length] = alldeps[i];
11858 + // Mark the dependence as processed.
11859 + alldeps[i]->usr = alldeps[i];
11860 + // Look for the next node.
11861 + find_paths_rec(alldeps[i]->((candl_statement_usr_p)target->usr)->label,
11862 + cur_length + 1, max_length, final_id, alldeps,
11863 + cur_path, paths_list);
11864 + // Reset the dependence.
11865 + alldeps[i]->usr = NULL;
11873 @@ -162,91 +132,55 @@ void find_paths_rec (int tgt_id, int cur_length, int max_length,
11877 -CandlDependence***
11878 -find_dep_paths (CandlDependence** ardeps,
11879 - CandlStatement* source,
11880 - CandlStatement*target)
11882 +osl_dependence_p** find_dep_paths(osl_dependence_p* ardeps,
11883 + osl_statement_p source,
11884 + osl_statement_p target) {
11886 for (nb_dep = 0; ardeps[nb_dep]; ++nb_dep)
11890 - CandlDependence* cur_path[nb_dep + 1];
11891 - CandlDependence*** paths_list =
11892 - (CandlDependence***)malloc(BUFF_SIZE * sizeof(CandlDependence**));
11893 + osl_dependence_p *cur_path =
11894 + (osl_dependence_p*) malloc(sizeof(osl_dependence_p) *
11896 + osl_dependence_p** paths_list =
11897 + (osl_dependence_p**)malloc(BUFF_SIZE * sizeof(osl_dependence_p*));
11898 for (i = 0; i < BUFF_SIZE; ++i)
11899 paths_list[i] = NULL;
11900 // Iterate on all possible paths length, from Sx to Sy, of length y-x.
11901 - for (i = 2; i <= target->label - source->label; ++i)
11902 - find_paths_rec (source->label, 0, i, target->label, ardeps, cur_path,
11905 + for (i = 2; i <= ((candl_statement_usr_p)target->usr)->label -
11906 + ((candl_statement_usr_p)source->usr)->label; ++i)
11907 + find_paths_rec(((candl_statement_usr_p)source->usr)->label, 0, i,
11908 + ((candl_statement_usr_p)target->usr)->label, ardeps,
11909 + cur_path, &paths_list);
11915 - * Return true if the 'size' first elements of 'l1' and 'l2' are equal.
11918 -int piplist_are_equal (PipList* l1, PipList* l2, int size)
11920 - if (l1 == NULL && l2 == NULL)
11922 - if (l1 == NULL || l2 == NULL)
11924 - if (l1->vector == NULL && l2->vector == NULL)
11926 - if (l1->vector == NULL || l2->vector == NULL)
11930 - for (; l1 && l2 && count < size; l1 = l1->next, l2 = l2->next, ++count)
11932 - if (l1->vector == NULL && l2->vector == NULL)
11934 - if (l1->vector == NULL || l2->vector == NULL)
11936 - if (l1->vector->nb_elements != l2->vector->nb_elements)
11939 - for (j = 0; j < l1->vector->nb_elements; ++j)
11940 - if (! CANDL_eq(l1->vector->the_vector[j],
11941 - l2->vector->the_vector[j]) ||
11942 - ! CANDL_eq(l1->vector->the_deno[j],
11943 - l2->vector->the_deno[j]))
11951 * Return true if the 'size' first variables in a quast are strictly
11956 -quast_are_equal (PipQuast* q1, PipQuast* q2, int size)
11958 +int quast_are_equal (PipQuast* q1, PipQuast* q2, int size) {
11959 if (q1 == NULL && q2 == NULL)
11961 if (q1 == NULL || q2 == NULL)
11964 // Inspect conditions.
11965 - if (q1->condition != NULL && q2->condition != NULL)
11967 - PipList c1; c1.next = NULL; c1.vector = q1->condition;
11968 - PipList c2; c2.next = NULL; c2.vector = q2->condition;
11969 - if (! piplist_are_equal(&c1, &c2, size))
11971 - return quast_are_equal (q1->next_then, q2->next_then, size) &&
11972 - quast_are_equal (q1->next_else, q2->next_else, size);
11974 + if (q1->condition != NULL && q2->condition != NULL) {
11975 + PipList c1; c1.next = NULL; c1.vector = q1->condition;
11976 + PipList c2; c2.next = NULL; c2.vector = q2->condition;
11977 + if (! piplist_are_equal(&c1, &c2, size))
11979 + return quast_are_equal(q1->next_then, q2->next_then, size) &&
11980 + quast_are_equal(q1->next_else, q2->next_else, size);
11982 if (q1->condition != NULL || q2->condition != NULL)
11984 - return piplist_are_equal (q1->list, q2->list, size);
11985 + return piplist_are_equal(q1->list, q2->list, size);
11989 @@ -256,9 +190,7 @@ quast_are_equal (PipQuast* q1, PipQuast* q2, int size)
11990 * corresponding to loop iterators).
11994 -is_covering (CandlDependence* dep, CandlDependence** path)
11996 +int is_covering(osl_dependence_p dep, osl_dependence_p* path) {
11997 int i, path_length;
11999 for (path_length = 0; path[path_length]; ++path_length)
12000 @@ -267,170 +199,154 @@ is_covering (CandlDependence* dep, CandlDependence** path)
12001 /// FIXME: This may be overly conservative.
12002 // Check the path extremal points type.
12003 if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV
12004 - || dep->type == CANDL_WAW)
12007 - if (path[0]->type != CANDL_RAW && path[0]->type != CANDL_RAW_SCALPRIV &&
12008 - path[0]->type != CANDL_WAW)
12010 - if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV)
12011 - if (path[path_length - 1]->type != CANDL_RAW &&
12012 - path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
12013 - path[path_length - 1]->type != CANDL_RAR)
12015 - if (dep->type == CANDL_WAW)
12016 - if (path[path_length - 1]->type != CANDL_WAR &&
12017 - path[path_length - 1]->type != CANDL_WAW)
12023 - if (path[0]->type != CANDL_WAR && path[0]->type != CANDL_RAR)
12025 - if (dep->type == CANDL_WAR)
12026 - if (path[path_length - 1]->type != CANDL_WAW &&
12027 - path[path_length - 1]->type != CANDL_WAR)
12029 - if (dep->type == CANDL_RAR)
12030 - if (path[path_length - 1]->type != CANDL_RAR &&
12031 - path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
12032 - path[path_length - 1]->type != CANDL_RAW)
12035 + || dep->type == CANDL_WAW) {
12037 + if (path[0]->type != CANDL_RAW && path[0]->type != CANDL_RAW_SCALPRIV &&
12038 + path[0]->type != CANDL_WAW)
12040 + if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV)
12041 + if (path[path_length - 1]->type != CANDL_RAW &&
12042 + path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
12043 + path[path_length - 1]->type != CANDL_RAR)
12045 + if (dep->type == CANDL_WAW)
12046 + if (path[path_length - 1]->type != CANDL_WAR &&
12047 + path[path_length - 1]->type != CANDL_WAW)
12052 + if (path[0]->type != CANDL_WAR && path[0]->type != CANDL_RAR)
12054 + if (dep->type == CANDL_WAR)
12055 + if (path[path_length - 1]->type != CANDL_WAW &&
12056 + path[path_length - 1]->type != CANDL_WAR)
12058 + if (dep->type == CANDL_RAR)
12059 + if (path[path_length - 1]->type != CANDL_RAR &&
12060 + path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
12061 + path[path_length - 1]->type != CANDL_RAW)
12065 // a- Fast check. Ensure the dependence depth is consistent across
12066 // the path. We may correctly cover _more_ points and still have a
12067 // perfect transitive cover.
12068 /// FIXME: ambiguous test?
12069 -/* for (i = 0; i < path_length; ++i) */
12070 -/* if (path[i]->depth > dep->depth) */
12072 + /* for (i = 0; i < path_length; ++i) */
12073 + /* if (path[i]->depth > dep->depth) */
12076 // b- Check the covering property. Works only if
12077 // the iterator part of iteration domains and access functions are
12078 // unimodular matrices.
12079 // Build a large system with all dependences.
12080 - int nb_par = path[0]->source->domain->NbColumns - path[0]->source->depth - 2;
12081 + int nb_par = path[0]->domain->nb_parameters;
12084 - for (i = 0; i < path_length; ++i)
12086 - nb_iters += path[i]->domain->NbColumns - nb_par - 2;
12087 - nb_rows += path[i]->domain->NbRows;
12089 - nb_iters -= path[i]->source->depth;
12091 - CandlMatrix* syst = candl_matrix_malloc (nb_rows, nb_iters + nb_par + 2);
12092 + for (i = 0; i < path_length; ++i) {
12093 + nb_iters += path[i]->source_nb_output_dims_domain +
12094 + path[i]->target_nb_output_dims_domain;
12095 + nb_rows += path[i]->domain->nb_rows;
12097 + nb_iters -= ((candl_statement_usr_p) path[i]->source->usr)->depth;
12100 + CandlMatrix* syst = candl_matrix_malloc(nb_rows, nb_iters + nb_par + 2);
12104 - for (k = 0; k < path_length; ++k)
12106 - for (i = 0; i < path[k]->domain->NbRows; ++i)
12108 - CANDL_assign(syst->p[pos][0], path[k]->domain->p[i][0]);
12109 - for (j = 1; j < path[k]->domain->NbColumns - 1 - nb_par; ++j)
12110 - CANDL_assign(syst->p[pos][j + iter_off], path[k]->domain->p[i][j]);
12111 - for (; j < path[k]->domain->NbColumns; ++j)
12113 - int parpos = j - (path[k]->domain->NbColumns - 1 - nb_par) +
12114 - syst->NbColumns - nb_par - 1;
12115 - CANDL_assign(syst->p[pos][parpos], path[k]->domain->p[i][j]);
12119 - iter_off += path[k]->source->depth;
12120 + for (k = 0; k < path_length; ++k) {
12121 + for (i = 0; i < path[k]->domain->NbRows; ++i) {
12122 + CANDL_assign(syst->p[pos][0], path[k]->domain->p[i][0]);
12123 + for (j = 1; j < path[k]->domain->NbColumns - 1 - nb_par; ++j)
12124 + CANDL_assign(syst->p[pos][j + iter_off], path[k]->domain->p[i][j]);
12125 + for (; j < path[k]->domain->NbColumns; ++j) {
12126 + int parpos = j - (path[k]->domain->NbColumns - 1 - nb_par) +
12127 + syst->NbColumns - nb_par - 1;
12128 + CANDL_assign(syst->p[pos][parpos], path[k]->domain->p[i][j]);
12132 + iter_off += path[k]->source->depth;
12136 // lexmin(dep, R) == lexmin(path, R) && lexmax(dep, R) == lexmax(path, R) &&
12137 // lexmin(dep, S) == lexmin(path, S) && lexmax(dep, S) == lexmax(path, S)
12138 PipOptions* options;
12139 - options = pip_options_init ();
12140 + options = pip_options_init();
12141 options->Simplify = 1;
12142 options->Urs_parms = -1;
12143 options->Urs_unknowns = -1;
12144 - CandlMatrix* context = candl_matrix_malloc (0, nb_par + 2);
12145 - PipQuast* qpath = pip_solve (syst, context, -1, options);
12146 - PipQuast* qdep = pip_solve (dep->domain, context, -1, options);
12147 - int are_equal = quast_are_equal (qpath, qdep, dep->source->depth);
12150 - pip_quast_free (qpath);
12151 - pip_quast_free (qdep);
12152 - options->Maximize = 1;
12153 - qpath = pip_solve (syst, context, -1, options);
12154 - qdep = pip_solve (dep->domain, context, -1, options);
12155 - are_equal = quast_are_equal (qpath, qdep, dep->source->depth);
12156 + CandlMatrix* context = candl_matrix_malloc(0, nb_par + 2);
12157 + PipQuast* qpath = pip_solve(syst, context, -1, options);
12158 + PipQuast* qdep = pip_solve(dep->domain, context, -1, options);
12159 + int are_equal = quast_are_equal(qpath, qdep, dep->source->depth);
12161 + pip_quast_free (qpath);
12162 + pip_quast_free (qdep);
12163 + options->Maximize = 1;
12164 + qpath = pip_solve(syst, context, -1, options);
12165 + qdep = pip_solve(dep->domain, context, -1, options);
12166 + are_equal = quast_are_equal(qpath, qdep, dep->source->depth);
12169 + pip_quast_free(qpath);
12170 + pip_quast_free(qdep);
12171 + options->Maximize = 0;
12172 + // Permute columns for first and last iterators.
12173 + for (i = 0; i < dep->target->depth; ++i) {
12174 + for (j = 0; j < syst->NbRows; ++j) {
12175 + int tmp = CANDL_get_si(syst->p[j][1]);
12176 + int pos = syst->NbColumns - 1 - nb_par - dep->target->depth + i;
12177 + CANDL_assign(syst->p[j][1], syst->p[j][pos]);
12178 + CANDL_set_si(syst->p[j][pos], tmp);
12183 - pip_quast_free (qpath);
12184 - pip_quast_free (qdep);
12185 - options->Maximize = 0;
12186 - // Permute columns for first and last iterators.
12187 - for (i = 0; i < dep->target->depth; ++i)
12189 - for (j = 0; j < syst->NbRows; ++j)
12191 - int tmp = CANDL_get_si(syst->p[j][1]);
12192 - int pos = syst->NbColumns - 1 - nb_par - dep->target->depth + i;
12193 - CANDL_assign(syst->p[j][1], syst->p[j][pos]);
12194 - CANDL_set_si(syst->p[j][pos], tmp);
12197 - qpath = pip_solve (syst, context, -1, options);
12198 - qdep = pip_solve (dep->domain, context, -1, options);
12199 - are_equal = quast_are_equal (qpath, qdep, dep->target->depth);
12203 - pip_quast_free (qpath);
12204 - pip_quast_free (qdep);
12205 - options->Maximize = 1;
12206 - qpath = pip_solve (syst, context, -1, options);
12207 - qdep = pip_solve (dep->domain, context, -1, options);
12208 - are_equal = quast_are_equal (qpath, qdep, dep->target->depth);
12211 - pip_options_free (options);
12212 - pip_quast_free (qpath);
12213 - pip_quast_free (qdep);
12214 - pip_matrix_free (syst);
12215 + qpath = pip_solve(syst, context, -1, options);
12216 + qdep = pip_solve(dep->domain, context, -1, options);
12217 + are_equal = quast_are_equal(qpath, qdep, dep->target->depth);
12220 + pip_quast_free(qpath);
12221 + pip_quast_free(qdep);
12222 + options->Maximize = 1;
12223 + qpath = pip_solve(syst, context, -1, options);
12224 + qdep = pip_solve(dep->domain, context, -1, options);
12225 + are_equal = quast_are_equal(qpath, qdep, dep->target->depth);
12228 + pip_options_free(options);
12229 + pip_quast_free(qpath);
12230 + pip_quast_free(qdep);
12231 + pip_matrix_free(syst);
12238 -is_iter_unimodular (CandlDependence* dep)
12240 +int is_iter_unimodular(osl_dependence_p dep) {
12241 // Check unimodular on the iterator part.
12243 - for (i = 0; i < dep->domain->NbRows; ++i)
12245 - if (i < dep->source->domain->NbRows ||
12246 - i > dep->source->domain->NbRows + dep->target->domain->NbRows)
12248 - for (j = 1; j <= dep->source->depth; ++j)
12250 - int val = CANDL_get_si(dep->domain->p[i][j]);
12251 - if (val < -1 || val > 1)
12255 - else if (i < dep->source->domain->NbRows +
12256 - dep->target->domain->NbRows ||
12257 - i > dep->source->domain->NbRows + dep->target->domain->NbRows)
12259 - for (j = 1; j <= dep->source->depth; ++j)
12261 - int val = CANDL_get_si(dep->domain->p[i][j + dep->source->depth]);
12262 - if (val < -1 || val > 1)
12267 + int precision = dep->domain->precision;
12268 + osl_relation_p matrix;
12270 + matrix = dep->source->domain;
12271 + for (i = 0 ; i < matrix->nb_rows ; i++)
12272 + for (j = 1 ; j <= matrix->nb_output_dims ; j++) {
12273 + n = osl_int_get_si(precision, matrix->m[i][j]);
12274 + if (n < -1 || n > 1)
12278 + matrix = dep->target->domain;
12279 + for (i = 0 ; i < matrix->nb_rows ; i++)
12280 + for (j = 1 ; j <= matrix->nb_output_dims ; j++) {
12281 + n = osl_int_get_si(precision, matrix->m[i][j]);
12282 + if (n < -1 || n > 1)
12287 @@ -441,157 +357,169 @@ is_iter_unimodular (CandlDependence* dep)
12288 * In-place modification of the list of dependence polyhedra.
12292 -candl_dependence_prune_transitively_covered (CandlDependence* deps)
12294 - CandlDependence* tmp;
12295 +osl_dependence_p osl_dependence_prune_transitively_covered(
12296 + osl_dependence_p deps) {
12297 + if (deps == NULL)
12300 + osl_dependence_p tmp;
12301 + osl_dependence_p *ardeps;
12302 + osl_relation_p srcmat;
12303 + osl_relation_p *allarrays;
12304 + osl_dependence_p** path;
12305 + osl_dependence_p *curardeps;
12306 + candl_statement_usr_p s_usr, t_usr;
12307 + int precision = deps->domain->precision;
12310 // 1- Collect all arrays that occur in dependences.
12311 int cnt, i, j, k, l;
12313 - for (tmp = deps, cnt = 0; tmp; tmp = tmp->next)
12315 - nb_stmts = tmp->source->label > nb_stmts ? tmp->source->label : nb_stmts;
12316 - nb_stmts = tmp->target->label > nb_stmts ? tmp->target->label : nb_stmts;
12319 + for (tmp = deps, cnt = 0; tmp; tmp = tmp->next) {
12320 + s_usr = tmp->source->usr;
12321 + t_usr = tmp->target->usr;
12322 + nb_stmts = s_usr->label > nb_stmts ? s_usr->label : nb_stmts;
12323 + nb_stmts = t_usr->label > nb_stmts ? t_usr->label : nb_stmts;
12327 - int nb_deps = cnt;
12328 - int allarrays[cnt];
12329 - for (tmp = deps, cnt = 0; tmp; tmp = tmp->next)
12331 - CandlMatrix* srcmat;
12332 - if (tmp->type == CANDL_RAW || tmp->type == CANDL_RAW_SCALPRIV
12333 - || tmp->type == CANDL_WAW)
12334 - srcmat = tmp->source->written;
12336 - srcmat = tmp->source->read;
12337 - for (i = 0; i < cnt; ++i)
12338 - if (allarrays[i] == CANDL_get_si(srcmat->p[tmp->ref_source][0]))
12341 - allarrays[cnt++] = CANDL_get_si(srcmat->p[tmp->ref_source][0]);
12343 - allarrays[cnt] = -1;
12345 + allarrays = (osl_relation_p*)malloc(sizeof(osl_relation_p)*cnt);
12347 + for (tmp = deps, cnt = 0; tmp; tmp = tmp->next) {
12348 + srcmat = candl_dependence_get_relation_ref_source_in_dep(tmp);
12349 + for (i = 0; i < cnt; ++i)
12350 + if (allarrays[i] == srcmat)
12353 + allarrays[cnt++] = srcmat;
12355 + allarrays[cnt] = NULL;
12357 // 2- Iterate on all arrays.
12358 - for (i = 0; allarrays[i] != -1; ++i)
12360 - // a- Collect all dependences to this array.
12361 - CandlDependence* ardeps[nb_deps + 1];
12362 - for (tmp = deps, cnt = 0; tmp; tmp = tmp->next)
12364 - CandlMatrix* srcmat;
12365 - if (tmp->type == CANDL_RAW || tmp->type == CANDL_RAW_SCALPRIV
12366 - || tmp->type == CANDL_WAW)
12367 - srcmat = tmp->source->written;
12369 - srcmat = tmp->source->read;
12370 - if (allarrays[i] == CANDL_get_si(srcmat->p[tmp->ref_source][0]))
12371 - ardeps[cnt++] = tmp;
12373 - ardeps[cnt] = NULL;
12375 - // b- First pruning. Remove all dependence polyhedra that are equal.
12376 - for (j = 0; ardeps[j]; ++j)
12378 - for (k = j + 1; ardeps[k]; ++k)
12379 - if (ardeps[j]->source == ardeps[k]->source &&
12380 - ardeps[j]->target == ardeps[k]->target &&
12381 - ardeps[j]->depth == ardeps[k]->depth &&
12382 - candl_matrix_equal (ardeps[j]->domain, ardeps[k]->domain))
12384 - ardeps[k - 1]->next = ardeps[k+1];
12385 - for (l = k; ardeps[l + 1]; ++l)
12386 - ardeps[l] = ardeps[l + 1];
12387 - ardeps[l] = NULL;
12392 - // c- Local pruning. Remove all self-dependences (1-cycles)
12393 - // and all backward-dependences.
12394 - for (j = 0; ardeps[j]; ++j)
12395 - if (ardeps[j]->source >= ardeps[j]->target)
12397 - for (k = j; ardeps[k + 1]; ++k)
12398 - ardeps[k] = ardeps[k + 1];
12399 - ardeps[k] = NULL;
12403 - // d- Local pruning. Remove all dependences where source/target
12404 - // are not unimodular in the iterator part of the access function and
12405 - // iteration domain.
12406 - for (j = 0; ardeps[j]; ++j)
12407 - if (! is_iter_unimodular (ardeps[j]))
12409 - for (k = j; ardeps[k + 1]; ++k)
12410 - ardeps[k] = ardeps[k + 1];
12411 - ardeps[k] = NULL;
12415 - // d- Given a pair of statements, check if there is a dependence
12416 - // path from its source to its target, of same type of a found
12417 - // direct dependence.
12418 - int stmts, stmtt;
12419 - for (stmts = 0; stmts < nb_stmts - 2; ++stmts)
12420 - for (stmtt = stmts + 2; stmtt < nb_stmts; ++stmtt)
12422 - // Ensure there exists a direct dependence between stmts
12424 - //printf ("consider S%d -> S%d\n", stmts, stmtt);
12425 - for (j = 0; ardeps[j]; ++j)
12426 - if (ardeps[j]->source->label == stmts &&
12427 - ardeps[j]->target->label == stmtt)
12431 - CandlStatement* source = ardeps[j]->source;
12432 - CandlStatement* target = ardeps[j]->target;
12434 - // Subset of deps that can be on the path.
12435 - CandlDependence* curardeps[nb_deps + 1];
12436 - for (k = 0, l = 0; ardeps[k]; ++k)
12437 - if (ardeps[k]->source->label >= source->label &&
12438 - ardeps[k]->source->label <= target->label &&
12439 - ardeps[k]->target->label >= source->label &&
12440 - ardeps[k]->target->label <= target->label)
12441 - curardeps[l++] = ardeps[k];
12442 - curardeps[l] = NULL;
12443 - CandlDependence*** paths =
12444 - find_dep_paths(curardeps, source, target);
12448 - for (j = 0; ardeps[j]; ++j)
12449 - if (ardeps[j]->source->label == stmts &&
12450 - ardeps[j]->target->label == stmtt)
12452 - // Inspect all paths. If there is a path
12453 - // that respect the transitive cover prop,
12454 - // then discard the dependence.
12455 - for (k = 0; paths[k] &&
12456 - ! is_covering (ardeps[j], paths[k]); ++k)
12460 - candl_matrix_free (ardeps[j]->domain);
12461 - free (ardeps[j]);
12463 - deps = ardeps[j + 1];
12465 - ardeps[j - 1]->next = ardeps[j + 1];
12468 - for (k = 0; paths[k]; ++k)
12474 + for (i = 0 ; allarrays[i] != NULL ; ++i) {
12475 + ardeps = (osl_dependence_p*) malloc(sizeof(osl_dependence_p) *
12478 + // a- Collect all dependences to this array.
12479 + for (tmp = deps, cnt = 0; tmp; tmp = tmp->next) {
12480 + srcmat = candl_dependence_get_relation_ref_source_in_dep(tmp);
12481 + if (allarrays[i] == srcmat)
12482 + ardeps[cnt++] = tmp;
12484 + ardeps[cnt] = NULL;
12486 + // b- First pruning. Remove all dependence polyhedra that are equal.
12487 + for (j = 0; ardeps[j]; ++j)
12488 + for (k = j + 1; ardeps[k]; ++k)
12489 + if (ardeps[j]->source == ardeps[k]->source &&
12490 + ardeps[j]->target == ardeps[k]->target &&
12491 + ardeps[j]->depth == ardeps[k]->depth &&
12492 + osl_relation_equal(ardeps[j]->domain, ardeps[k]->domain)) {
12493 + ardeps[k - 1]->next = ardeps[k+1];
12494 + for (l = k; ardeps[l + 1]; ++l)
12495 + ardeps[l] = ardeps[l + 1];
12496 + ardeps[l] = NULL;
12500 + // c- Local pruning. Remove all self-dependences (1-cycles)
12501 + // and all backward-dependences.
12502 + for (j = 0; ardeps[j]; ++j) {
12503 + s_usr = ardeps[j]->source->usr;
12504 + t_usr = ardeps[j]->target->usr;
12505 + if (s_usr->label >= t_usr->label) {
12506 + for (k = j; ardeps[k + 1]; ++k)
12507 + ardeps[k] = ardeps[k + 1];
12508 + ardeps[k] = NULL;
12513 + // d- Local pruning. Remove all dependences where source/target
12514 + // are not unimodular in the iterator part of the access function and
12515 + // iteration domain.
12516 + for (j = 0; ardeps[j]; ++j)
12517 + if (! is_iter_unimodular(ardeps[j])) {
12518 + for (k = j; ardeps[k + 1]; ++k)
12519 + ardeps[k] = ardeps[k + 1];
12520 + ardeps[k] = NULL;
12524 + // d- Given a pair of statements, check if there is a dependence
12525 + // path from its source to its target, of same type of a found
12526 + // direct dependence.
12527 + int source_label, target_label;
12528 + for (source_label = 0; source_label < nb_stmts - 2; ++source_label)
12529 + for (target_label = source_label + 2; target_label < nb_stmts;
12530 + ++target_label) {
12531 + // Ensure there exists a direct dependence between source_label
12532 + // and target_label.
12533 + //printf ("consider S%d -> S%d\n", source_label, target_label);
12534 + for (j = 0; ardeps[j]; ++j) {
12535 + s_usr = ardeps[j]->source->usr;
12536 + t_usr = ardeps[j]->target->usr;
12537 + if (s_usr->label == source_label &&
12538 + t_usr->label == target_label)
12542 + osl_statement_p source = ardeps[j]->source;
12543 + osl_statement_p target = ardeps[j]->target;
12545 + // Subset of deps that can be on the path.
12546 + curardeps = (osl_dependence_p*) malloc(sizeof(osl_dependence_p) *
12549 + for (k = 0, l = 0; ardeps[k]; ++k) {
12550 + s_usr = ardeps[k]->source->usr;
12551 + t_usr = ardeps[k]->target->usr;
12552 + if (s_usr->label >= source->label &&
12553 + s_usr->label <= target->label &&
12554 + t_usr->label >= source->label &&
12555 + t_usr->label <= target->label)
12556 + curardeps[l++] = ardeps[k];
12558 + curardeps[l] = NULL;
12559 + paths = find_dep_paths(curardeps, source, target);
12562 + for (j = 0; ardeps[j]; ++j) {
12563 + s_usr = ardeps[j]->source->usr;
12564 + t_usr = ardeps[j]->target->usr;
12565 + if (s_usr->label == source_label &&
12566 + t_usr->label == target_label) {
12567 + // Inspect all paths. If there is a path
12568 + // that respect the transitive cover prop,
12569 + // then discard the dependence.
12570 + for (k = 0; paths[k] && !is_covering(ardeps[j], paths[k]); ++k)
12573 + osl_relation_free(ardeps[j]->domain);
12576 + deps = ardeps[j + 1];
12578 + ardeps[j - 1]->next = ardeps[j + 1];
12582 + for (k = 0; paths[k]; ++k)
12600 diff --git a/source/scop.c b/source/scop.c
12601 new file mode 100644
12602 index 0000000..f6ec0ae
12604 +++ b/source/scop.c
12608 + /**------ ( ----------------------------------------------------------**
12610 + **----- / ) --------------------------------------------------------**
12611 + ** ( * ( scop.c **
12612 + **---- \#/ --------------------------------------------------------**
12613 + ** .-"#'-. First version: june 7th 2012 **
12614 + **--- |"-.-"| -------------------------------------------------------**
12617 + ******** | | *************************************************************
12618 + * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
12619 + ******************************************************************************
12621 + * Copyright (C) 2003-2008 Cedric Bastoul *
12623 + * This is free software; you can redistribute it and/or modify it under the *
12624 + * terms of the GNU General Public License as published by the Free Software *
12625 + * Foundation; either version 2 of the License, or (at your option) any later *
12628 + * This software is distributed in the hope that it will be useful, but *
12629 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
12630 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
12631 + * for more details. *
12633 + * You should have received a copy of the GNU General Public License along *
12634 + * with software; if not, write to the Free Software Foundation, Inc., *
12635 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
12637 + * CAnDL, the Chunky Dependence Analyzer *
12638 + * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
12640 + ******************************************************************************/
12643 + * author Joel Poudroux
12646 +#include <stdlib.h>
12647 +#include <osl/scop.h>
12648 +#include <osl/statement.h>
12649 +#include <candl/scop.h>
12650 +#include <candl/statement.h>
12653 + * candl_scop_usr_init function:
12654 + * initialize a candl_scop_usr structure
12656 + * May, 2013 extended to each scop in the list,
12658 +void candl_scop_usr_init(osl_scop_p scop) {
12661 + candl_scop_usr_p scop_usr;
12663 + /* Init the scop_usr structure */
12664 + scop_usr = (candl_scop_usr_p) malloc(sizeof(candl_scop_usr_t));
12665 + scop_usr->scalars_privatizable = NULL;
12666 + scop_usr->usr_backup = scop->usr;
12667 + scop->usr = scop_usr;
12669 + candl_statement_usr_init_all(scop);
12671 + scop = scop->next;
12677 + * candl_scop_usr_cleanup function:
12679 +void candl_scop_usr_cleanup(osl_scop_p scop) {
12682 + osl_statement_p statement = scop->statement;
12683 + candl_scop_usr_p scop_usr;
12684 + while (statement != NULL) {
12685 + candl_statement_usr_cleanup(statement);
12686 + statement = statement->next;
12688 + scop_usr = scop->usr;
12690 + if (scop_usr->scalars_privatizable)
12691 + free(scop_usr->scalars_privatizable);
12692 + scop->usr = scop_usr->usr_backup;
12696 + scop = scop->next;
12699 diff --git a/source/statement.c b/source/statement.c
12700 index 39ee0b8..d6845dd 100644
12701 --- a/source/statement.c
12702 +++ b/source/statement.c
12706 /**------ ( ----------------------------------------------------------**
12708 **----- / ) --------------------------------------------------------**
12709 - ** ( * ( statement.c **
12710 + ** ( * ( usr.c **
12711 **---- \#/ --------------------------------------------------------**
12712 - ** .-"#'-. First version: september 9th 2003 **
12713 + ** .-"#'-. First version: june 7th 2012 **
12714 **--- |"-.-"| -------------------------------------------------------**
12719 ******** | | *************************************************************
12720 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
12721 ******************************************************************************
12723 - * Copyright (C) 2003 Cedric Bastoul *
12724 + * Copyright (C) 2003-2008 Cedric Bastoul *
12726 * This is free software; you can redistribute it and/or modify it under the *
12727 * terms of the GNU General Public License as published by the Free Software *
12728 @@ -32,319 +33,103 @@
12729 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
12731 ******************************************************************************/
12732 -/* CAUTION: the english used for comments is probably the worst you ever read,
12733 - * please feel free to correct and improve it !
12736 -# include <stdlib.h>
12737 -# include <stdio.h>
12738 -# include <ctype.h>
12739 -# include <string.h>
12740 -# include "../include/candl/candl.h"
12743 -/******************************************************************************
12744 - * Structure display function *
12745 - ******************************************************************************/
12749 - * candl_statement_print_structure function:
12750 - * Displays a CandlStatement structure (statement) into a file (file,
12751 - * possibly stdout) in a way that trends to be understandable without falling
12752 - * in a deep depression or, for the lucky ones, getting a headache... It
12753 - * includes an indentation level (level) in order to work with others
12754 - * print_structure functions.
12755 - * - 18/09/2003: first version.
12757 + * author Joel Poudroux and Cedric Bastoul
12759 -void candl_statement_print_structure(file, statement, level)
12761 -CandlStatement * statement ;
12765 - if (statement != NULL)
12766 - { /* Go to the right level. */
12767 - for(j=0; j<level; j++)
12768 - fprintf(file,"|\t") ;
12769 - fprintf(file,"+-- CandlStatement\n") ;
12771 - /* A blank line. */
12772 - for(j=0; j<=level+1; j++)
12773 - fprintf(file,"|\t") ;
12774 - fprintf(file,"\n") ;
12776 - /* Go to the right level and print the label. */
12777 - for(j=0; j<=level; j++)
12778 - fprintf(file,"|\t") ;
12779 - fprintf(file,"Label: %d\n",statement->label) ;
12781 - /* A blank line. */
12782 - for(j=0; j<=level+1; j++)
12783 - fprintf(file,"|\t") ;
12784 - fprintf(file,"\n") ;
12786 - /* Go to the right level and print the type. */
12787 - for(j=0; j<=level; j++)
12788 - fprintf(file,"|\t") ;
12789 - fprintf(file,"Type: ") ;
12790 - switch (statement->type)
12791 - { case CANDL_UNSET : fprintf(file,"UNSET\n") ; break ;
12792 - case CANDL_ASSIGNMENT : fprintf(file,"assignment\n") ; break ;
12793 - case CANDL_P_REDUCTION : fprintf(file,"plus-reduction\n") ; break ;
12794 - case CANDL_M_REDUCTION : fprintf(file,"minus-reduction\n") ; break ;
12795 - case CANDL_T_REDUCTION : fprintf(file,"times-reduction\n") ; break ;
12796 - default : fprintf(file,"unknown\n") ;
12799 - /* A blank line. */
12800 - for(j=0; j<=level+1; j++)
12801 - fprintf(file,"|\t") ;
12802 - fprintf(file,"\n") ;
12804 - /* Go to the right level and print the outer loops. */
12805 - for(j=0; j<=level; j++)
12806 - fprintf(file,"|\t") ;
12807 - fprintf(file,"Depth: %d, outer loops(s):",statement->depth) ;
12808 - for (i=0;i<statement->depth;i++)
12809 - fprintf(file," %d",statement->index[i]) ;
12810 - fprintf(file,"\n") ;
12812 - /* A blank line. */
12813 - for(j=0; j<=level+1; j++)
12814 - fprintf(file,"|\t") ;
12815 - fprintf(file,"\n") ;
12817 - /* Print the iteration domain. */
12818 - candl_matrix_print_structure(file,statement->domain,level+1) ;
12820 - /* Print the written data. */
12821 - candl_matrix_print_structure(file,statement->written,level+1) ;
12823 - /* Print the read data. */
12824 - candl_matrix_print_structure(file,statement->read,level+1) ;
12827 - { /* Go to the right level. */
12828 - for(j=0; j<level; j++)
12829 - fprintf(file,"|\t") ;
12830 - fprintf(file,"+-- NULL statement\n") ;
12833 - /* The last line. */
12834 - for(j=0; j<=level; j++)
12835 - fprintf(file,"|\t") ;
12836 - fprintf(file,"\n") ;
12841 - * candl_statement_print function:
12842 - * This function prints the content of a CandlStatement structure (statement)
12843 - * into a file (file, possibly stdout).
12844 - * - 09/09/2003: first version.
12846 -void candl_statement_print(FILE * file, CandlStatement * statement)
12847 -{ candl_statement_print_structure(file,statement,0) ;
12851 -/******************************************************************************
12852 - * Memory deallocation function *
12853 - ******************************************************************************/
12857 - * candl_statement_free function:
12858 - * This function frees the allocated memory for a CandlStatement structure.
12859 - * - 09/09/2003: first version.
12861 -void candl_statement_free(CandlStatement * statement)
12862 -{ free(statement->index) ;
12863 - pip_matrix_free(statement->domain) ;
12864 - pip_matrix_free(statement->read) ;
12865 - pip_matrix_free(statement->written) ;
12866 - free(statement) ;
12869 +#include <stdlib.h>
12870 +#include <osl/scop.h>
12871 +#include <osl/statement.h>
12872 +#include <osl/extensions/dependence.h>
12873 +#include <osl/relation.h>
12874 +#include <candl/macros.h>
12875 +#include <candl/statement.h>
12876 +#include <candl/util.h>
12878 -/******************************************************************************
12879 - * Reading functions *
12880 - ******************************************************************************/
12881 +#define CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH 128
12885 - * candl_statement_read function:
12886 - * This function reads statement data from a file (file) and puts them into
12887 - * a CandlStatement structure. This function returns a pointer to this
12889 - * - label is the statement number ;
12890 - * - nb_parameters is the number of parameters.
12892 - * - 09/09/2003: first version.
12893 + * candl_statement_usr_init_all function:
12894 + * Init each candl_statement_usr structure of statements
12896 -CandlStatement * candl_statement_read(FILE * file, int label, int nb_parameters)
12897 -{ int i, n, * index ;
12898 - char s[CANDL_MAX_STRING], str[CANDL_MAX_STRING], * c, type ;
12899 - CandlStatement * statement ;
12901 - /* Statement data. */
12902 - statement = candl_statement_malloc() ;
12904 - /* We first read the statement type. */
12905 - while (fgets(s,CANDL_MAX_STRING,file) == 0) ;
12906 - while ((*s=='#' || *s=='\n') || (sscanf(s," %c",&type)<1))
12907 - fgets(s,CANDL_MAX_STRING,file) ;
12908 +void candl_statement_usr_init_all(osl_scop_p scop) {
12911 + * that statements must be sorted to compute the statement label
12912 + * the problem is if the scop is reordered, the second transformed scop
12913 + * must be aligned with it
12916 + osl_statement_p iter;
12917 + osl_relation_p scattering;
12918 + candl_statement_usr_p stmt_usr;
12921 + int precision = scop->context->precision;
12922 + int count = 0; /* counter for statements */
12925 - { case 'A': statement->type = CANDL_ASSIGNMENT ; break ;
12926 - case 'P': statement->type = CANDL_P_REDUCTION ; break ;
12927 - case 'M': statement->type = CANDL_M_REDUCTION ; break ;
12928 - case 'T': statement->type = CANDL_T_REDUCTION ; break ;
12929 - default : fprintf(stderr, "[Candl]ERROR: unknown statement type %c\n",type);
12930 - fprintf(stderr, " possible types are:\n") ;
12931 - fprintf(stderr, " - A for assignment (=),\n") ;
12932 - fprintf(stderr, " - P for plus-reduction (+=),\n") ;
12933 - fprintf(stderr, " - M for minus-reduction (-=),\n") ;
12934 - fprintf(stderr, " - T for times-reduction (*=).\n") ;
12936 + /* Initialize structures used in iterator indices computation. */
12939 + int cur_index[CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH];
12940 + int last[CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH];
12941 + for (i = 0; i < CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH; ++i) {
12942 + cur_index[i] = i;
12946 - statement->label = label ;
12947 - statement->domain = pip_matrix_read(file) ;
12948 - statement->depth = statement->domain->NbColumns - nb_parameters - 2 ;
12950 - index = (int *)malloc(sizeof(int)*statement->depth) ;
12951 - if (index == NULL)
12952 - { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
12956 - do /* Skip the comments, spaces and empty lines... */
12957 - { c = fgets(s,CANDL_MAX_STRING,file) ;
12958 - while ((c != NULL) && isspace(*c) && (*c != '\n'))
12961 - while (c != NULL && (*c == '#' || *c == '\n'));
12963 + /* Add useful information in the usr field of each statements */
12964 + for (iter = scop->statement ; iter != NULL ; iter = iter->next) {
12965 + scattering = iter->scattering;
12968 - { fprintf(stderr, "[Candl]ERROR: no labels in input file.\n") ;
12971 - for (i=0;i<statement->depth;i++)
12972 - { /* All iterator labels must be on the same line. */
12973 - while (isspace(*c))
12975 - if (c == NULL || *c == '#' || *c == '\n')
12976 - { fprintf(stderr, "[Candl]ERROR: not enough labels in input file.\n") ;
12979 - /* n is strlen(str). */
12980 - if (sscanf(c,"%s%n",str,&n) == 0)
12981 - { fprintf(stderr, "[Candl]ERROR: no labels in input file.\n") ;
12983 + stmt_usr = (candl_statement_usr_p) malloc(sizeof(candl_statement_usr_t));
12984 + stmt_usr->depth = scattering->nb_output_dims/2;
12985 + stmt_usr->label = count;
12986 + stmt_usr->type = OSL_DEPENDENCE_ASSIGNMENT;
12987 + stmt_usr->usr_backup = iter->usr;
12988 + stmt_usr->index = (stmt_usr->depth ?
12989 + (int*) malloc(stmt_usr->depth * sizeof(int)) :
12992 + /* Compute the value of the iterator indices.
12993 + * extracted from the last candl
12995 + for (j = 0; j < stmt_usr->depth; ++j) {
12996 + row = candl_util_relation_get_line(scattering, j*2);
12997 + val = osl_int_get_si(precision,
12998 + scattering->m[row][scattering->nb_columns - 1]);
12999 + if (last[j] < val) {
13001 + for (k = j + 1; k < CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH; ++k)
13003 + for (k = j; k < CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH; ++k)
13004 + cur_index[k] = max + (k - j) + 1;
13008 - sscanf(str,"%d",&index[i]) ;
13011 - statement->index = index ;
13013 - statement->written = pip_matrix_read(file) ;
13014 - statement->read = pip_matrix_read(file) ;
13015 + for (j = 0; j < stmt_usr->depth; ++j)
13016 + stmt_usr->index[j] = cur_index[j];
13018 - return statement ;
13022 -/******************************************************************************
13023 - * Processing functions *
13024 - ******************************************************************************/
13028 - * candl_statement_malloc function:
13029 - * This function allocates the memory space for a CandlStatement structure and
13030 - * sets its fields with default values. Then it returns a pointer to the
13031 - * allocated space.
13032 - * - 09/12/2005: first version.
13034 -CandlStatement * candl_statement_malloc()
13035 -{ CandlStatement * statement ;
13037 - /* Memory allocation for the CloogProgram structure. */
13038 - statement = (CandlStatement *)malloc(sizeof(CandlStatement)) ;
13039 - if (statement == NULL)
13040 - { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
13042 + max = max < cur_index[j - 1] ? cur_index[j - 1] : max;
13044 + iter->usr = stmt_usr;
13048 - /* We set the various fields with default values. */
13049 - statement->label = CANDL_UNSET ;
13050 - statement->type = CANDL_UNSET ;
13051 - statement->depth = CANDL_UNSET ;
13052 - statement->index = NULL ;
13053 - statement->domain = NULL ;
13054 - statement->written = NULL ;
13055 - statement->read = NULL ;
13056 - statement->ref = NULL ;
13058 - return statement ;
13063 - * candl_statement_commute function:
13064 - * This function returns 1 if the two statements given as parameter commute,
13065 - * 0 otherwise. It uses the statement type information to answer the question.
13066 - * - 09/12/2005: first version.
13067 + * candl_usr_free function:
13069 -int candl_statement_commute(statement1, statement2)
13070 -CandlStatement * statement1, * statement2 ;
13071 -{ int type1, type2, nb_rows, i ;
13073 - type1 = statement1->type ;
13074 - type2 = statement2->type ;
13076 - /* In the case of self-dependence, a statement commutes with hitself if
13077 - * it is a reduction.
13079 - if ((statement1 == statement2) &&
13080 - ((type1 == CANDL_P_REDUCTION) ||
13081 - (type1 == CANDL_M_REDUCTION) ||
13082 - (type1 == CANDL_T_REDUCTION)))
13085 - /* Two statement commute when they are a reduction of the same type (or if
13086 - * their left and right members are the same, but it's not exploited here).
13087 - * The type may differ if it is either minus or plus-reduction. Furthermore,
13088 - * they have to write onto the same array (and only one array).
13090 - if (((type1 == CANDL_P_REDUCTION) && (type2 == CANDL_P_REDUCTION)) ||
13091 - ((type1 == CANDL_M_REDUCTION) && (type2 == CANDL_M_REDUCTION)) ||
13092 - ((type1 == CANDL_T_REDUCTION) && (type2 == CANDL_T_REDUCTION)) ||
13093 - ((type1 == CANDL_P_REDUCTION) && (type2 == CANDL_M_REDUCTION)) ||
13094 - ((type1 == CANDL_M_REDUCTION) && (type2 == CANDL_P_REDUCTION)))
13095 - { /* Here we check that there is one, only one and the same array. */
13096 - nb_rows = statement1->written->NbRows ;
13097 - if ((nb_rows == 0) || (nb_rows != statement2->written->NbRows))
13100 - if (statement1->written->p[0][0] != statement2->written->p[0][0])
13103 - for (i=1;i<nb_rows;i++)
13104 - if ((statement1->written->p[i][0] != 0) ||
13105 - (statement2->written->p[i][0] != 0))
13112 +void candl_statement_usr_cleanup(osl_statement_p statement) {
13113 + candl_statement_usr_p stmt_usr;
13114 + stmt_usr = statement->usr;
13116 + if (stmt_usr->index)
13117 + free(stmt_usr->index);
13118 + statement->usr = stmt_usr->usr_backup;
13128 diff --git a/source/util.c b/source/util.c
13129 new file mode 100644
13130 index 0000000..df83aad
13132 +++ b/source/util.c
13135 + /**------ ( ----------------------------------------------------------**
13137 + **----- / ) --------------------------------------------------------**
13138 + ** ( * ( util.c **
13139 + **---- \#/ --------------------------------------------------------**
13140 + ** .-"#'-. First version: june 7th 2012 **
13141 + **--- |"-.-"| -------------------------------------------------------**
13144 + ******** | | *************************************************************
13145 + * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
13146 + ******************************************************************************
13148 + * Copyright (C) 2003-2008 Cedric Bastoul *
13150 + * This is free software; you can redistribute it and/or modify it under the *
13151 + * terms of the GNU General Public License as published by the Free Software *
13152 + * Foundation; either version 2 of the License, or (at your option) any later *
13155 + * This software is distributed in the hope that it will be useful, but *
13156 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
13157 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
13158 + * for more details. *
13160 + * You should have received a copy of the GNU General Public License along *
13161 + * with software; if not, write to the Free Software Foundation, Inc., *
13162 + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
13164 + * CAnDL, the Chunky Dependence Analyzer *
13165 + * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
13167 + ******************************************************************************/
13170 + * author Joel Poudroux and Cedric Bastoul
13173 +#include <stdio.h>
13174 +#include <stdlib.h>
13175 +#include <osl/statement.h>
13176 +#include <osl/relation.h>
13177 +#include <osl/macros.h>
13178 +#include <osl/extensions/dependence.h>
13179 +#include <osl/relation_list.h>
13180 +#include <osl/scop.h>
13181 +#include <candl/macros.h>
13182 +#include <candl/util.h>
13183 +#include <candl/statement.h>
13187 + * candl_util_relation_get_line function:
13188 + * Because the lines in the scattering matrix may have not ordered, we have to
13189 + * search the corresponding line. It returns the first line where the value is
13190 + * different from zero in the `column'. `column' is between 0 and
13191 + * nb_output_dims-1
13192 + * \param[in] relation
13193 + * \param[in] column Line to search
13194 + * \return Return the real line
13196 +int candl_util_relation_get_line(osl_relation_p relation, int column) {
13197 + if (column < 0 || column > relation->nb_output_dims)
13200 + int precision = relation->precision;
13201 + for (i = 0 ; i < relation->nb_rows ; i++) {
13202 + if (!osl_int_zero(precision, relation->m[i][column + 1])) {
13206 + return (i == relation->nb_rows ? -1 : i );
13211 +/* Check if two scop can be compared (same number of statements and
13212 + * same access array/domain in the same order)
13214 + * \param[in] s1 first scop to compare
13215 + * \param[in] s2 second scop to compare
13216 + * \return 1 if two scops equal, 0 otherwise
13218 +int candl_util_check_scop(osl_scop_p s1, osl_scop_p s2) {
13220 + osl_statement_p it1 = s1->statement, it2 = s2->statement;
13221 + for (; it1 != NULL && it2 != NULL ; it1 = it1->next, it2 = it2->next) {
13222 + if (!osl_relation_list_equal(it1->access, it2->access))
13224 + if (!osl_relation_equal(it1->domain, it2->domain))
13228 + /* Different number of statements */
13229 + if ((it1 == NULL || it2 == NULL) && it1 != it2)
13235 +/* Extends the candl_util_check_scop() functionality to a list of scops
13236 + * Compares each scop in s1 to the corresponding element in list s2
13237 + * same access array/domain in the same order)
13239 + * \param[in] s1 first scop List to compare
13240 + * \param[in] s2 second scop List to compare
13241 + * \return 1 if two scops lists equal, 0 otherwise
13243 +int candl_util_check_scop_list(osl_scop_p s1, osl_scop_p s2) {
13245 + while ((s1!=NULL) && (s2!=NULL)) {
13246 + if(!candl_util_check_scop(s1, s2))
13253 + /* Different number of scops */
13254 + if ((s1 == NULL || s2 == NULL) && s1 != s2)
13257 + /*scop lists can be compared*/
13261 +/* Return the number access array which have the type `type'
13263 +static int count_nb_access(osl_statement_p st, int type) {
13264 + osl_relation_list_p access = st->access;
13266 + for (; access != NULL ; access = access->next)
13267 + if (access->elt->type == type)
13274 + * candl_util_statement_commute function:
13275 + * This function returns 1 if the two statements given as parameter commute,
13276 + * 0 otherwise. It uses the statement type information to answer the question.
13277 + * - 09/12/2005: first version.
13279 +int candl_util_statement_commute(osl_statement_p statement1,
13280 + osl_statement_p statement2) {
13281 + candl_statement_usr_p usr1, usr2;
13282 + int type1, type2;
13285 + usr1 = statement1->usr;
13286 + usr2 = statement2->usr;
13287 + type1 = usr1->type;
13288 + type2 = usr2->type;
13290 + /* In the case of self-dependence, a statement commutes with hitself if
13291 + * it is a reduction.
13293 + if ((statement1 == statement2) &&
13294 + ((type1 == OSL_DEPENDENCE_P_REDUCTION) ||
13295 + (type1 == OSL_DEPENDENCE_M_REDUCTION) ||
13296 + (type1 == OSL_DEPENDENCE_T_REDUCTION)))
13299 + /* Two statement commute when they are a reduction of the same type (or if
13300 + * their left and right members are the same, but it's not exploited here).
13301 + * The type may differ if it is either minus or plus-reduction. Furthermore,
13302 + * they have to write onto the same array (and only one array).
13304 + if ((type1 == OSL_DEPENDENCE_P_REDUCTION && type2 == OSL_DEPENDENCE_P_REDUCTION) ||
13305 + (type1 == OSL_DEPENDENCE_M_REDUCTION && type2 == OSL_DEPENDENCE_M_REDUCTION) ||
13306 + (type1 == OSL_DEPENDENCE_T_REDUCTION && type2 == OSL_DEPENDENCE_T_REDUCTION) ||
13307 + (type1 == OSL_DEPENDENCE_P_REDUCTION && type2 == OSL_DEPENDENCE_M_REDUCTION) ||
13308 + (type1 == OSL_DEPENDENCE_M_REDUCTION && type2 == OSL_DEPENDENCE_P_REDUCTION)) {
13309 + /* Here we check that there is one, only one and the same array. */
13310 + if (count_nb_access(statement1, OSL_TYPE_WRITE) > 1 ||
13311 + count_nb_access(statement2, OSL_TYPE_WRITE) > 1)
13314 + /* search the first osl_write access */
13315 + osl_relation_list_p access1 = statement1->access;
13316 + osl_relation_list_p access2 = statement2->access;
13317 + for (; access1 != NULL && access2 != NULL ;
13318 + access1 = access1->next, access2 = access2->next)
13319 + if (access1->elt->type == OSL_TYPE_WRITE)
13322 + if (access1 == NULL || access2 == NULL ||
13323 + access2->elt->type != OSL_TYPE_WRITE ||
13324 + access2->elt->nb_output_dims != access1->elt->nb_output_dims) {
13325 + osl_statement_dump(stderr, statement1);
13326 + osl_statement_dump(stderr, statement2);
13327 + CANDL_error("These statements haven't the same access array or access is NULL");
13330 + /* Check if the first dim (the Arr column) is the same */
13331 + id1 = osl_relation_get_array_id(access1->elt);
13332 + id2 = osl_relation_get_array_id(access2->elt);
13341 diff --git a/source/violation.c b/source/violation.c
13342 index 1f2d4bb..3f8e3fe 100644
13343 --- a/source/violation.c
13344 +++ b/source/violation.c
13346 **---- \#/ --------------------------------------------------------**
13347 ** .-"#'-. First version: december 12th 2005 **
13348 **--- |"-.-"| -------------------------------------------------------**
13353 ******** | | *************************************************************
13354 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
13355 ******************************************************************************
13356 @@ -36,10 +36,20 @@
13357 * please feel free to correct and improve it !
13360 -# include <stdlib.h>
13361 -# include <stdio.h>
13362 -# include <string.h>
13363 -# include "../include/candl/candl.h"
13364 +#include <stdlib.h>
13365 +#include <stdio.h>
13366 +#include <string.h>
13367 +#include <osl/macros.h>
13368 +#include <osl/relation.h>
13369 +#include <osl/statement.h>
13370 +#include <osl/scop.h>
13371 +#include <osl/extensions/dependence.h>
13372 +#include <candl/macros.h>
13373 +#include <candl/matrix.h>
13374 +#include <candl/piplib.h>
13375 +#include <candl/piplib-wrapper.h>
13376 +#include <candl/statement.h>
13377 +#include <candl/violation.h>
13380 /******************************************************************************
13381 @@ -48,84 +58,79 @@
13385 - * candl_violation_print_structure function:
13386 + * candl_violation_idump function:
13387 * Displays a CandlViolation structure (violation) into a file (file,
13388 * possibly stdout) in a way that trends to be understandable without falling
13389 * in a deep depression or, for the lucky ones, getting a headache... It
13390 * includes an indentation level (level) in order to work with others
13391 - * print_structure functions.
13392 + * idump functions.
13393 * - 18/09/2003: first version.
13395 -void candl_violation_print_structure(file, violation, level)
13397 -CandlViolation * violation ;
13399 -{ int j, first=1 ;
13400 - CandlDependence * next=NULL ;
13402 - if (violation != NULL)
13403 - { /* Go to the right level. */
13404 +void candl_violation_idump(FILE *file, candl_violation_p violation,
13407 + osl_dependence_p next=NULL;
13409 + if (violation != NULL) { /* Go to the right level. */
13410 for(j=0; j<level; j++)
13411 - fprintf(file,"|\t") ;
13412 - fprintf(file,"+-- CandlViolation\n") ;
13415 - { for(j=0; j<level; j++)
13416 - fprintf(file,"|\t") ;
13417 - fprintf(file,"+-- NULL dependence violation\n") ;
13418 + fprintf(file,"|\t");
13419 + fprintf(file,"+-- CandlViolation\n");
13421 + for(j=0; j<level; j++)
13422 + fprintf(file,"|\t");
13423 + fprintf(file,"+-- NULL dependence violation\n");
13426 - while (violation != NULL)
13428 - { /* Go to the right level. */
13429 + while (violation != NULL) {
13430 + if (!first) { /* Go to the right level. */
13431 for(j=0; j<level; j++)
13432 - fprintf(file,"|\t") ;
13433 - fprintf(file,"| CandlViolation\n") ;
13434 + fprintf(file,"|\t");
13435 + fprintf(file,"| CandlViolation\n");
13442 /* A blank line. */
13443 for(j=0; j<=level+1; j++)
13444 - fprintf(file,"|\t") ;
13445 - fprintf(file,"\n") ;
13446 + fprintf(file,"|\t");
13447 + fprintf(file,"\n");
13449 /* Go to the right level and print the dimension. */
13450 for(j=0; j<=level; j++)
13451 - fprintf(file,"|\t") ;
13452 - fprintf(file,"Dimension: %d\n",violation->dimension) ;
13453 + fprintf(file,"|\t");
13454 + fprintf(file,"Dimension: %d\n",violation->dimension);
13456 /* A blank line. */
13457 for(j=0; j<=level+1; j++)
13458 - fprintf(file,"|\t") ;
13459 - fprintf(file,"\n") ;
13460 + fprintf(file,"|\t");
13461 + fprintf(file,"\n");
13463 /* Print the dependence. */
13464 - if (violation->dependence != NULL)
13465 - { next = violation->dependence->next ; /* To not print the whole list... */
13466 - violation->dependence->next = NULL ; /* I know it's not beautiful :-/ ! */
13467 + if (violation->dependence != NULL) {
13468 + next = violation->dependence->next; /* To not print the whole list... */
13469 + violation->dependence->next = NULL; /* I know it's not beautiful :-/ ! */
13471 - candl_dependence_print_structure(file,violation->dependence,level+1) ;
13472 + osl_dependence_idump(file,violation->dependence,level+1);
13473 if (violation->dependence != NULL)
13474 - violation->dependence->next = next ;
13475 + violation->dependence->next = next;
13477 /* Print the dependence polyhedron. */
13478 - candl_matrix_print_structure(file,violation->domain,level+1) ;
13479 + osl_relation_idump(file, violation->domain, level+1);
13481 - violation = violation->next ;
13482 + violation = violation->next;
13485 - if (violation != NULL)
13486 - { for (j=0; j<=level; j++)
13487 - fprintf(file,"|\t") ;
13488 - fprintf(file,"V\n") ;
13489 + if (violation != NULL) {
13490 + for (j=0; j<=level; j++)
13491 + fprintf(file,"|\t");
13492 + fprintf(file,"V\n");
13496 /* The last line. */
13497 for(j=0; j<=level; j++)
13498 - fprintf(file,"|\t") ;
13499 - fprintf(file,"\n") ;
13500 + fprintf(file,"|\t");
13501 + fprintf(file,"\n");
13505 @@ -133,8 +138,8 @@ int level ;
13506 * This function prints the content of a CandlViolation structure
13507 * (violation) into a file (file, possibly stdout).
13509 -void candl_violation_print(FILE * file, CandlViolation * violation)
13510 -{ candl_violation_print_structure(file,violation,0) ;
13511 +void candl_violation_dump(FILE * file, candl_violation_p violation) {
13512 + candl_violation_idump(file,violation,0);
13516 @@ -144,43 +149,47 @@ void candl_violation_print(FILE * file, CandlViolation * violation)
13517 * See http://www.graphviz.org
13518 * - 12/12/2005: first version.
13520 -void candl_violation_pprint(FILE * file, CandlViolation * violation)
13522 - CandlDependence * dependence ;
13523 +void candl_violation_pprint(FILE * file, candl_violation_p violation) {
13525 + osl_dependence_p dependence;
13526 + candl_statement_usr_p s_usr;
13527 + candl_statement_usr_p t_usr;
13529 - fprintf(file,"digraph G {\n") ;
13530 + fprintf(file,"digraph G {\n");
13532 - fprintf(file,"# Legality Violation Graph\n") ;
13533 + fprintf(file,"# Legality Violation Graph\n");
13534 fprintf(file,"# Generated by Candl "CANDL_RELEASE" "CANDL_VERSION" bits\n");
13535 if (violation == NULL)
13536 - fprintf(file,"# Congratulations: the transformation is legal !\n");
13538 - while (violation != NULL)
13539 - { dependence = violation->dependence ;
13541 - fprintf(file," S%d -> S%d [label=\" ",dependence->source->label,
13542 - dependence->target->label) ;
13543 - switch (dependence->type)
13544 - { case CANDL_UNSET : fprintf(file,"UNSET") ; break ;
13545 - case CANDL_RAW : fprintf(file,"RAW") ; break ;
13546 - case CANDL_WAR : fprintf(file,"WAR") ; break ;
13547 - case CANDL_WAW : fprintf(file,"WAW") ; break ;
13548 - case CANDL_RAR : fprintf(file,"RAR") ; break ;
13549 - default : fprintf(file,"unknown") ;
13550 + fprintf(file,"# Congratulations: the transformation is legal !\n");
13552 + while (violation != NULL) {
13553 + dependence = violation->dependence;
13554 + s_usr = dependence->stmt_source_ptr->usr;
13555 + t_usr = dependence->stmt_target_ptr->usr;
13557 + fprintf(file," S%d -> S%d [label=\" ", s_usr->label,
13559 + switch (dependence->type) {
13560 + case OSL_UNDEFINED : fprintf(file,"UNSET"); break;
13561 + case OSL_DEPENDENCE_RAW : fprintf(file,"RAW") ; break;
13562 + case OSL_DEPENDENCE_WAR : fprintf(file,"WAR") ; break;
13563 + case OSL_DEPENDENCE_WAW : fprintf(file,"WAW") ; break;
13564 + case OSL_DEPENDENCE_RAR : fprintf(file,"RAR") ; break;
13565 + default : fprintf(file,"unknown");
13567 fprintf(file," depth %d, ref %d->%d, viol %d \"];\n",
13569 dependence->ref_source,
13570 dependence->ref_target,
13571 - violation->dimension) ;
13572 - violation = violation->next ;
13574 + violation->dimension);
13575 + violation = violation->next;
13580 - fprintf(file,"# Number of edges = %i\n}\n",i) ;
13581 + fprintf(file,"# Number of edges = %i\n}\n",i);
13583 - fprintf(file,"}\n") ;
13584 + fprintf(file,"}\n");
13588 @@ -190,13 +199,14 @@ void candl_violation_pprint(FILE * file, CandlViolation * violation)
13590 * - 20/03/2006: first version.
13592 -void candl_violation_view(CandlViolation * violation)
13593 -{ FILE * temp_output ;
13595 - temp_output = fopen(CANDL_TEMP_OUTPUT,"w") ;
13596 - candl_violation_pprint(temp_output,violation) ;
13597 - fclose(temp_output) ;
13598 - system("(dot -Tps "CANDL_TEMP_OUTPUT" | gv - &) && rm -f "CANDL_TEMP_OUTPUT) ;
13599 +void candl_violation_view(candl_violation_p violation) {
13600 + FILE * temp_output;
13601 + temp_output = fopen(CANDL_TEMP_OUTPUT,"w+");
13602 + candl_violation_pprint(temp_output,violation);
13603 + fclose(temp_output);
13604 + /* check the return to remove the warning compilation */
13605 + if(system("dot -Tps "CANDL_TEMP_OUTPUT" | gv - && rm -f "CANDL_TEMP_OUTPUT" &"))
13610 @@ -208,14 +218,13 @@ void candl_violation_view(CandlViolation * violation)
13611 * This function frees the allocated memory for a CandlViolation structure.
13612 * - 18/09/2003: first version.
13614 -void candl_violation_free(CandlViolation * violation)
13615 -{ CandlViolation * next ;
13617 - while (violation != NULL)
13618 - { next = violation->next ;
13619 - candl_matrix_free(violation->domain) ;
13620 - free(violation) ;
13621 - violation = next ;
13622 +void candl_violation_free(candl_violation_p violation) {
13623 + candl_violation_p next;
13624 + while (violation != NULL) {
13625 + next = violation->next;
13626 + osl_relation_free(violation->domain);
13628 + violation = next;
13632 @@ -232,23 +241,27 @@ void candl_violation_free(CandlViolation * violation)
13634 * - 07/12/2005: first version.
13636 -CandlViolation * candl_violation_malloc()
13637 -{ CandlViolation * violation ;
13638 +candl_violation_p candl_violation_malloc() {
13639 + candl_violation_p violation;
13641 /* Memory allocation for the CandlViolation structure. */
13642 - violation = (CandlViolation *)malloc(sizeof(CandlViolation)) ;
13643 - if (violation == NULL)
13644 - { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
13646 + violation = (candl_violation_p) malloc(sizeof(candl_violation_t));
13647 + if (violation == NULL) {
13648 + fprintf(stderr, "[Candl]ERROR: memory overflow.\n");
13652 /* We set the various fields with default values. */
13653 - violation->dependence = NULL ;
13654 - violation->domain = NULL ;
13655 - violation->next = NULL ;
13656 - violation->dimension = CANDL_UNSET ;
13658 - return violation ;
13659 + violation->dependence = NULL;
13660 + violation->domain = NULL;
13661 + violation->next = NULL;
13662 + violation->dimension = OSL_UNDEFINED;
13663 + violation->source_nb_output_dims_scattering = -1;
13664 + violation->target_nb_output_dims_scattering = -1;
13665 + violation->source_nb_local_dims_scattering = -1;
13666 + violation->target_nb_local_dims_scattering = -1;
13668 + return violation;
13672 @@ -258,22 +271,23 @@ CandlViolation * candl_violation_malloc()
13673 * of this list is (start). This function updates (now) to the end of the loop
13674 * list (loop), and updates (start) if the added element is the first one -that
13675 * is when (start) is NULL-.
13676 - * - 12/12/2005: first version (from candl_dependence_add).
13677 + * - 12/12/2005: first version (from candl_dependence_add,
13678 + * currently osl_dependence_add).
13680 -void candl_violation_add(start, now, violation)
13681 -CandlViolation ** start, ** now, * violation ;
13682 -{ if (violation != NULL)
13683 - { if (*start == NULL)
13684 - { *start = violation ;
13688 - { (*now)->next = violation ;
13689 - *now = (*now)->next ;
13690 +void candl_violation_add(candl_violation_p* start,
13691 + candl_violation_p* now,
13692 + candl_violation_p violation) {
13693 + if (violation != NULL) {
13694 + if (*start == NULL) {
13695 + *start = violation;
13698 + (*now)->next = violation;
13699 + *now = (*now)->next;
13702 while ((*now)->next != NULL)
13703 - *now = (*now)->next ;
13704 + *now = (*now)->next;
13708 @@ -289,86 +303,97 @@ CandlViolation ** start, ** now, * violation ;
13710 * - 12/12/2005: first version.
13712 -CandlViolation * candl_violation(program, dependence, options)
13713 -CandlProgram * program ;
13714 -CandlDependence * dependence ;
13715 -CandlOptions * options ;
13716 -{ int dimension, max_dimension, violated ;
13717 - CandlMatrix * system, * domain, * t_source, * t_target ;
13718 - CandlStatement * source, * target ;
13719 - CandlViolation * violation=NULL, * now=NULL, * new ;
13720 - PipOptions * pip_options ;
13721 - PipQuast * solution ;
13723 - /* If there is no program or transformation, we consider this legal. */
13724 - if ((program == NULL) || (program->transformation == NULL))
13727 - /* If the dependence graph is not already built, do it. */
13728 - if (dependence == NULL)
13729 - dependence = candl_dependence(program,options) ;
13731 - pip_options = pip_options_init() ;
13732 - pip_options->Simplify = 1 ;
13733 +candl_violation_p candl_violation(osl_scop_p orig_scop,
13734 + osl_dependence_p orig_dependence,
13735 + osl_scop_p test_scop,
13736 + candl_options_p options) {
13737 + osl_statement_p source, target, iter;
13738 + osl_statement_p *stmts;
13739 + osl_relation_p t_source, t_target;
13740 + candl_statement_usr_p s_usr, t_usr;
13741 + candl_violation_p violation = NULL, now, new;
13742 + PipOptions *pip_options;
13743 + PipQuast *solution;
13745 + int nb_par = orig_scop->context->nb_parameters;
13746 + int nb_stmts = 0;
13747 + int dimension, max_dimension, violated;
13749 + /* If there is no scop or transformation, we consider this legal. */
13750 + if (test_scop == NULL)
13753 + /* Temporary array to access faster at the `label'th statement */
13754 + for (iter = test_scop->statement ; iter != NULL ;
13755 + iter = iter->next, nb_stmts++)
13757 + stmts = (osl_statement_p*) malloc(sizeof(osl_statement_p) * nb_stmts);
13758 + for (i = 0, iter = test_scop->statement ; iter != NULL ;
13759 + iter = iter->next, i++) {
13763 + pip_options = pip_options_init();
13764 + pip_options->Simplify = 1;
13766 /* We check every edge of the dependence graph. */
13767 - while (dependence != NULL)
13768 - { source = dependence->source ;
13769 - target = dependence->target ;
13770 - domain = dependence->domain ;
13771 + while (orig_dependence != NULL) {
13772 + source = orig_dependence->stmt_source_ptr;
13773 + target = orig_dependence->stmt_target_ptr;
13774 + s_usr = source->usr;
13775 + t_usr = target->usr;
13777 /* We find the source transformation matrix. */
13778 - t_source = program->transformation[source->label] ;
13779 + t_source = stmts[s_usr->label]->scattering;
13781 /* We find the target transformation matrix. */
13782 - t_target = program->transformation[target->label] ;
13784 + t_target = stmts[t_usr->label]->scattering;
13786 /* The maximal dimension we have to check for legality. */
13787 - max_dimension = CANDL_min(t_source->NbRows,t_target->NbRows) ;
13789 + max_dimension = CANDL_min(t_source->nb_output_dims,t_target->nb_output_dims);
13791 /* We check each dimension for legality. */
13792 - for (dimension = 0; dimension<max_dimension; dimension++)
13795 + for (dimension = 1; dimension <= max_dimension; dimension++) {
13798 /* We build the constraint system corresponding to that
13799 * violation then check if there is an integral point inside,
13800 * if yes there is actually a dependence violation and we
13801 * will add this one to the list.
13803 - system = candl_matrix_violation(dependence->domain,t_source,t_target,
13804 - dimension,program->context->NbColumns-2) ;
13806 - solution = pip_solve(system,program->context,-1,pip_options) ;
13807 + new = candl_matrix_violation(orig_dependence, t_source,
13808 + t_target, dimension,
13810 + solution = pip_solve_osl(new->domain, orig_scop->context, -1, pip_options);
13812 if ((solution != NULL) &&
13813 ((solution->list != NULL) || (solution->condition != NULL)))
13816 - pip_quast_free(solution) ;
13820 - { new = candl_violation_malloc() ;
13821 + pip_quast_free(solution);
13823 - /* We set the various fields with corresponding values. */
13824 - new->dependence = dependence ;
13825 - new->dimension = dimension ;
13826 - new->domain = system ;
13829 - candl_violation_add(&violation,&now,new) ;
13830 + /* We set the various fields with corresponding values. */
13831 + new->dependence = orig_dependence;
13832 + new->dimension = dimension;
13833 + candl_violation_add(&violation,&now,new);
13835 - if (!options->fullcheck)
13836 - { pip_options_free(pip_options) ;
13837 - return violation ;
13839 + if (!options->fullcheck) {
13840 + pip_options_free(pip_options);
13841 + return violation;
13843 + } else if (new) {
13844 + candl_violation_free(new);
13847 - candl_matrix_free(system) ;
13849 - dependence = dependence->next ;
13850 + orig_dependence = orig_dependence->next;
13853 - pip_options_free(pip_options) ;
13854 - return violation ;
13857 + pip_options_free(pip_options);
13859 + return violation;