--- /dev/null
+diff --git a/.gitmodules b/.gitmodules
+new file mode 100644
+index 0000000..3279daf
+--- /dev/null
++++ b/.gitmodules
+@@ -0,0 +1,6 @@
++[submodule "osl"]
++ path = osl
++ url = https://github.com/periscop/openscop.git
++[submodule "piplib"]
++ path = piplib
++ url = https://github.com/periscop/piplib.git
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+new file mode 100755
+index 0000000..a16d5e4
+--- /dev/null
++++ b/CMakeLists.txt
+@@ -0,0 +1,249 @@
++cmake_minimum_required(VERSION 2.8)
++
++
++set(PACKAGE_VERSION "0.6.2")
++set(RELEASE "${PACKAGE_VERSION}")
++set(BITS "32")
++set(DEFINE_HAS_ISL_LIB "")
++set(top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
++
++set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
++
++
++# User's settings - C Flags
++
++# set(release "TRUE")
++ set(release "FALSE")
++
++ # Release
++ if (release)
++ set(CMAKE_C_FLAGS "-O3")
++ # Debug # valgrind --show-reachable=yes --leak-check=full -v exe
++ else()
++ set(CMAKE_C_FLAGS "-O0 -g3")
++ endif()
++
++# User's settings - General C Flags
++ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -std=c99")
++
++
++# Build doxygen
++ find_package(Doxygen)
++ if (DOXYGEN_FOUND)
++ configure_file("doc/Doxyfile.in" "Doxyfile")
++ add_custom_target(
++ doxygen
++ ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
++ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
++ COMMENT "Generating API documentation with Doxygen" VERBATIM
++ )
++ else()
++ message (STATUS "Doxygen not found :( API documentation can not be built")
++ endif()
++
++# Build documentation
++
++ # doc
++ find_program(texi2pdf_exe texi2pdf)
++ if (texi2pdf_exe)
++ add_custom_target(
++ doc
++ ${texi2pdf_exe} ${CMAKE_CURRENT_SOURCE_DIR}/doc/candl.texi --output=${CMAKE_CURRENT_BINARY_DIR}/candl.pdf
++ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
++ COMMENT "Generating documentation (pdf) (with texi2pdf)" VERBATIM
++ )
++ else()
++ message (STATUS "texi2pdf not found :( Documentation can not be built")
++ endif()
++
++
++# osl
++ find_package(osl REQUIRED)
++
++# GMP & piplib
++ message(STATUS "---")
++ find_library(gmp_LIB gmp)
++ if (gmp_LIB)
++ message (STATUS "Library gmp found =) ${gmp_LIB}")
++ set(BITS "MP")
++ # piplibMP
++ find_package(piplibMP REQUIRED)
++ else()
++ message(STATUS "Library gmp not found :(")
++ # piplib64
++ find_package(piplib64 REQUIRED)
++ endif()
++
++# Include directories (to use #include <> instead of #include "")
++
++ # include/candl/macros.h
++ configure_file("include/candl/macros.h.in" "include/candl/macros.h")
++ include_directories("${CMAKE_CURRENT_BINARY_DIR}/include")
++ # candl
++ include_directories("./include")
++
++
++# Compiler log
++ message(STATUS "---")
++ message(STATUS "C compiler = ${CMAKE_C_COMPILER}")
++ if (release)
++ message(STATUS "Mode Release")
++ else()
++ message(STATUS "Mode Debug")
++ endif()
++ message(STATUS "C flags = ${CMAKE_C_FLAGS}")
++
++
++# Library
++
++ message(STATUS "---")
++
++ # files .c
++ file(
++ GLOB_RECURSE
++ sources
++ source/*
++ )
++ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/source/candl.c;" "" sources "${sources}") # with ;
++ string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/source/candl.c" "" sources "${sources}") # without ;
++
++ # Shared
++ add_library(
++ candl
++ SHARED
++ ${sources}
++ )
++ target_link_libraries(candl ${OSL_LIBRARY})
++ if (gmp_LIB)
++ target_link_libraries(candl ${PIPLIBMP_LIBRARY})
++ else()
++ target_link_libraries(candl ${PIPLIB64_LIBRARY})
++ endif()
++ get_property(candl_lib_location TARGET candl PROPERTY LOCATION)
++ message(STATUS "Add candl library (shared) ${candl_lib_location}")
++
++ # Static
++ add_library(
++ candl_static
++ STATIC
++ ${sources}
++ )
++ set_target_properties(candl_static PROPERTIES OUTPUT_NAME candl)
++ if (gmp_LIB)
++ target_link_libraries(candl_static ${PIPLIBMP_LIBRARY})
++ else()
++ target_link_libraries(candl_static ${PIPLIB64_LIBRARY})
++ endif()
++ target_link_libraries(candl_static ${OSL_LIBRARY})
++ get_property(candl_static_lib_location TARGET candl_static PROPERTY LOCATION)
++ message(STATUS "Add candl library (static) ${candl_static_lib_location}")
++
++
++# Executables & tests
++
++ message(STATUS "---") # candl
++
++ message(STATUS "Add executable candl")
++ add_executable(candl_exe "source/candl.c")
++ set_target_properties(candl_exe PROPERTIES OUTPUT_NAME "candl")
++ target_link_libraries(candl_exe candl_static ${OSL_LIBRARY})
++ if (gmp_LIB)
++ target_link_libraries(candl_exe candl_static ${gmp_LIB})
++ endif()
++
++ # candl test
++ find_program(bash_exe bash)
++ if (bash_exe)
++
++ message(STATUS "---")
++
++ enable_testing()
++
++ file(
++ GLOB_RECURSE
++ tests_unitary
++ tests/unitary/*.c
++ )
++
++ foreach(test ${tests_unitary})
++ message(STATUS "Add Unitary test ${test}")
++ add_test(
++ "tests_unitary_${test}"
++ "${bash_exe}"
++ "${CMAKE_CURRENT_SOURCE_DIR}/tests/checker.sh"
++ "${test}"
++ "${test}"
++ "0"
++ )
++ endforeach()
++
++ file(
++ GLOB_RECURSE
++ tests_transformations_must_fail
++ tests/transformations/must_fail/*.c
++ )
++
++ foreach(test ${tests_transformations_must_fail})
++ message(STATUS "Add Transformation must fail test ${test}")
++ add_test(
++ "tests_transformations_must_fail_${test}"
++ "${bash_exe}"
++ "${CMAKE_CURRENT_SOURCE_DIR}/tests/checker.sh"
++ "${test}"
++ "${test}"
++ "1"
++ )
++ endforeach()
++
++ file(
++ GLOB_RECURSE
++ tests_transformations_working
++ tests/transformations/working/*.c
++ )
++
++ foreach(test ${tests_transformations_working})
++ message(STATUS "Add Transformation working test ${test}")
++ add_test(
++ "tests_transformations_working_${test}"
++ "${bash_exe}"
++ "${CMAKE_CURRENT_SOURCE_DIR}/tests/checker.sh"
++ "${test}"
++ "${test}"
++ "1"
++ )
++ endforeach()
++
++ endif()
++
++
++# Install
++
++ install(TARGETS candl LIBRARY DESTINATION lib)
++ install(TARGETS candl_static ARCHIVE DESTINATION lib)
++ install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN "*.h")
++ install(DIRECTORY include/ DESTINATION include FILES_MATCHING PATTERN "*.hpp")
++ install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/" DESTINATION include FILES_MATCHING PATTERN "*.h")
++ install(FILES candl-config.cmake DESTINATION lib/candl)
++ install(TARGETS candl_exe RUNTIME DESTINATION bin)
++
++
++# Little help
++
++ message(STATUS "You can execute:")
++ message(STATUS " make # To compile candl library & candl")
++ if (bash_exe)
++ message(STATUS " make test # To execute tests")
++ message(STATUS " (with the first candl in the $PATH (?))")
++ endif()
++ message(STATUS " make install # To install library, include and CMake module")
++ message(STATUS " # If you need root access:")
++ message(STATUS " # sudo make install")
++ message(STATUS " # su -c \"make install\"")
++ if (DOXYGEN_FOUND)
++ message(STATUS " make doxygen # To generate the Doxygen")
++ endif()
++ if( texi2pdf_exe)
++ message(STATUS " make doc # To generate the documentation")
++ endif()
++
++ message(STATUS "---")
+diff --git a/Makefile.am b/Makefile.am
+index fefbf45..6839b4b 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -32,39 +32,90 @@
+ # * *
+ # *****************************************************************************/
+
++#############################################################################
++
++if BUNDLED_OSL
++ MAYBE_OSL = osl
++ OSL_LA = $(top_builddir)/osl/libosl.la
++endif
++if BUNDLED_PIPLIB
++ MAYBE_PIPLIB = piplib
++ PIPLIB_LA = $(top_builddir)/piplib/libpiplib$(BITS).la
++endif
++
++SUBDIRS = $(MAYBE_OSL) $(MAYBE_PIPLIB) doc tests
++DIST_SUBDIRS = $(MAYBE_OSL) $(MAYBE_PIPLIB) doc tests
++ACLOCAL_AMFLAGS = -I m4
++
++#############################################################################
++
++bin_PROGRAMS = candl
++lib_LTLIBRARIES = libcandl.la
+
+ #############################################################################
+-SUBDIRS = doc source include tests
+
++pkginclude_HEADERS = \
++ include/candl/candl.h \
++ include/candl/dependence.h \
++ include/candl/scop.h \
++ include/candl/statement.h \
++ include/candl/macros.h \
++ include/candl/util.h \
++ include/candl/ddv.h \
++ include/candl/matrix.h \
++ include/candl/options.h \
++ include/candl/piplib.h \
++ include/candl/piplib-wrapper.h \
++ include/candl/violation.h
++
++DEFAULT_INCLUDES = -I.
++INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
++AM_CFLAGS = $(CFLAGS_WARN)
+
+ #############################################################################
+-ACLOCAL_AMFLAGS = -I autoconf
+
+-m4datadir = $(datadir)/aclocal
++EXTRA_DIST = COPYING.LESSER AUTHORS
++
++libcandl_la_LIBADD = @OSL_LIBS@ @PIPLIB_LIBS@ $(OSL_LA) $(PIPLIB_LA)
++libcandl_la_CPPFLAGS = @OSL_CPPFLAGS@ @PIPLIB_CPPFLAGS@ -g
++libcandl_la_LDFLAGS = @OSL_LDFLAGS@ @PIPLIB_LDFLAGS@
++libcandl_la_SOURCES = \
++ source/dependence.c \
++ source/ddv.c \
++ source/scop.c \
++ source/statement.c \
++ source/util.c \
++ source/isl-wrapper.c \
++ source/matrix.c \
++ source/options.c \
++ source/piplib-wrapper.c \
++ source/pruning.c \
++ source/violation.c
+
+-EXTRA_DIST = COPYING.LESSER AUTHORS
++#############################################################################
+
+-AUX_DIST = \
+- $(ac_aux_dir)/config.guess \
+- $(ac_aux_dir)/config.sub \
+- $(ac_aux_dir)/install-sh \
+- $(ac_aux_dir)/ltmain.sh \
+- $(ac_aux_dir)/missing \
+- $(ac_aux_dir)/depcomp \
+- $(ac_aux_dir)/texinfo.tex
++LDADD = @CANDL_LIBS@ @OSL_LIBS@ @PIPLIB_LIBS@
++candl_CPPFLAGS = @OSL_CPPFLAGS@ @PIPLIB_CPPFLAGS@ -g -Wall
++candl_LDFLAGS = #@OSL_LDFLAGS@ @PIPLIB_LDFLAGS@ # TO BE REMOVED
++candl_DEPENDENCIES = libcandl.la
++candl_SOURCES = source/candl.c
+
++#############################################################################
+
+-MAINTAINERCLEANFILES = \
+- Makefile.in \
+- aclocal.m4 \
+- configure \
+- source/stamp-h.in \
++MAINTAINERCLEANFILES = \
++ Makefile.in \
++ aclocal.m4 \
++ configure \
+ $(AUX_DIST)
+
+ #############################################################################
++
+ dist-hook:
+ (cd $(distdir) && mkdir -p $(ac_aux_dir))
+ for file in $(AUX_DIST); do \
+ cp $$file $(distdir)/$$file; \
+ done
+ #############################################################################
++
++valcheck:
++ $(MAKE) valcheck -C tests
+diff --git a/README b/README
+index 1b20de6..864d102 100644
+--- a/README
++++ b/README
+@@ -5,7 +5,7 @@
+ Install
+ -------
+
+-To install candl, PIPLib must be installed. Optionally, scoplib must
++To install candl, PIPLib must be installed. Optionally, OpenScop library must
+ be installed to enable SCoP support.
+
+ $> ./configure --with-piplib=/path/to/piplib/install --with-scoplib=/path/to/scoplib/install
+@@ -15,6 +15,32 @@ $> make
+ $> make install
+
+
++Alternatively, to use bunled PIPLib and OpenScop library, follow following command
++sequence:
++
++$> ./get_submodules.sh
++
++$> ./autogen.sh
++
++$> ./configure --with-piplib=bundled --with-scoplib=bundled
++
++$> make
++
++$> make install
++
++Alternative: Install with CMake
++-------------------------------
++
++$> mkdir build
++$> cd build
++$> cmake .. # -DCMAKE_INSTALL_PREFIX="/your/install/directory"
++$> make
++$> make test
++$> # make install # sudo make install # su -c "make install"
++$> make doc
++$> make doxygen
++
++
+ Support
+ -------
+
+diff --git a/TODO b/TODO
+new file mode 100644
+index 0000000..74b6087
+--- /dev/null
++++ b/TODO
+@@ -0,0 +1,59 @@
++
++- unchecked -commute
++
++- lastwriter not finished
++ see the FIXME in the function candl_dep_compute_lastwriter
++
++- compilation error with ISL :
++ To test it, in isl-wrapper change #ifdef CANDL_SUPPORTS_ISL to
++ #ifndef CANDL_SUPPORTS_ISL
++
++ The error is :
++ source/isl-wrapper.c: In function ‘isl_constraint_read_from_matrix’:
++ source/isl-wrapper.c:79: warning: passing argument 1 of ‘isl_equality_alloc’ from incompatible pointer type
++ /home/jpoudroux/usr/include/isl/constraint.h:28: note: expected ‘struct isl_local_space *’ but argument is of type ‘struct isl_space *’
++ source/isl-wrapper.c:81: warning: passing argument 1 of ‘isl_inequality_alloc’ from incompatible pointer type
++ /home/jpoudroux/usr/include/isl/constraint.h:29: note: expected ‘struct isl_local_space *’ but argument is of type ‘struct isl_space *’
++
++- prunnning not finish (prunning.c: line 258 to 328)
++ Uncomment the CANDL_COMPILE_PRUNNING in candl.h, or remove the ifdef in
++ prunning.c
++
++- change the type of the dependence/violation domain
++ (at the end of candl_dependence_build_system and candl_matrix_violation)
++ today it's : OSL_UNDEFINED
++
++- candl_usr_init
++ the statements must be sorted to compute the statement label
++ the problem is if the scop is reordered, the second transformed scop
++ must be "aligned" with it (the first statement need to corresponds to the first
++ statement of the second scop, but the scattering could be different)
++
++ Functions of clay, which could return a non ordered scop :
++ (they create new statements)
++ iss, unroll, peel
++
++- in pip_has_rational_point:
++ -> FIXME (dependence.c:2243)
++
++- autocorrect not implemented yet
++
++- compilation warning with gmp :
++ /usr/bin/ld: warning: libgmp.so.3, needed by /home/jpoudroux/usr/lib/libosl.so, may conflict with libgmp.so.10
++
++- autoreconf error in the piplib module
++ -> piplib must be installed in /
++
++ or execute these commands :
++ $ cd piplib
++ $ echo "AM_PROG_CC_C_O" >>configure.in
++ $ touch NEWS AUTHORS ChangeLog
++ $ cd ..
++ $ ./redo.sh
++
++ If you want to set piplib as "bundled", uncomment these lines in the
++ configure.ac :
++ 295: if test $with_piplib = bundled; then
++ 296: AC_CONFIG_SUBDIRS(piplib)
++ 297: fi
++
+diff --git a/autoconf/.gitignore b/autoconf/.gitignore
+new file mode 100644
+index 0000000..e69de29
+diff --git a/autoconf/candl.m4 b/autoconf/candl.m4
+deleted file mode 100644
+index 2d1347e..0000000
+--- a/autoconf/candl.m4
++++ /dev/null
+@@ -1,81 +0,0 @@
+-AC_DEFUN([CANDL_ARG_LIBS_DEPENDENCIES],
+-[
+-dnl Add $prefix to the library path (convenience).
+- if test -e ${prefix}/include; then
+- CPPFLAGS="${CPPFLAGS} -I${prefix}/include"
+- fi;
+- if test -e ${prefix}/lib; then
+- LDFLAGS="${LDFLAGS} -L${prefix}/lib"
+- fi;
+-dnl Offer --with-piplib.
+- AC_ARG_WITH(piplib,
+- AC_HELP_STRING([--with-piplib=DIR],
+- [DIR Location of PIPLib package]),
+- [with_piplib=$withval;
+- CPPFLAGS="${CPPFLAGS} -I$withval/include";
+- LDFLAGS="${LDFLAGS} -L$withval/lib"
+- ],
+- [with_piplib=yes])
+-dnl Check for piplib existence.
+- AS_IF([test "x$with_piplib" != xno],
+- [AC_SEARCH_LIBS([pip_solve], [piplib$BITS],
+- [LIBS="-lpiplib$BITS $LIBS";
+- AC_DEFINE([HAVE_LIBPIPLIB], [1], [Define if you have libpiplib$BITS])
+- ],
+- [if test "x$with_piplib" != xcheck; then
+- AC_MSG_FAILURE([--with-piplib was given, but test for piplib failed])
+- fi
+- ])
+- ])
+-dnl Offer --with-scoplib.
+- AC_ARG_WITH(scoplib,
+- AC_HELP_STRING([--with-scoplib=DIR],
+- [DIR Location of ScopLib package]),
+- [with_scoplib=$withval;
+- CPPFLAGS="${CPPFLAGS} -I$withval/include";
+- LDFLAGS="${LDFLAGS} -L$withval/lib"
+- ],
+- [with_scoplib=check])
+-dnl Check for scoplib existence.
+- AS_IF([test "x$with_scoplib" != xno],
+- [AC_SEARCH_LIBS([scoplib_scop_read], [scoplib],
+- [LIBS="-lscoplib $LIBS";
+- DEFINE_HAS_SCOPLIB_LIB="# define CANDL_SUPPORTS_SCOPLIB"
+- ],
+- [DEFINE_HAS_SCOPLIB_LIB=""
+- if test "x$with_scoplib" != xcheck; then
+- AC_MSG_FAILURE([Test for ScopLib failed. Use --with-scoplib to specify libscoplib path.])
+- fi
+- ])
+- ])
+-dnl Offer --with-gmp-prefix.
+- AC_ARG_WITH(gmp-prefix,
+- AC_HELP_STRING([--with-gmp-prefix=DIR],
+- [DIR Location of GMP package (only headers are needed)]),
+- [CPPFLAGS="${CPPFLAGS} -I$withval/include";
+- LDFLAGS="${LDFLAGS} -L$withval/lib";
+- ])
+-dnl Offer --with-isl.
+- AC_ARG_WITH(isl,
+- AC_HELP_STRING([--with-isl=DIR],
+- [DIR Location of Isl package]),
+- [with_isl=$withval;
+- CPPFLAGS="${CPPFLAGS} -I$withval/include";
+- LDFLAGS="${LDFLAGS} -L$withval/lib"
+- ],
+- [with_isl=check])
+-dnl Check for isl existence.
+- AS_IF([test "x$with_isl" != xno],
+- [AC_SEARCH_LIBS([isl_version], [isl],
+- [LIBS="-lisl $LIBS";
+- DEFINE_HAS_ISL_LIB="# define CANDL_SUPPORTS_ISL"
+- ],
+- [DEFINE_HAS_ISL_LIB=""
+- if test "x$with_isl" != xcheck; then
+- AC_MSG_FAILURE([Test for Isl failed. Use --with-isl to specify libisl path.])
+- fi
+- ])
+- ])
+-])
+-
+-
+#diff --git a/autogen.sh b/autogen.sh
+#index b67de1f..c27fa40 100755
+#--- a/autogen.sh
+#+++ b/autogen.sh
+#@@ -1,5 +1,8 @@
+#-#! /bin/sh
+#-
+#-aclocal -I autoconf
+#-libtoolize --force --copy
+#-autoreconf -vfi
+#+#!/bin/sh
+#+autoreconf -i
+#+if test -f osl/autogen.sh; then
+#+ (cd osl; ./autogen.sh)
+#+fi
+#+if test -f piplib/autogen.sh; then
+#+ (cd piplib; ./autogen.sh)
+#+fi
+diff --git a/candl-config.cmake b/candl-config.cmake
+new file mode 100644
+index 0000000..c1047d0
+--- /dev/null
++++ b/candl-config.cmake
+@@ -0,0 +1,25 @@
++# Try to find the candl library
++
++# CANDL_FOUND - System has candl lib
++# CANDL_INCLUDE_DIR - The candl include directory
++# CANDL_LIBRARY - Library needed to use candl
++
++
++if (CANDL_INCLUDE_DIR AND CANDL_LIBRARY)
++ # Already in cache, be silent
++ set(CANDL_FIND_QUIETLY TRUE)
++endif()
++
++find_path(CANDL_INCLUDE_DIR NAMES candl/candl.h)
++find_library(CANDL_LIBRARY NAMES candl)
++
++if (CANDL_LIBRARY AND CANDL_INCLUDE_DIR)
++ message(STATUS "Library candl found =) ${CANDL_LIBRARY}")
++else()
++ message(STATUS "Library candl not found =(")
++endif()
++
++include(FindPackageHandleStandardArgs)
++FIND_PACKAGE_HANDLE_STANDARD_ARGS(CANDL DEFAULT_MSG CANDL_INCLUDE_DIR CANDL_LIBRARY)
++
++mark_as_advanced(CANDL_INCLUDE_DIR CANDL_LIBRARY)
+diff --git a/configure.ac b/configure.ac
+new file mode 100644
+index 0000000..03c9ce4
+--- /dev/null
++++ b/configure.ac
+@@ -0,0 +1,320 @@
++dnl /**-------------------------------------------------------------------**
++dnl ** CAnDL **
++dnl **-------------------------------------------------------------------**
++dnl ** configure.in **
++dnl **-------------------------------------------------------------------**
++dnl ** First version: september 8th 2003 **
++dnl **-------------------------------------------------------------------**/
++dnl
++dnl /**************************************************************************
++dnl * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
++dnl ***************************************************************************
++dnl * *
++dnl * Copyright (C) 2003-2008 Cedric Bastoul *
++dnl * *
++dnl * This is free software; you can redistribute it and/or modify it under *
++dnl * the terms of the GNU General Public License as published by the Free *
++dnl * Software Foundation; either version 2 of the License, or (at your *
++dnl * option) any later version. *
++dnl * *
++dnl * This software is distributed in the hope that it will be useful, but *
++dnl * WITHOUT ANY WARRANTY; without even the implied warranty of *
++dnl * MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
++dnl * General Public License for more details. *
++dnl * *
++dnl * You should have received a copy of the GNU General Public License along *
++dnl * with software; if not, write to the Free Software Foundation, Inc., *
++dnl * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++dnl * *
++dnl * CAnDL, the Chunky Dependence Analyser *
++dnl * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++dnl * *
++dnl ***************************************************************************/
++
++m4_define([version_major], [0])
++m4_define([version_minor], [0])
++m4_define([version_revision], [1])
++
++AC_PREREQ(2.53)
++
++dnl Fill here the @bug email adress.
++AC_INIT([candl], [0.6.2], [cedric.bastoul@inria.fr,pouchet@cse.ohio-state.edu])
++
++AC_CONFIG_SRCDIR([include/candl/candl.h])
++
++dnl Put as most as possible configuration files to an auxialiry
++dnl directory.
++AC_CONFIG_AUX_DIR(autoconf)
++AC_CONFIG_MACRO_DIR([m4])
++
++dnl Initialize automake. Here, a special tar version that enables
++dnl (very) long filenames.
++#AM_INIT_AUTOMAKE([1.9 tar-ustar no-define foreign dist-bzip2])
++AM_INIT_AUTOMAKE([foreign])
++m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
++
++dnl default version
++BITS="MP"
++CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP
++
++
++dnl /**************************************************************************
++dnl * Checking *
++dnl **************************************************************************/
++
++
++dnl Checks for programs.
++AC_PROG_CC
++AC_PROG_LN_S
++AC_PROG_MAKE_SET
++AC_CHECK_PROG(CD, cd)
++AC_PROG_INSTALL
++AC_PROG_LIBTOOL
++AC_CHECK_PROGS(DOXYGEN,doxygen,doxygen)
++
++AX_CC_MAXOPT
++AC_SUBST(CFLAGS_WARN)
++AX_CFLAGS_WARN_ALL(CFLAGS_WARN)
++
++dnl Checks for typedefs, structures, and compiler characteristics.
++AC_C_CONST
++AC_TYPE_SIZE_T
++
++dnl Checks for header files.
++AC_HEADER_STDC
++AC_CHECK_HEADERS([errno.h stddef.h stdlib.h string.h strings.h unistd.h])
++
++dnl Checks for library functions.
++AC_CHECK_FUNCS(strtol)
++
++
++dnl /**************************************************************************
++dnl * Option setting *
++dnl **************************************************************************/
++
++dnl /**************************************************************************
++dnl * Where is the OpenScop Library? *
++dnl **************************************************************************/
++
++AX_SUBMODULE(osl,system|build|bundled,system)
++
++AC_SUBST(OSL_CPPFLAGS)
++AC_SUBST(OSL_LDFLAGS)
++AC_SUBST(OSL_LIBS)
++case "$with_osl" in
++bundled)
++ OSL_CPPFLAGS="-I$srcdir/osl/include -Iosl/include"
++ OSL_LIBS="$srcdir/osl/libosl.la"
++ ;;
++build)
++ OSL_CPPFLAGS="-I$osl_srcdir/include -I$with_osl_builddir/include"
++ OSL_LIBS="$with_osl_builddir/libosl.la"
++ ;;
++system)
++ if test "x$with_osl_prefix" != "x"; then
++ OSL_CPPFLAGS="-I$with_osl_prefix/include"
++ fi
++ if test "x$with_osl_exec_prefix" != "x"; then
++ OSL_LDFLAGS="-L$with_osl_exec_prefix/lib"
++ fi
++ OSL_LIBS="$with_osl_prefix/lib/libosl.la -losl"
++esac
++AM_CONDITIONAL(BUNDLED_OSL, test $with_osl = bundled)
++
++
++
++dnl GMP
++
++dnl Some default values cause I'm not sure whether autoconf set them, while
++dnl documentation says it does...
++gmp_package="yes"
++gmp_include_package="yes"
++gmp_library_package="yes"
++
++NEED_MP="no"
++
++dnl --with-gmp=gmp-path
++AC_ARG_WITH(gmp,
++ [ --with-gmp=DIR DIR where the gmp package is installed],
++ [ echo "Package gmp : $withval" &&
++ gmp_package=$withval &&
++ GMP_INC=$gmp_package/include &&
++ GMP_LIB=$gmp_package/lib &&
++ CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
++ NEED_MP="yes"])
++
++AC_ARG_WITH(gmp-include,
++ [ --with-gmp-include=DIR DIR where gmp.h is installed],
++ [ echo "Package gmp-include : $withval" &&
++ gmp_include_package=$withval &&
++ GMP_INC=$gmp_include_package &&
++ CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
++ NEED_MP="yes"])
++
++AC_ARG_WITH(gmp-library,
++ [ --with-gmp-library=DIR DIR where the gmp library is installed],
++ [ echo "Package gmp-library : $withval" &&
++ gmp_library_package=$withval &&
++ GMP_LIB=$gmp_library_package &&
++ CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
++ NEED_MP="yes"])
++
++AC_ARG_ENABLE(int-version,
++ [ --enable-int-version 'int' (32 bits) version is built],
++ [ echo "Package int : $enableval" &&
++ BITS="32" &&
++ CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_LONG])
++
++AC_ARG_ENABLE(llint-version,
++ [ --enable-llint-version 'long long int' (64 bits) version is built],
++ [ echo "Package long long int : $enableval" &&
++ BITS="64" &&
++ CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_LONGLONG])
++
++AC_ARG_ENABLE(mp-version,
++ [ --enable-mp-version 'MP' (multiple precision) version is built],
++ [ echo "Package mp : $enableval" &&
++ BITS="MP" &&
++ CPPFLAGS=-DCANDL_LINEAR_VALUE_IS_MP &&
++ NEED_MP="yes"])
++
++AC_ARG_ENABLE(piplib-hybrid,
++ [ --enable-piplib-hybrid Link with piplib-hybrid],
++ [ echo "Piplib-hybrid support : $enableval" &&
++ if test "x$enableval" = "xyes"; then
++ CPPFLAGS=-DCANDL_HAS_PIPLIB_HYBRID
++ fi])
++
++
++dnl /**************************************************************************
++dnl * Where is the PipLib Library? *
++dnl **************************************************************************/
++
++AX_SUBMODULE(piplib,system|build|bundled,system)
++
++AC_SUBST(PIPLIB_CPPFLAGS)
++AC_SUBST(PIPLIB_LDFLAGS)
++AC_SUBST(PIPLIB_LIBS)
++case "$with_piplib" in
++bundled)
++ PIPLIB_CPPFLAGS="-I$srcdir/piplib/include -Ipiplib/include"
++ PIPLIB_LIBS="$srcdir/piplib/libpiplib$BITS.la"
++ ;;
++build)
++ PIPLIB_CPPFLAGS="-I$piplib_srcdir/include -I$with_piplib_builddir/include"
++ PIPLIB_LIBS="$with_piplib_builddir/libpiplib$BITS.la"
++ ;;
++system)
++ if test "x$with_piplib_prefix" != "x"; then
++ PIPLIB_CPPFLAGS="-I$with_piplib_prefix/include"
++ fi
++ if test "x$with_piplib_exec_prefix" != "x"; then
++ PIPLIB_LDFLAGS="-L$with_piplib_exec_prefix/lib"
++ fi
++ PIPLIB_LIBS="$with_piplib_prefix/lib/libpiplib$BITS.la -lpiplib$BITS"
++esac
++AM_CONDITIONAL(BUNDLED_PIPLIB, test $with_piplib = bundled)
++
++
++
++dnl /**************************************************************************
++dnl * Where is GMP? *
++dnl **************************************************************************/
++
++
++dnl Checking for gmp
++AC_MSG_CHECKING(whether gmp works)
++if test "$gmp_package" = "no"; then
++ echo "GMP package not defined"
++ AC_MSG_RESULT(no)
++ TO_BUILD_MP=""
++else
++ if test "$NEED_MP" = "no"; then
++ echo "Mode normal GMP"
++ TO_BUILD="$TO_BUILD MP"
++ AC_CHECK_HEADER(gmp.h,
++ [AC_SEARCH_LIBS([__gmpz_init], [gmp],
++ [LIBS="$LIBS -lgmp"],
++ [echo "Can't find gmp library." &&
++ echo "MP version will not be built." &&
++ TO_BUILD_MP=""])],
++ [echo "Can't find gmp headers." &&
++ echo "MP version will not be built." &&
++ TO_BUILD_MP=""])
++ else
++ dnl Default given by --with-X is "yes", --without-X is "no". We also
++ dnl initialized manually all gmp_package* variables to "yes" (thus they are
++ dnl supposed to be "yes" except if the user set them himself).
++ if test "$gmp_package" != "yes" ; then
++ echo "(GMP path has been set by user)"
++ GMP_DIR=$gmp_package
++ dnl Useful for AC_CHECK_X to find what we want.
++ CPPFLAGS="-I$GMP_DIR/include $CPPFLAGS"
++ LDFLAGS="-L$GMP_DIR/lib $LDFLAGS"
++ fi
++
++ if test "$gmp_include_package" != "yes" ; then
++ CPPFLAGS="-I$GMP_INC $CPPFLAGS"
++ fi
++
++ if test "$gmp_library_package" != "yes" ; then
++ LDFLAGS="-L$GMP_LIB $LDFLAGS"
++ fi
++
++ AC_CHECK_HEADER(gmp.h,
++ [],
++ [AC_MSG_ERROR(Can't find gmp headers.)])
++ AC_SEARCH_LIBS([__gmpz_init], [gmp],
++ [LIBS="$LIBS -lgmp"],
++ [AC_MSG_ERROR(Can't find gmp library.)])
++
++ AC_MSG_RESULT(yes)
++ fi
++fi
++
++dnl /**************************************************************************
++dnl * Substitutions *
++dnl **************************************************************************/
++
++
++dnl Substitutions to do.
++AC_SUBST(BITS)
++AC_SUBST(DEFINE_HAS_ISL_LIB)
++AC_SUBST(ac_aux_dir)
++AC_SUBST(abs_top_srcdir)
++
++
++dnl Configure Makefiles.
++AC_CONFIG_FILES([
++ Makefile
++ doc/Makefile
++ doc/Doxyfile
++ include/candl/macros.h
++ include/candl/piplib.h
++ tests/Makefile
++ ],
++ [test -z "$CONFIG_HEADERS" || echo timestamp > source/stamp-h.in])
++
++#if test $with_piplib = system; then
++# AC_CONFIG_SUBDIRS(piplib)
++#fi
++if test $with_osl = bundled; then
++ AC_CONFIG_SUBDIRS(osl)
++fi
++
++dnl forcing candl to use local libcandl.la
++dnl if --prefix is not specified
++CANDL_LIBS="$srcdir/libcandl.la -lcandl"
++AC_SUBST(CANDL_LIBS)
++
++
++
++AC_OUTPUT
++
++echo " /*-----------------------------------------------*"
++echo " * Candl configuration is OK *"
++echo " *-----------------------------------------------*/"
++echo "It appears that your system is OK to start Candl compilation. You need"
++echo "now to type \"make\". Lastly type \"make install\" to install Candl on"
++echo "your system (log as root if necessary)."
++
+diff --git a/configure.in b/configure.in
+deleted file mode 100644
+index f6cf7ad..0000000
+--- a/configure.in
++++ /dev/null
+@@ -1,233 +0,0 @@
+-dnl /**-------------------------------------------------------------------**
+-dnl ** CAnDL **
+-dnl **-------------------------------------------------------------------**
+-dnl ** configure.in **
+-dnl **-------------------------------------------------------------------**
+-dnl ** First version: september 8th 2003 **
+-dnl **-------------------------------------------------------------------**/
+-dnl
+-dnl /**************************************************************************
+-dnl * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
+-dnl ***************************************************************************
+-dnl * *
+-dnl * Copyright (C) 2003-2008 Cedric Bastoul *
+-dnl * *
+-dnl * This is free software; you can redistribute it and/or modify it under *
+-dnl * the terms of the GNU General Public License as published by the Free *
+-dnl * Software Foundation; either version 2 of the License, or (at your *
+-dnl * option) any later version. *
+-dnl * *
+-dnl * This software is distributed in the hope that it will be useful, but *
+-dnl * WITHOUT ANY WARRANTY; without even the implied warranty of *
+-dnl * MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+-dnl * General Public License for more details. *
+-dnl * *
+-dnl * You should have received a copy of the GNU General Public License along *
+-dnl * with software; if not, write to the Free Software Foundation, Inc., *
+-dnl * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+-dnl * *
+-dnl * CAnDL, the Chunky Dependence Analyser *
+-dnl * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+-dnl * *
+-dnl ***************************************************************************/
+-
+-
+-AC_PREREQ(2.13)
+-dnl Fill here the @bug email adress.
+-AC_INIT([candl], [0.6.2], [cedric.bastoul@inria.fr,pouchet@cse.ohio-state.edu])
+-dnl A common file, which serve as a test.
+-AC_CONFIG_SRCDIR([include/candl/program.h])
+-dnl Put as most as possible configuration files to an auxialiry
+-dnl directory.
+-AC_CONFIG_AUX_DIR([autoconf])
+-dnl Initialize automake. Here, a special tar version that enables
+-dnl (very) long filenames.
+-AM_INIT_AUTOMAKE([1.9 tar-ustar no-define foreign dist-bzip2])
+-
+-
+-dnl default version
+-BITS="64"
+-CPPFLAGS=-DLINEAR_VALUE_IS_LONGLONG
+-
+-
+-dnl /**************************************************************************
+-dnl * Checking *
+-dnl **************************************************************************/
+-
+-
+-dnl Checks for programs.
+-AC_PROG_CC
+-AC_PROG_LN_S
+-AC_PROG_MAKE_SET
+-AC_CHECK_PROG(CD, cd)
+-AC_PROG_LIBTOOL
+-AC_CHECK_PROGS(DOXYGEN,doxygen,doxygen)
+-
+-dnl Checks for typedefs, structures, and compiler characteristics.
+-AC_C_CONST
+-AC_TYPE_SIZE_T
+-
+-dnl Checks for header files.
+-AC_HEADER_STDC
+-AC_CHECK_HEADERS([errno.h stddef.h stdlib.h string.h strings.h unistd.h])
+-
+-dnl Checks for library functions.
+-AC_CHECK_FUNCS(strtol)
+-
+-
+-dnl /**************************************************************************
+-dnl * Option setting *
+-dnl **************************************************************************/
+-
+-dnl Some default values cause I'm not sure whether autoconf set them, while
+-dnl documentation says it does...
+-gmp_package="yes"
+-gmp_include_package="yes"
+-gmp_library_package="yes"
+-
+-NEED_MP="no"
+-
+-dnl --with-gmp=gmp-path
+-AC_ARG_WITH(gmp,
+- [ --with-gmp=DIR DIR where the gmp package is installed],
+- [ echo "Package gmp : $withval" &&
+- gmp_package=$withval &&
+- GMP_INC=$gmp_package/include &&
+- GMP_LIB=$gmp_package/lib &&
+- CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
+- NEED_MP="yes"])
+-
+-AC_ARG_WITH(gmp-include,
+- [ --with-gmp-include=DIR DIR where gmp.h is installed],
+- [ echo "Package gmp-include : $withval" &&
+- gmp_include_package=$withval &&
+- GMP_INC=$gmp_include_package &&
+- CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
+- NEED_MP="yes"])
+-
+-AC_ARG_WITH(gmp-library,
+- [ --with-gmp-library=DIR DIR where the gmp library is installed],
+- [ echo "Package gmp-library : $withval" &&
+- gmp_library_package=$withval &&
+- GMP_LIB=$gmp_library_package &&
+- CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
+- NEED_MP="yes"])
+-
+-AC_ARG_ENABLE(int-version,
+- [ --enable-int-version 'int' (32 bits) version is built],
+- [ echo "Package int : $enableval" &&
+- BITS="32" &&
+- CPPFLAGS=-DLINEAR_VALUE_IS_LONG])
+-
+-AC_ARG_ENABLE(llint-version,
+- [ --enable-llint-version 'long long int' (64 bits) version is built],
+- [ echo "Package long long int : $enableval" &&
+- BITS="64" &&
+- CPPFLAGS=-DLINEAR_VALUE_IS_LONGLONG])
+-
+-AC_ARG_ENABLE(mp-version,
+- [ --enable-mp-version 'MP' (multiple precision) version is built],
+- [ echo "Package mp : $enableval" &&
+- BITS="MP" &&
+- CPPFLAGS=-DLINEAR_VALUE_IS_MP &&
+- NEED_MP="yes"])
+-
+-AC_ARG_ENABLE(piplib-hybrid,
+- [ --enable-piplib-hybrid Link with piplib-hybrid],
+- [ echo "Piplib-hybrid support : $enableval" &&
+- if test "x$enableval" = "xyes"; then
+- CPPFLAGS=-DCANDL_HAS_PIPLIB_HYBRID
+- fi])
+-
+-
+-dnl /**************************************************************************
+-dnl * Where is GMP? *
+-dnl **************************************************************************/
+-
+-
+-dnl Checking for gmp
+-AC_MSG_CHECKING(whether gmp works)
+-if test "$gmp_package" = "no"; then
+- echo "GMP package not defined"
+- AC_MSG_RESULT(no)
+- TO_BUILD_MP=""
+-else
+- if test "$NEED_MP" = "no"; then
+- echo "Mode normal GMP"
+- TO_BUILD="$TO_BUILD MP"
+- AC_CHECK_HEADER(gmp.h,
+- [AC_SEARCH_LIBS([__gmpz_init], [gmp],
+- [LIBS="$LIBS -lgmp"],
+- [echo "Can't find gmp library." &&
+- echo "MP version will not be built." &&
+- TO_BUILD_MP=""])],
+- [echo "Can't find gmp headers." &&
+- echo "MP version will not be built." &&
+- TO_BUILD_MP=""])
+- else
+- dnl Default given by --with-X is "yes", --without-X is "no". We also
+- dnl initialized manually all gmp_package* variables to "yes" (thus they are
+- dnl supposed to be "yes" except if the user set them himself).
+-
+- if test "$gmp_package" != "yes" ; then
+- echo "(GMP path has been set by user)"
+- GMP_DIR=$gmp_package
+- dnl Useful for AC_CHECK_X to find what we want.
+- CPPFLAGS="-I$GMP_DIR/include $CPPFLAGS"
+- LDFLAGS="-L$GMP_DIR/lib $LDFLAGS"
+- fi
+-
+- if test "$gmp_include_package" != "yes" ; then
+- CPPFLAGS="-I$GMP_INC $CPPFLAGS"
+- fi
+-
+- if test "$gmp_library_package" != "yes" ; then
+- LDFLAGS="-L$GMP_LIB $LDFLAGS"
+- fi
+-
+- AC_CHECK_HEADER(gmp.h,
+- [],
+- [AC_MSG_ERROR(Can't find gmp headers.)])
+- AC_SEARCH_LIBS([__gmpz_init], [gmp],
+- [LIBS="$LIBS -lgmp"],
+- [AC_MSG_ERROR(Can't find gmp library.)])
+-
+- AC_MSG_RESULT(yes)
+- fi
+-fi
+-
+-CANDL_ARG_LIBS_DEPENDENCIES
+-
+-
+-
+-dnl /**************************************************************************
+-dnl * Substitutions *
+-dnl **************************************************************************/
+-
+-
+-dnl Substitutions to do.
+-AC_SUBST(BITS)
+-AC_SUBST(DEFINE_HAS_SCOPLIB_LIB)
+-AC_SUBST(DEFINE_HAS_ISL_LIB)
+-AC_SUBST(ac_aux_dir)
+-
+-dnl Configure Makefiles.
+-AC_CONFIG_FILES([
+- Makefile
+- doc/Makefile
+- doc/Doxyfile
+- include/Makefile
+- include/candl/candl.h
+- source/Makefile
+- tests/Makefile
+- ],
+- [test -z "$CONFIG_HEADERS" || echo timestamp > source/stamp-h.in])
+-
+-AC_OUTPUT
+-
+-echo " /*-----------------------------------------------*"
+-echo " * Candl configuration is OK *"
+-echo " *-----------------------------------------------*/"
+-echo "It appears that your system is OK to start Candl compilation. You need"
+-echo "now to type \"make\". Lastly type \"make install\" to install Candl on"
+-echo "your system (log as root if necessary)."
+diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
+index e172bda..510d8f1 100644
+--- a/doc/Doxyfile.in
++++ b/doc/Doxyfile.in
+@@ -478,7 +478,8 @@ WARN_LOGFILE =
+ # with spaces.
+
+ INPUT = @top_srcdir@/source \
+- @top_srcdir@/include/candl
++ @top_srcdir@/include/candl \
++ include/candl/macros.h
+
+ # This tag can be used to specify the character encoding of the source files that
+ # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
+diff --git a/get_submodules.sh b/get_submodules.sh
+new file mode 100755
+index 0000000..94842b6
+--- /dev/null
++++ b/get_submodules.sh
+@@ -0,0 +1,9 @@
++#!/bin/bash
++git submodule init
++git submodule update
++if test -f osl/autogen.sh; then
++ (cd osl; ./autogen.sh && ./configure)
++fi
++if test -f piplib/autogen.sh; then
++ (cd piplib; ./autogen.sh && ./configure)
++fi
+diff --git a/include/Makefile.am b/include/Makefile.am
+deleted file mode 100644
+index ed48dcd..0000000
+--- a/include/Makefile.am
++++ /dev/null
+@@ -1,54 +0,0 @@
+-#
+-# /**-------------------------------------------------------------------**
+-# ** CAnDL **
+-# **-------------------------------------------------------------------**
+-# ** Makefile.am **
+-# **-------------------------------------------------------------------**
+-# ** First version: september 8th 2003 **
+-# **-------------------------------------------------------------------**/
+-#
+-#/*****************************************************************************
+-# * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
+-# *****************************************************************************
+-# * *
+-# * Copyright (C) 2003-2008 Cedric Bastoul *
+-# * *
+-# * This is free software; you can redistribute it and/or modify it under the *
+-# * terms of the GNU General Public License as published by the Free Software *
+-# * Foundation; either version 2 of the License, or (at your option) any *
+-# * later version. *
+-# * *
+-# * This software is distributed in the hope that it will be useful, but *
+-# * WITHOUT ANY WARRANTY; without even the implied warranty of *
+-# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
+-# * Public License for more details. *
+-# * *
+-# * You should have received a copy of the GNU General Public License along *
+-# * with software; if not, write to the Free Software Foundation, Inc., *
+-# * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+-# * *
+-# * CAnDL, the Chunky Dependence Analyser *
+-# * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+-# * *
+-# *****************************************************************************/
+-
+-
+-#############################################################################
+-SUBDIRS =
+-
+-#############################################################################
+-MAINTAINERCLEANFILES = Makefile.in
+-
+-#############################################################################
+-
+-pkginclude_HEADERS = \
+- candl/candl.h \
+- candl/dependence.h \
+- candl/ddv.h \
+- candl/matrix.h \
+- candl/options.h \
+- candl/piplib-wrapper.h \
+- candl/program.h \
+- candl/pruning.h \
+- candl/statement.h \
+- candl/violation.h
+diff --git a/include/candl/candl.h b/include/candl/candl.h
+new file mode 100644
+index 0000000..926511f
+--- /dev/null
++++ b/include/candl/candl.h
+@@ -0,0 +1,50 @@
++
++ /**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( candl.h **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: september 8th 2003 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
++ ******** | | *************************************************************
++ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
++ ******************************************************************************
++ * *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
++ * *
++ * This is free software; you can redistribute it and/or modify it under the *
++ * terms of the GNU Lesser General Public License as published by the Free *
++ * Software Foundation; either version 3 of the License, or (at your option) *
++ * any later version. *
++ * *
++ * This software is distributed in the hope that it will be useful, but *
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
++ * for more details. *
++ * *
++ * You should have received a copy of the GNU Lesser General Public License *
++ * along with software; if not, write to the Free Software Foundation, Inc., *
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++ * *
++ * CAnDL, the Chunky Dependence Analyser *
++ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++ * *
++ ******************************************************************************/
++
++#ifndef CANDL_H
++#define CANDL_H
++
++# include <candl/ddv.h>
++# include <candl/dependence.h>
++# include <candl/macros.h>
++# include <candl/matrix.h>
++# include <candl/options.h>
++# include <candl/piplib-wrapper.h>
++# include <candl/scop.h>
++# include <candl/statement.h>
++# include <candl/util.h>
++# include <candl/violation.h>
++
++#endif
+diff --git a/include/candl/candl.h.in b/include/candl/candl.h.in
+deleted file mode 100644
+index 187981e..0000000
+--- a/include/candl/candl.h.in
++++ /dev/null
+@@ -1,160 +0,0 @@
+-
+- /**------ ( ----------------------------------------------------------**
+- ** )\ CAnDL **
+- **----- / ) --------------------------------------------------------**
+- ** ( * ( candl.h **
+- **---- \#/ --------------------------------------------------------**
+- ** .-"#'-. First version: september 8th 2003 **
+- **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
+- ******** | | *************************************************************
+- * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+- ******************************************************************************
+- * *
+- * Copyright (C) 2003-2008 Cedric Bastoul *
+- * *
+- * This is free software; you can redistribute it and/or modify it under the *
+- * terms of the GNU Lesser General Public License as published by the Free *
+- * Software Foundation; either version 3 of the License, or (at your option) *
+- * any later version. *
+- * *
+- * This software is distributed in the hope that it will be useful, but *
+- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
+- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
+- * for more details. *
+- * *
+- * You should have received a copy of the GNU Lesser General Public License *
+- * along with software; if not, write to the Free Software Foundation, Inc., *
+- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+- * *
+- * CAnDL, the Chunky Dependence Analyser *
+- * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+- * *
+- ******************************************************************************/
+-
+-
+-/******************************************************************************
+- * THIS FILE HAS BEEN AUTOMATICALLY GENERATED FROM candl.h.in BY configure *
+- ******************************************************************************/
+-
+-
+-#ifndef CANDL_H
+-# define CANDL_H
+-
+-# define CANDL_RELEASE "@PACKAGE_VERSION@"
+-# define CANDL_VERSION "@BITS@"
+-@DEFINE_HAS_SCOPLIB_LIB@
+-@DEFINE_HAS_ISL_LIB@
+-
+-
+-# include <piplib/piplib@BITS@.h>
+-# include <candl/options.h>
+-# include <candl/matrix.h>
+-# include <candl/statement.h>
+-# include <candl/program.h>
+-# include <candl/dependence.h>
+-# include <candl/ddv.h>
+-# include <candl/violation.h>
+-# include <candl/pruning.h>
+-
+-# define CANDL_UNSET -1 /* Must be negative (we do use that property).
+- * All other constants have to be different.
+- */
+-
+-# define CANDL_RAW 1
+-# define CANDL_WAR 2
+-# define CANDL_WAW 3
+-# define CANDL_RAR 4
+-# define CANDL_RAW_SCALPRIV 5
+-
+-# define CANDL_ASSIGNMENT 1
+-# define CANDL_P_REDUCTION 2
+-# define CANDL_M_REDUCTION 3
+-# define CANDL_T_REDUCTION 4
+-
+-# define CANDL_EQUAL 1
+-# define CANDL_POSIT 2
+-# define CANDL_LATER 3
+-# define CANDL_NEVER 4
+-
+-# define CANDL_NB_INFOS 3
+-
+-# define CANDL_MAX_STRING 2048
+-# define CANDL_TEMP_OUTPUT "candl.temp"
+-
+-/* Useful macros. */
+-# define CANDL_max(x,y) ((x) > (y)? (x) : (y))
+-# define CANDL_min(x,y) ((x) < (y)? (x) : (y))
+-
+-# define CANDL_FAIL(msg) { fprintf(stderr, "[Candl] " msg "\n"); exit(1); }
+-
+-/******************************************************************************
+- * FORMAT *
+- ******************************************************************************/
+-#if defined(LINEAR_VALUE_IS_LONGLONG)
+-#define CANDL_FMT "%4lld "
+-#elif defined(LINEAR_VALUE_IS_LONG)
+-#define CANDL_FMT "%4ld "
+-#else /* GNUMP */
+-#define CANDL_FMT "%4s"
+-#endif
+-
+-/******************************************************************************
+- * CANDL GMP MACROS *
+- ******************************************************************************/
+-#ifdef LINEAR_VALUE_IS_MP
+-/* Basic Macros */
+-#define CANDL_init(val) (mpz_init((val)))
+-#define CANDL_assign(v1,v2) (mpz_set((v1),(v2)))
+-#define CANDL_set_si(val,i) (mpz_set_si((val),(i)))
+-#define CANDL_get_si(val) (mpz_get_si((val)))
+-#define CANDL_clear(val) (mpz_clear((val)))
+-#define CANDL_print(Dst,fmt,val) { char *str; \
+- str = mpz_get_str(0,10,(val)); \
+- fprintf((Dst),(fmt),str); free(str); \
+- }
+-
+-/* Boolean operators on 'Value' or 'Entier' */
+-#define CANDL_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
+-#define CANDL_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
+-
+-/* Binary operators on 'Value' or 'Entier' */
+-#define CANDL_increment(ref,val) (mpz_add_ui((ref),(val),1))
+-#define CANDL_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
+-#define CANDL_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
+-#define CANDL_oppose(ref,val) (mpz_neg((ref),(val)))
+-
+-/* Conditional operations on 'Value' or 'Entier' */
+-#define CANDL_zero_p(val) (mpz_sgn(val) == 0)
+-#define CANDL_notzero_p(val) (mpz_sgn(val) != 0)
+-
+-/******************************************************************************
+- * CANDL BASIC TYPES MACROS *
+- ******************************************************************************/
+-#else
+-/* Basic Macros */
+-#define CANDL_init(val) ((val) = 0)
+-#define CANDL_assign(v1,v2) ((v1) = (v2))
+-#define CANDL_set_si(val,i) ((val) = (Entier)(i))
+-#define CANDL_get_si(val) ((val))
+-#define CANDL_clear(val) ((val) = 0)
+-#define CANDL_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
+-
+-/* Boolean operators on 'Value' or 'Entier' */
+-#define CANDL_eq(v1,v2) ((v1)==(v2))
+-#define CANDL_ne(v1,v2) ((v1)!=(v2))
+-
+-/* Binary operators on 'Value' or 'Entier' */
+-#define CANDL_increment(ref,val) ((ref) = (val)+(Entier)(1))
+-#define CANDL_decrement(ref,val) ((ref) = (val)-(Entier)(1))
+-#define CANDL_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
+-#define CANDL_oppose(ref,val) ((ref) = (-(val)))
+-
+-/* Conditional operations on 'Value' or 'Entier' */
+-#define CANDL_zero_p(val) CANDL_eq(val,0)
+-#define CANDL_notzero_p(val) CANDL_ne(val,0)
+-
+-#endif
+-
+-#endif // !CANDL_H
+diff --git a/include/candl/ddv.h b/include/candl/ddv.h
+index bbc97db..8ae9a61 100644
+--- a/include/candl/ddv.h
++++ b/include/candl/ddv.h
+@@ -38,26 +38,18 @@
+ * \author Louis-Noel Pouchet
+ */
+
+-
+ #ifndef CANDL_DDV_H
+ # define CANDL_DDV_H
+
+-
+ # include <stdio.h>
+-# include <candl/statement.h>
+-# include <candl/matrix.h>
+-# include <candl/program.h>
+-# include <candl/options.h>
+-# include <candl/dependence.h>
+-
+-
+
+ # if defined(__cplusplus)
+ extern "C"
+ {
+ # endif
+
+-
++struct osl_scop;
++struct osl_dependence;
+
+ /******************************************************************************
+ * Dependence Distance structures *
+@@ -112,9 +104,6 @@ extern "C"
+
+ typedef struct candl_ddv CandlDDV;
+
+-
+-
+-
+ /******************************************************************************
+ * Memory deallocation function *
+ ******************************************************************************/
+@@ -127,7 +116,6 @@ extern "C"
+ CandlDDV*
+ candl_ddv_malloc();
+
+-
+ /**
+ * candl_ddv_alloc: Allocate a ddv for a loop of depth 'size'.
+ *
+@@ -136,7 +124,6 @@ candl_ddv_malloc();
+ CandlDDV*
+ candl_ddv_alloc(int);
+
+-
+ /**
+ * candl_ddv_free: Free a ddv.
+ *
+@@ -145,7 +132,6 @@ candl_ddv_alloc(int);
+ void
+ candl_ddv_free(CandlDDV*);
+
+-
+ /**
+ * candl_ddv_set_type_at: Set the type of a ddv component. Type is one of
+ * '=', '>', '<', '*' or 'constant' as defined by the enum e_dv_type.
+@@ -173,12 +159,10 @@ candl_ddv_set_value_at(CandlDDV*, int, int);
+ void
+ candl_ddv_set_deptype(CandlDDV*, int);
+
+-
+ /******************************************************************************
+ * Structure display function *
+ ******************************************************************************/
+
+-
+ /**
+ * candl_ddv_print: print a ddv.
+ *
+@@ -186,7 +170,6 @@ candl_ddv_set_deptype(CandlDDV*, int);
+ void
+ candl_ddv_print(FILE*, CandlDDV*);
+
+-
+ /******************************************************************************
+ * Processing functions *
+ ******************************************************************************/
+@@ -199,7 +182,7 @@ candl_ddv_print(FILE*, CandlDDV*);
+ *
+ */
+ CandlDDV*
+-candl_ddv_extract_in_loop(CandlProgram*, CandlDependence*, int);
++candl_ddv_extract_in_loop(struct osl_scop*, struct osl_dependence*, int);
+
+ /**
+ * candl_loops_are_permutable: output 1 if the 2 loops are permutable.
+@@ -207,10 +190,7 @@ candl_ddv_extract_in_loop(CandlProgram*, CandlDependence*, int);
+ *
+ */
+ int
+-candl_loops_are_permutable(CandlProgram* program, CandlDependence* deps,
+- int loop_id1, int loop_id2);
+-
+-
++candl_loops_are_permutable(struct osl_scop*, struct osl_dependence*, int, int);
+
+ # if defined(__cplusplus)
+ }
+diff --git a/include/candl/dependence.h b/include/candl/dependence.h
+index 0f40e65..9205de4 100644
+--- a/include/candl/dependence.h
++++ b/include/candl/dependence.h
+@@ -33,153 +33,99 @@
+ * *
+ ******************************************************************************/
+
+-
+ #ifndef CANDL_DEPENDENCE_H
+ # define CANDL_DEPENDENCE_H
+
+-
+ # include <stdio.h>
+-# include <candl/statement.h>
+-# include <candl/matrix.h>
+-# include <candl/program.h>
+ # include <candl/options.h>
+
+-
+-
+-# define CANDL_ARRAY_BUFF_SIZE 2048
+-# define CANDL_VAR_UNDEF 1
+-# define CANDL_VAR_IS_DEF 2
+-# define CANDL_VAR_IS_USED 3
+-# define CANDL_VAR_IS_DEF_USED 4
+-
++# define CANDL_ARRAY_BUFF_SIZE 2048
++# define CANDL_VAR_UNDEF 1
++# define CANDL_VAR_IS_DEF 2
++# define CANDL_VAR_IS_USED 3
++# define CANDL_VAR_IS_DEF_USED 4
+
+ # if defined(__cplusplus)
+ extern "C"
+ {
+ # endif
+
+-
+-/**
+- * CandlDependence structure:
+- * this structure contains all the informations about a data dependence, it is
+- * also a node of the linked list of all dependences of the dependence graph.
+- */
+-struct candldependence
+-{ CandlStatement * source; /**< Pointer to source statement. */
+- CandlStatement * target; /**< Pointer to target statement. */
+- int depth; /**< Dependence level. */
+- int type; /**< Dependence type: a dependence from source
+- * to target can be:
+- * - CANDL_UNSET if the dependence type is
+- * still not set,
+- * - CANDL_RAW if source writes M and
+- * target read M (flow-dependence),
+- * - CANDL_WAR if source reads M and
+- * target writes M (anti-dependence),
+- * - CANDL_WAW if source writes M and
+- * target writes M too (output-dependence)
+- * - CANDL_RAR if source reads M and
+- * target reads M too (input-dependence).
+- */
+- int ref_source; /**< Position of source reference. */
+- int ref_target; /**< Position of target reference. */
+- CandlMatrix * domain; /**< Dependence polyhedron. */
+-
+- void* usr; /**< User field, for library users
+- convenience. */
+- struct candldependence * next; /**< Pointer to next dependence */
+-};
+-typedef struct candldependence CandlDependence;
+-typedef struct candldependence candl_dependence_t;
+-typedef struct candldependence * candl_dependence_p;
+-
+-
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-void candl_dependence_print_structure(FILE *, candl_dependence_p, int);
+-void candl_dependence_print(FILE *, candl_dependence_p);
+-void candl_dependence_pprint(FILE *, candl_dependence_p);
+-void candl_dependence_view(candl_dependence_p);
+-# ifdef CANDL_SUPPORTS_SCOPLIB
+-CandlDependence* candl_dependence_read_from_scop(scoplib_scop_p, CandlProgram*);
+-void candl_dependence_update_scop_with_deps(scoplib_scop_p, CandlDependence*);
+-void candl_dependence_print_scop(FILE*, FILE*, CandlDependence*);
+-# endif
++struct osl_relation;
++struct osl_statement;
++struct osl_scop;
++struct osl_dependence;
+
+ #ifdef CANDL_SUPPORTS_ISL
+-CandlDependence* candl_dependence_isl_simplify(CandlDependence*, CandlProgram*);
++struct osl_dependence* candl_dependence_isl_simplify(struct osl_dependence*,
++ struct osl_scop*);
+ # endif
+
+-
+-/******************************************************************************
+- * Memory alloc/dealloc function *
+- ******************************************************************************/
+-candl_dependence_p candl_dependence_malloc();
+-void candl_dependence_free(candl_dependence_p);
+-
++/*+***************************************************************************
++ * Structure display function *
++ *****************************************************************************/
++void candl_dependence_pprint(FILE*, struct osl_dependence*);
++void candl_dependence_view(struct osl_dependence*);
+
+ /******************************************************************************
+ * Processing functions *
+ ******************************************************************************/
+-int candl_dependence_gcd_test(CandlStatement*,
+- CandlStatement*,
+- CandlMatrix*, int);
+-int candl_dependence_check(CandlProgram *,
+- candl_dependence_p,
+- CandlOptions *);
+-candl_dependence_p candl_dependence(CandlProgram *, CandlOptions *);
+-
++int candl_dependence_gcd_test(struct osl_statement*,
++ struct osl_statement*,
++ struct osl_relation*, int);
++int candl_dependence_check(struct osl_scop*,
++ struct osl_dependence*,
++ candl_options_p);
++struct osl_dependence* candl_dependence(struct osl_scop*, candl_options_p);
++void candl_dependence_add_extension(struct osl_scop*,
++ candl_options_p);
++
++/*+***************************************************************************
++ * Memory allocation/deallocation function *
++ *****************************************************************************/
++void candl_dependence_init_fields(struct osl_scop*,
++ struct osl_dependence*);
+
+ /******************************************************************************
+ * Scalar analysis functions *
+ ******************************************************************************/
+-int
+-candl_dependence_var_is_scalar (candl_program_p, int);
+-
+-CandlStatement**
+-candl_dependence_refvar_chain(candl_program_p, CandlStatement*, int, int);
+-
+-int
+-candl_dependence_var_is_ref(CandlStatement*, int);
+-
+-int
+-candl_dependence_check_domain_is_included(CandlStatement*, CandlStatement*,
+- CandlMatrix*, int);
+-
+-int
+-candl_dependence_scalar_is_privatizable_at(candl_program_p, int, int);
+-
+-int
+-candl_dependence_is_loop_carried (candl_program_p, CandlDependence*, int);
+-
+-void
+-candl_dependence_prune_scalar_waw (candl_program_p, CandlOptions*,
+- CandlDependence**);
+-
+-void
+-candl_dependence_prune_with_privatization (candl_program_p, CandlOptions*,
+- CandlDependence**);
+-
+-int
+-candl_dependence_scalar_renaming(candl_program_p, CandlOptions*,
+- CandlDependence**);
+-
+-int
+-candl_dependence_analyze_scalars(candl_program_p, CandlOptions*);
++int candl_dependence_var_is_scalar(struct osl_scop*, int);
++struct osl_statement** candl_dependence_refvar_chain(struct osl_scop*,
++ struct osl_statement*, int, int);
++int candl_dependence_var_is_ref(struct osl_statement*, int);
++int candl_dependence_check_domain_is_included(
++ struct osl_statement*,
++ struct osl_statement*,
++ struct osl_relation*, int);
++int candl_dependence_scalar_is_privatizable_at(
++ struct osl_scop*, int, int);
++int candl_dependence_is_loop_carried(struct osl_scop*,
++ struct osl_dependence*, int);
++void candl_dependence_prune_scalar_waw(struct osl_scop*,
++ candl_options_p,
++ struct osl_dependence**);
++void candl_dependence_prune_with_privatization(
++ struct osl_scop*,
++ candl_options_p,
++ struct osl_dependence**);
++int candl_dependence_scalar_renaming(struct osl_scop*,
++ candl_options_p,
++ struct osl_dependence**);
++int candl_dependence_analyze_scalars(struct osl_scop*,
++ candl_options_p);
+
+ /******************************************************************************
+ * Miscellaneous functions *
+ ******************************************************************************/
+-int
+-candl_num_dependences(CandlDependence *candl_deps);
+-
+-void
+-candl_compute_last_writer (CandlDependence *dep, CandlProgram *prog);
++struct osl_relation* candl_dependence_get_relation_ref_source_in_dep(
++ struct osl_dependence*);
++struct osl_relation* candl_dependence_get_relation_ref_target_in_dep(
++ struct osl_dependence*);
++int candl_num_dependences(struct osl_dependence*);
++void candl_compute_last_writer(struct osl_dependence*,
++ struct osl_scop*);
++struct osl_dependence* candl_dependence_prune_transitively_covered(
++ struct osl_dependence*);
+
+-CandlDependence*
+-candl_dependence_prune_transitively_covered (CandlDependence* deps);
+-
+ # if defined(__cplusplus)
+ }
+ # endif
+diff --git a/include/candl/macros.h.in b/include/candl/macros.h.in
+new file mode 100644
+index 0000000..def4643
+--- /dev/null
++++ b/include/candl/macros.h.in
+@@ -0,0 +1,160 @@
++
++ /**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( candl.h **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: september 8th 2003 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
++ ******** | | *************************************************************
++ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
++ ******************************************************************************
++ * *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
++ * *
++ * This is free software; you can redistribute it and/or modify it under the *
++ * terms of the GNU Lesser General Public License as published by the Free *
++ * Software Foundation; either version 3 of the License, or (at your option) *
++ * any later version. *
++ * *
++ * This software is distributed in the hope that it will be useful, but *
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
++ * for more details. *
++ * *
++ * You should have received a copy of the GNU Lesser General Public License *
++ * along with software; if not, write to the Free Software Foundation, Inc., *
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++ * *
++ * CAnDL, the Chunky Dependence Analyser *
++ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++ * *
++ ******************************************************************************/
++
++
++/******************************************************************************
++ * THIS FILE HAS BEEN AUTOMATICALLY GENERATED FROM macros.h.in BY configure *
++ ******************************************************************************/
++
++#ifndef CANDL_MACROS_H
++# define CANDL_MACROS_H
++
++# define CANDL_EQUAL 1
++# define CANDL_POSIT 2
++# define CANDL_LATER 3
++# define CANDL_NEVER 4
++
++# define CANDL_NB_INFOS 3
++
++# define CANDL_MAX_STRING 2048
++# define CANDL_TEMP_OUTPUT "candl.temp"
++
++# define CANDL_RELEASE "@PACKAGE_VERSION@"
++# define CANDL_VERSION "@BITS@"
++@DEFINE_HAS_ISL_LIB@
++
++/* Useful macros. */
++# define CANDL_max(x,y) ((x) > (y)? (x) : (y))
++# define CANDL_min(x,y) ((x) < (y)? (x) : (y))
++
++# define CANDL_info(msg) \
++ do { \
++ fprintf(stderr,"[Candl] Info: "msg" (%s).\n", __func__); \
++ } while (0)
++
++# define CANDL_warning(msg) \
++ do { \
++ fprintf(stderr,"[Candl] Warning: "msg" (%s).\n", __func__); \
++ } while (0)
++
++# define CANDL_error(msg) \
++ do { \
++ fprintf(stderr,"[Candl] Error: "msg" (%s).\n", __func__); \
++ exit(1); \
++ } while (0)
++
++# define CANDL_malloc(ptr, type, size) \
++ do { \
++ if (((ptr) = (type)malloc(size)) == NULL) \
++ CANDL_error("memory overflow"); \
++ } while (0)
++
++# define CANDL_realloc(ptr, type, size) \
++ do { \
++ if (((ptr) = (type)realloc(ptr, size)) == NULL) \
++ CANDL_error("memory overflow"); \
++ } while (0)
++
++# define CANDL_fail(msg) { fprintf(stderr, "[Candl] " msg "\n"); exit(1); }
++
++/******************************************************************************
++ * FORMAT *
++ ******************************************************************************/
++#if defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++#define CANDL_FMT "%4lld "
++#elif defined(CANDL_LINEAR_VALUE_IS_LONG)
++#define CANDL_FMT "%4ld "
++#else /* GNUMP */
++#define CANDL_FMT "%4s"
++#endif
++
++/******************************************************************************
++ * CANDL GMP MACROS *
++ ******************************************************************************/
++#ifdef CANDL_LINEAR_VALUE_IS_MP
++/* Basic Macros */
++#define CANDL_init(val) (mpz_init((val)))
++#define CANDL_assign(v1,v2) (mpz_set((v1),(v2)))
++#define CANDL_set_si(val,i) (mpz_set_si((val),(i)))
++#define CANDL_get_si(val) (mpz_get_si((val)))
++#define CANDL_clear(val) (mpz_clear((val)))
++#define CANDL_print(Dst,fmt,val) { char *str; \
++ str = mpz_get_str(0,10,(val)); \
++ fprintf((Dst),(fmt),str); free(str); \
++ }
++
++/* Boolean operators on 'Value' or 'Entier' */
++#define CANDL_eq(v1,v2) (mpz_cmp((v1),(v2)) == 0)
++#define CANDL_ne(v1,v2) (mpz_cmp((v1),(v2)) != 0)
++
++/* Binary operators on 'Value' or 'Entier' */
++#define CANDL_increment(ref,val) (mpz_add_ui((ref),(val),1))
++#define CANDL_decrement(ref,val) (mpz_sub_ui((ref),(val),1))
++#define CANDL_subtract(ref,val1,val2) (mpz_sub((ref),(val1),(val2)))
++#define CANDL_oppose(ref,val) (mpz_neg((ref),(val)))
++
++/* Conditional operations on 'Value' or 'Entier' */
++#define CANDL_zero_p(val) (mpz_sgn(val) == 0)
++#define CANDL_notzero_p(val) (mpz_sgn(val) != 0)
++
++/******************************************************************************
++ * CANDL BASIC TYPES MACROS *
++ ******************************************************************************/
++#else
++/* Basic Macros */
++#define CANDL_init(val) ((val) = 0)
++#define CANDL_assign(v1,v2) ((v1) = (v2))
++#define CANDL_set_si(val,i) ((val) = (Entier)(i))
++#define CANDL_get_si(val) ((val))
++#define CANDL_clear(val) ((val) = 0)
++#define CANDL_print(Dst,fmt,val) (fprintf((Dst),(fmt),(val)))
++
++/* Boolean operators on 'Value' or 'Entier' */
++#define CANDL_eq(v1,v2) ((v1)==(v2))
++#define CANDL_ne(v1,v2) ((v1)!=(v2))
++
++/* Binary operators on 'Value' or 'Entier' */
++#define CANDL_increment(ref,val) ((ref) = (val)+(Entier)(1))
++#define CANDL_decrement(ref,val) ((ref) = (val)-(Entier)(1))
++#define CANDL_subtract(ref,val1,val2) ((ref) = (val1)-(val2))
++#define CANDL_oppose(ref,val) ((ref) = (-(val)))
++
++/* Conditional operations on 'Value' or 'Entier' */
++#define CANDL_zero_p(val) CANDL_eq(val,0)
++#define CANDL_notzero_p(val) CANDL_ne(val,0)
++
++#endif
++
++#endif // !CANDL_MACROS_H
+diff --git a/include/candl/matrix.h b/include/candl/matrix.h
+index 7bbc13b..60e525f 100644
+--- a/include/candl/matrix.h
++++ b/include/candl/matrix.h
+@@ -33,92 +33,26 @@
+ * *
+ ******************************************************************************/
+
+-
+ #ifndef CANDL_MATRIX_H
+ # define CANDL_MATRIX_H
+
+-# include <stdio.h>
+-# include <piplib/piplib.h>
+-
+-# ifdef LINEAR_VALUE_IS_LONG
+-# define CLAN_INT_T_IS_LONG
+-# endif
+-# ifdef LINEAR_VALUE_IS_LONGLONG
+-# define CLAN_INT_T_IS_LONGLONG
+-# endif
+-# ifdef LINEAR_VALUE_IS_MP
+-# define CLAN_INT_T_IS_MP
+-# endif
++# include <candl/violation.h>
+
+ # if defined(__cplusplus)
+ extern "C"
+ {
+ # endif
+
++struct osl_relation;
++struct osl_dependence;
+
+-/**
+- * The matrix structure comes directly from PipLib (defined in piplib/piplib.h)
+- * which is directly the PolyLib Matrix (defined in polylib/types.h)
+- * here is how it looks like (at least in PipLib 1.3.5 version):
+- *
+- * struct pipmatrix
+- * { unsigned NbRows; // The number of rows (= NbConstraints in Polyhedron).
+- * unsigned NbColumns; // The number of columns (= Dimension+2 in Polyhedron).
+- * Value **p; // An array of pointers to the beginning of each row.
+- * Value *p_Init; // The matrix is stored here, contiguously in memory.
+- * int p_Init_size; // Needed to free the memory allocated by mpz_init.
+- * } ;
+- * typedef struct pipmatrix PipMatrix ;
+- */
+-
+-typedef PipMatrix CandlMatrix;
+-
+-
+-/**
+- * CandlMatrixList structure:
+- * this structure reprensents a node of a linked list of CandlMatrix structures.
+- */
+-struct candlmatrixlist
+-{ CandlMatrix * matrix; /**< An element of the list. */
+- struct candlmatrixlist * next;/**< Pointer to the next element of the list.*/
+-};
+-typedef struct candlmatrixlist CandlMatrixList;
+-
+-
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-void candl_matrix_print_structure(FILE *, CandlMatrix *, int);
+-void candl_matrix_print(FILE *, CandlMatrix *);
+-void candl_matrix_print_data(FILE *, CandlMatrix *);
+-void candl_matrix_list_print_structure(FILE *, CandlMatrixList *, int);
+-void candl_matrix_list_print(FILE *, CandlMatrixList *);
+-
+-/******************************************************************************
+- * Memory deallocation function *
+- ******************************************************************************/
+-void candl_matrix_free(CandlMatrix *);
+-void candl_matrix_list_free(CandlMatrixList *);
+-
+-
+-/******************************************************************************
+- * Reading functions *
+- ******************************************************************************/
+-CandlMatrix * candl_matrix_read(FILE *);
+-CandlMatrixList * candl_matrix_list_read(FILE *);
+-
+-
+-/******************************************************************************
+- * Processing functions *
+- ******************************************************************************/
+-CandlMatrix * candl_matrix_malloc(int, int);
+-CandlMatrixList * candl_matrix_list_malloc();
+-CandlMatrix * candl_matrix_violation(CandlMatrix *, CandlMatrix *,
+- CandlMatrix *, int, int);
+-int candl_matrix_check_point (CandlMatrix* , CandlMatrix* );
++candl_violation_p candl_matrix_violation(struct osl_dependence*,
++ struct osl_relation*, struct osl_relation*,
++ int, int);
++int candl_matrix_check_point(struct osl_relation*,
++ struct osl_relation*);
+
+ # if defined(__cplusplus)
+ }
+ # endif
+-#endif /* define CANDL_DEPENDENCE_H */
+-
++#endif
+diff --git a/include/candl/options.h b/include/candl/options.h
+index e62fddb..7154cb5 100644
+--- a/include/candl/options.h
++++ b/include/candl/options.h
+@@ -33,7 +33,6 @@
+ * *
+ ******************************************************************************/
+
+-
+ #ifndef CANDL_OPTIONS_H
+ # define CANDL_OPTIONS_H
+
+@@ -44,60 +43,55 @@ extern "C"
+ {
+ # endif
+
+-
+ /**
+- * CandlOptions structure:
++ * candl_options structure:
+ * this structure contains all the informations on the state of Candl options.
+ */
+-struct candloptions
+-{ /* OPTIONS FOR DEPENDENCE COMPUTATION */
++struct candl_options {
++ /* OPTIONS FOR DEPENDENCE COMPUTATION */
+ int waw; /**< 1 if write after write (output) dependences matter. */
+ int raw; /**< 1 if read after write (flow) dependences matter. */
+ int war; /**< 1 if write after read (anti) dependences matter. */
+ int rar; /**< 1 if read after read (input) dependences matter. */
+ int commute; /**< 1 to use commutativity to simplify dependences. */
+ int fullcheck; /**< 1 to compute all dependence violations. */
+- int depgraph; /**< 1 to print the dependence graph. */
+- int violgraph; /**< 1 to print the violation graph. */
+ int scalar_renaming; /**< 1 to enable scalar renaming. */
+ int scalar_privatization; /**< 1 to enable scalar privatization. */
+ int scalar_expansion; /**< 1 to enable scalar privatization. */
+ int lastwriter; /**< 1 to compute last writer */
+- int readscop; /**< 1 to enable reading from a .scop formatted file. */
+- int writescop; /**< 1 to enable writing to a .scop formatted file. */
+- int scoptocandl; /**< 1 to act as a .scop to candl converter. */
+ int verbose; /**< 1 to enable verbose output. */
++ int outscop; /**< 1 to print the scop with dependences. */
++ int autocorrect; /**< 1 to correct violations. fullcheck is set to 1 and
++ * the -test is required.
++ */
+ /* UNDOCUMENTED OPTIONS FOR THE AUTHOR ONLY */
+ int view; /**< 1 to call dot and gv to visualize the graphs. */
+ int structure; /**< 1 to print internal dependence structure. */
+ int prune_dups; /**< 1 to use experimental dependence pruning algorithm. */
+-} ;
+-typedef struct candloptions CandlOptions;
++};
+
++typedef struct candl_options candl_options_t;
++typedef struct candl_options* candl_options_p;
+
+ /******************************************************************************
+ * Structure display function *
+ ******************************************************************************/
+-void candl_options_print(FILE *, CandlOptions *);
+-
++void candl_options_print(FILE *, candl_options_p);
+
+ /******************************************************************************
+ * Memory deallocation function *
+ ******************************************************************************/
+-void candl_options_free(CandlOptions *);
+-
++void candl_options_free(candl_options_p);
+
+ /******************************************************************************
+ * Reading function *
+ ******************************************************************************/
+-void candl_options_read(int, char **, FILE **, FILE **, CandlOptions **);
+-
++void candl_options_read(int, char **, FILE **, FILE **, FILE**, candl_options_p*);
+
+ /******************************************************************************
+ * Processing functions *
+ ******************************************************************************/
+-CandlOptions * candl_options_malloc(void);
+-
++candl_options_p candl_options_malloc(void);
+
+ #if defined(__cplusplus)
+ }
+diff --git a/include/candl/piplib-wrapper.h b/include/candl/piplib-wrapper.h
+index 27576f5..642e366 100644
+--- a/include/candl/piplib-wrapper.h
++++ b/include/candl/piplib-wrapper.h
+@@ -41,23 +41,27 @@
+ #ifndef CANDL_PIPLIB_WRAPPER_H
+ # define CANDL_PIPLIB_WRAPPER_H
+
+-
+-# include <stdio.h>
+-# include <candl/matrix.h>
+-
+-
+-
+ # if defined(__cplusplus)
+ extern "C"
+ {
+ # endif
+-
+
+-int
+-pip_has_rational_point(PipMatrix* system,
+- PipMatrix* context,
+- int conservative);
+-
++struct osl_relation;
++struct pipmatrix;
++struct pipquast;
++struct pipoptions;
++struct piplist;
++
++struct pipmatrix* pip_relation2matrix(struct osl_relation*);
++struct osl_relation* pip_matrix2relation(struct pipmatrix*);
++int pip_has_rational_point(struct osl_relation*,
++ struct osl_relation*, int);
++struct pipquast* pip_solve_osl(struct osl_relation*, struct osl_relation*,
++ int, struct pipoptions*);
++int piplist_are_equal(struct piplist*, struct piplist*, int);
++struct osl_relation* pip_quast_to_polyhedra(struct pipquast*, int, int);
++struct osl_relation* pip_quast_no_solution_to_polyhedra(struct pipquast*,
++ int, int);
+
+ # if defined(__cplusplus)
+ }
+diff --git a/include/candl/piplib.h.in b/include/candl/piplib.h.in
+new file mode 100644
+index 0000000..dfaf33a
+--- /dev/null
++++ b/include/candl/piplib.h.in
+@@ -0,0 +1,51 @@
++
++ /**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( piplib.h **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: August 5th 2014 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
++ ******** | | *************************************************************
++ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
++ ******************************************************************************
++ * *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
++ * *
++ * This is free software; you can redistribute it and/or modify it under the *
++ * terms of the GNU Lesser General Public License as published by the Free *
++ * Software Foundation; either version 3 of the License, or (at your option) *
++ * any later version. *
++ * *
++ * This software is distributed in the hope that it will be useful, but *
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
++ * for more details. *
++ * *
++ * You should have received a copy of the GNU Lesser General Public License *
++ * along with software; if not, write to the Free Software Foundation, Inc., *
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++ * *
++ * CAnDL, the Chunky Dependence Analyzer *
++ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++ * *
++ ******************************************************************************/
++
++
++#ifndef CANDL_PIPLIB_H
++# define CANDL_PIPLIB_H
++
++# if defined(__cplusplus)
++extern "C"
++ {
++# endif
++
++# include <piplib/piplib@BITS@.h>
++
++# if defined(__cplusplus)
++ }
++# endif
++#endif /* define CANDL_PIPLIB_H */
++
+diff --git a/include/candl/program.h b/include/candl/program.h
+deleted file mode 100644
+index 073016a..0000000
+--- a/include/candl/program.h
++++ /dev/null
+@@ -1,113 +0,0 @@
+-
+- /**------ ( ----------------------------------------------------------**
+- ** )\ CAnDL **
+- **----- / ) --------------------------------------------------------**
+- ** ( * ( program.h **
+- **---- \#/ --------------------------------------------------------**
+- ** .-"#'-. First version: september 9th 2003 **
+- **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
+- ******** | | *************************************************************
+- * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+- ******************************************************************************
+- * *
+- * Copyright (C) 2003-2008 Cedric Bastoul *
+- * *
+- * This is free software; you can redistribute it and/or modify it under the *
+- * terms of the GNU General Public License as published by the Free Software *
+- * Foundation; either version 2 of the License, or (at your option) any later *
+- * version. *
+- * *
+- * This software is distributed in the hope that it will be useful, but *
+- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
+- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
+- * for more details. *
+- * *
+- * You should have received a copy of the GNU General Public License along *
+- * with software; if not, write to the Free Software Foundation, Inc., *
+- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+- * *
+- * CAnDL, the Chunky Dependence Analyzer *
+- * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+- * *
+- ******************************************************************************/
+-
+-
+-#ifndef CANDL_PROGRAM_H
+-# define CANDL_PROGRAM_H
+-
+-# include <stdio.h>
+-# include <stdlib.h>
+-# include <candl/matrix.h>
+-# include <candl/statement.h>
+-
+-# ifdef CANDL_SUPPORTS_SCOPLIB
+-# include <scoplib/scop.h>
+-# endif
+-
+-
+-# if defined(__cplusplus)
+-extern "C"
+- {
+-# endif
+-
+-/**
+- * candl_program_t structure:
+- * this structure contains all the informations about a program.
+- */
+-struct candl_program
+-{
+- CandlMatrix * context; /**< The context of the program. */
+- int nb_statements; /**< The number of statements. */
+- CandlStatement ** statement; /**< Array of nb_statements pointers on
+- * the statements of the program.
+- */
+- CandlMatrix ** transformation; /**< Array of nb_statements pointers on
+- * the transformation candidate (one
+- * function per statement). If NULL:
+- * no tranformation candidate.
+- */
+- int* scalars_privatizable;
+-};
+-typedef struct candl_program CandlProgram;
+-typedef struct candl_program candl_program_t;
+-typedef struct candl_program * candl_program_p;
+-
+-
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-void candl_program_print_structure(FILE *, candl_program_p, int);
+-void candl_program_print(FILE *, candl_program_p);
+-void candl_program_print_candl_file(FILE *, candl_program_p);
+-
+-/******************************************************************************
+- * Memory alloc/dealloc function *
+- ******************************************************************************/
+-candl_program_p candl_program_malloc();
+-void candl_program_free(candl_program_p);
+-
+-
+-/******************************************************************************
+- * Reading function *
+- ******************************************************************************/
+-candl_program_p candl_program_read(FILE *);
+-/* This function is compiled if candl was configured with CLAN support. */
+-# ifdef CANDL_SUPPORTS_SCOPLIB
+-candl_program_p candl_program_read_scop(FILE *);
+-# endif
+-
+-/******************************************************************************
+- * Processing functions *
+- ******************************************************************************/
+-/* This function is compiled if candl was configured with CLAN support. */
+-# ifdef CANDL_SUPPORTS_SCOPLIB
+-candl_program_p candl_program_convert_scop(scoplib_scop_p, int**);
+-# endif
+-
+-# if defined(__cplusplus)
+- }
+-# endif
+-#endif /* define CANDL_PROGRAM_H */
+-
+diff --git a/include/candl/pruning.h b/include/candl/pruning.h
+deleted file mode 100644
+index ad75e38..0000000
+--- a/include/candl/pruning.h
++++ /dev/null
+@@ -1,65 +0,0 @@
+-
+- /**------ ( ----------------------------------------------------------**
+- ** )\ CAnDL **
+- **----- / ) --------------------------------------------------------**
+- ** ( * ( pruning.h **
+- **---- \#/ --------------------------------------------------------**
+- ** .-"#'-. First version: July 17th 2011 **
+- **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
+- ******** | | *************************************************************
+- * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+- ******************************************************************************
+- * *
+- * Copyright (C) 2003-2008 Cedric Bastoul *
+- * *
+- * This is free software; you can redistribute it and/or modify it under the *
+- * terms of the GNU General Public License as published by the Free Software *
+- * Foundation; either version 2 of the License, or (at your option) any later *
+- * version. *
+- * *
+- * This software is distributed in the hope that it will be useful, but *
+- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
+- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
+- * for more details. *
+- * *
+- * You should have received a copy of the GNU General Public License along *
+- * with software; if not, write to the Free Software Foundation, Inc., *
+- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+- * *
+- * CAnDL, the Chunky Dependence Analyzer *
+- * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+- * *
+- ******************************************************************************/
+-
+-/**
+- * \file pruning.h
+- * \author Louis-Noel Pouchet
+- */
+-
+-#ifndef CANDL_PRUNING_H
+-# define CANDL_PRUNING_H
+-
+-
+-# include <stdio.h>
+-# include <candl/statement.h>
+-# include <candl/matrix.h>
+-# include <candl/program.h>
+-# include <candl/options.h>
+-# include <candl/matrix.h>
+-
+-
+-# if defined(__cplusplus)
+-extern "C"
+- {
+-# endif
+-
+-CandlDependence*
+-candl_dependence_prune_transitively_covered (CandlDependence* deps);
+-
+-# if defined(__cplusplus)
+- }
+-# endif
+-#endif /* define CANDL_PRUNING_H */
+-
+diff --git a/include/candl/scop.h b/include/candl/scop.h
+new file mode 100644
+index 0000000..ead43ed
+--- /dev/null
++++ b/include/candl/scop.h
+@@ -0,0 +1,66 @@
++
++ /**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( scop.h **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: july 9th 2012 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
++ ******** | | *************************************************************
++ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
++ ******************************************************************************
++ * *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
++ * *
++ * This is free software; you can redistribute it and/or modify it under the *
++ * terms of the GNU General Public License as published by the Free Software *
++ * Foundation; either version 2 of the License, or (at your option) any later *
++ * version. *
++ * *
++ * This software is distributed in the hope that it will be useful, but *
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
++ * for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License along *
++ * with software; if not, write to the Free Software Foundation, Inc., *
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++ * *
++ * CAnDL, the Chunky Dependence Analyzer *
++ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++ * *
++ ******************************************************************************/
++
++/*
++ * author Joel Poudroux
++ */
++
++#ifndef CANDL_SCOP_H
++# define CANDL_SCOP_H
++
++# if defined(__cplusplus)
++extern "C"
++ {
++# endif
++
++struct osl_scop;
++
++struct candl_scop_usr {
++ int size;
++ int *scalars_privatizable;
++ void *usr_backup; /**< If there is already a usr field, it will be saved */
++};
++
++typedef struct candl_scop_usr candl_scop_usr_t;
++typedef struct candl_scop_usr* candl_scop_usr_p;
++
++void candl_scop_usr_init(struct osl_scop*);
++void candl_scop_usr_cleanup(struct osl_scop*);
++
++# if defined(__cplusplus)
++ }
++# endif
++
++#endif
+diff --git a/include/candl/statement.h b/include/candl/statement.h
+index 9e434a4..a26eff6 100644
+--- a/include/candl/statement.h
++++ b/include/candl/statement.h
+@@ -4,7 +4,7 @@
+ **----- / ) --------------------------------------------------------**
+ ** ( * ( statement.h **
+ **---- \#/ --------------------------------------------------------**
+- ** .-"#'-. First version: september 8th 2003 **
++ ** .-"#'-. First version: july 9th 2012 **
+ **--- |"-.-"| -------------------------------------------------------**
+ | |
+ | |
+@@ -33,68 +33,38 @@
+ * *
+ ******************************************************************************/
+
++/*
++ * author Joel Poudroux
++ */
+
+ #ifndef CANDL_STATEMENT_H
+-# define CANDL_STATEMENT_H
+-
+-# include <stdio.h>
+-# include <candl/matrix.h>
++#define CANDL_STATEMENT_H
+
+ # if defined(__cplusplus)
+ extern "C"
+ {
+ # endif
+
++struct osl_scop;
++struct osl_statement;
+
+-/**
+- * CandlStatement structure:
+- * this structure contains all the informations about a program statement.
+- */
+-struct candlstatement
+-{ int label; /**< Statement number (it must be the array
+- * index of this statement in the "statement"
+- * field of the CandlProgram structure).
+- */
+- int type; /**< Statement type. */
+- int depth; /**< Nesting level (nb of surrounding loops).*/
+- int * index; /**< Iteration domain's iterator labels. */
+- CandlMatrix * domain; /**< Iteration domain. */
+- CandlMatrix * written; /**< Array of written data. */
+- CandlMatrix * read; /**< Array of read data. */
+- void* ref; /**< Reference to another structure
+- describing the same statement. */
++struct candl_statement_usr {
++ int label; /**< Statement label = 'n'th statement */
++ int depth;
++ int type;
++ int *index; /**< Loops label name */
++ void *usr_backup; /**< If there is already a usr field, it will be saved */
+ };
+-typedef struct candlstatement CandlStatement;
+-
+
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-void candl_statement_print_structure(FILE *, CandlStatement *, int);
+-void candl_statement_print(FILE *, CandlStatement *);
+-
+-
+-/******************************************************************************
+- * Memory deallocation function *
+- ******************************************************************************/
+-void candl_statement_free(CandlStatement *);
+-
+-
+-/******************************************************************************
+- * Reading functions *
+- ******************************************************************************/
+-CandlStatement * candl_statement_read(FILE *, int, int);
+-
+-
+-/******************************************************************************
+- * Processing functions *
+- ******************************************************************************/
+-CandlStatement * candl_statement_malloc();
+-int candl_statement_commute(CandlStatement *, CandlStatement *);
++typedef struct candl_statement_usr candl_statement_usr_t;
++typedef struct candl_statement_usr* candl_statement_usr_p;
+
++void candl_statement_usr_init_all(struct osl_scop*);
++void candl_statement_usr_cleanup(struct osl_statement*);
+
+ # if defined(__cplusplus)
+ }
+ # endif
+-#endif /* define CANDL_STATEMENT_H */
+
++
++#endif
+diff --git a/include/candl/util.h b/include/candl/util.h
+new file mode 100644
+index 0000000..c20f09b
+--- /dev/null
++++ b/include/candl/util.h
+@@ -0,0 +1,61 @@
++
++ /**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( util.h **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: june 7th 2012 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
++ ******** | | *************************************************************
++ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
++ ******************************************************************************
++ * *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
++ * *
++ * This is free software; you can redistribute it and/or modify it under the *
++ * terms of the GNU General Public License as published by the Free Software *
++ * Foundation; either version 2 of the License, or (at your option) any later *
++ * version. *
++ * *
++ * This software is distributed in the hope that it will be useful, but *
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
++ * for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License along *
++ * with software; if not, write to the Free Software Foundation, Inc., *
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++ * *
++ * CAnDL, the Chunky Dependence Analyzer *
++ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++ * *
++ ******************************************************************************/
++
++/*
++ * author Joel Poudroux
++ */
++
++#ifndef CANDL_UTIL_H
++#define CANDL_UTIL_H
++
++# if defined(__cplusplus)
++extern "C"
++ {
++# endif
++
++struct osl_scop;
++struct osl_relation;
++struct osl_statement;
++
++int candl_util_relation_get_line(struct osl_relation*, int);
++int candl_util_statement_commute(struct osl_statement*, struct osl_statement*);
++int candl_util_check_scop(struct osl_scop*, struct osl_scop*);
++int candl_util_check_scop_list(struct osl_scop*, struct osl_scop*);
++
++# if defined(__cplusplus)
++ }
++# endif
++
++#endif
+diff --git a/include/candl/violation.h b/include/candl/violation.h
+index da09565..f395b63 100644
+--- a/include/candl/violation.h
++++ b/include/candl/violation.h
+@@ -38,52 +38,92 @@
+ # define CANDL_VIOLATION_H
+
+ # include <stdio.h>
+-# include <candl/dependence.h>
+-# include <candl/matrix.h>
++# include <candl/options.h>
+
+ # if defined(__cplusplus)
+ extern "C"
+ {
+ # endif
+
++struct osl_scop;
++struct osl_dependence;
++struct osl_relation;
+
+ /**
+ * CandlViolation structure:
+ * this structure contains all informations about a data dependence violation.
+- */
+-struct candlviolation
+-{ CandlDependence * dependence; /**< Pointer to violated dependence. */
+- int dimension; /**< Violation dimension. */
+- CandlMatrix * domain; /**< Violation polyhedron. */
+- struct candlviolation * next; /**< Pointer to next violation. */
++ *
++
++ Violation domain structure
++ ________________________________________________________________________________________________
++ / source (output) | target (input) | local dims \
++ __ |_______________________|_______________________|___________________________________________________|_____________
++ / eq |output |output |output |output |output |output |ld dom |ld acc |ld scatt |ld dom |ld acc |ld scatt | | \
++ | in |domain |access |scatt |domain |access |scatt |source |source |source |target |target |target |parameters | 1 |
++ _____________________|____|_______|_______|_______|_______|_______|_______|_______|_______|_________|_______|_______|_________|___________|___|
++ |Domain source | X | X : : | : : | X : : | : : | X | X |
++ |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
++ |Domain target | X | : : | X : : | : : | X : : | X | X |
++ |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
++ Dependence |Access source | X | X : X : | : : | : X : | : : | X | X |
++ system |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
++ |Access target | X | : : | X : X : | : : | : X : | X | X |
++ |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
++ |Access equality | | : Id : | : -Id : | : : | : : | | |
++ |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___| | 0 : 0..depth-1
++ |Precedence | X | Id : : | -Id : : | : : | : : | | X | <--| 0|-1 : depth
++ ===============================================================================================================================================
++ |Scattering | | : : | : : | : : | : : | | |
++ |source | X | X : : X | : : | : : X | : : | X | X |
++ |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
++ |Scattering | | : : | : : | : : | : : | | |
++ |target | X | : : | X : : X | : : | : : X | X | X |
++ |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
++ |Equality at | | : : | : : | : : | : : | | |
++ |1 ... dim_1 | | : : Id | : : -Id | : : | : : | | |
++ |________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___|
++ at |Scat source > | | : : | : : | : : | : : | | |
++ dim |Scat target | 1 | : : 1 | : : -1 | : : | : : | |-1 |
++ \________________|____|_______:_______:_______|_______:_______:_______|_______:_______:_________|_______:_______:_________|___________|___/
++
++ (1) (2) (3) (4)
++*/
++
++struct candl_violation {
++ struct osl_dependence* dependence; /**< Pointer to violated dependence. */
++ int dimension; /**< Violation dimension. */
++ struct osl_relation* domain; /**< Violation polyhedron. */
++ struct candl_violation* next; /**< Pointer to next violation. */
++
++ int source_nb_output_dims_scattering; // (1)
++ int target_nb_output_dims_scattering; // (2)
++ int source_nb_local_dims_scattering; // (3)
++ int target_nb_local_dims_scattering; // (4)
+ };
+-typedef struct candlviolation CandlViolation;
+-
++typedef struct candl_violation candl_violation_t;
++typedef struct candl_violation* candl_violation_p;
+
+ /******************************************************************************
+ * Structure display function *
+ ******************************************************************************/
+-void candl_violation_print_structure(FILE *, CandlViolation *, int);
+-void candl_violation_print(FILE *, CandlViolation *);
+-void candl_violation_pprint(FILE *, CandlViolation *);
+-void candl_violation_view(CandlViolation *);
+-
++void candl_violation_idump(FILE*, candl_violation_p, int);
++void candl_violation_dump(FILE*, candl_violation_p);
++void candl_violation_pprint(FILE*, candl_violation_p);
++void candl_violation_view(candl_violation_p);
+
+ /******************************************************************************
+ * Memory deallocation function *
+ ******************************************************************************/
+-void candl_violation_free(CandlViolation *);
+-
++void candl_violation_free(candl_violation_p);
+
+ /******************************************************************************
+ * Processing functions *
+ ******************************************************************************/
+-CandlViolation * candl_violation_malloc();
+-void candl_violation_add(CandlViolation **, CandlViolation **,
+- CandlViolation *);
+-CandlViolation * candl_violation(CandlProgram *, CandlDependence *,
+- CandlOptions *);
+-
++candl_violation_p candl_violation_malloc();
++void candl_violation_add(candl_violation_p*, candl_violation_p*,
++ candl_violation_p);
++candl_violation_p candl_violation(struct osl_scop*, struct osl_dependence*,
++ struct osl_scop*, candl_options_p);
+
+ # if defined(__cplusplus)
+ }
+diff --git a/m4/ax_cc_maxopt.m4 b/m4/ax_cc_maxopt.m4
+new file mode 100644
+index 0000000..da415be
+--- /dev/null
++++ b/m4/ax_cc_maxopt.m4
+@@ -0,0 +1,178 @@
++# ===========================================================================
++# http://www.nongnu.org/autoconf-archive/ax_cc_maxopt.html
++# ===========================================================================
++#
++# SYNOPSIS
++#
++# AX_CC_MAXOPT
++#
++# DESCRIPTION
++#
++# Try to turn on "good" C optimization flags for various compilers and
++# architectures, for some definition of "good". (In our case, good for
++# FFTW and hopefully for other scientific codes. Modify as needed.)
++#
++# The user can override the flags by setting the CFLAGS environment
++# variable. The user can also specify --enable-portable-binary in order to
++# disable any optimization flags that might result in a binary that only
++# runs on the host architecture.
++#
++# Note also that the flags assume that ANSI C aliasing rules are followed
++# by the code (e.g. for gcc's -fstrict-aliasing), and that floating-point
++# computations can be re-ordered as needed.
++#
++# Requires macros: AX_CHECK_COMPILER_FLAGS, AX_COMPILER_VENDOR,
++# AX_GCC_ARCHFLAG, AX_GCC_X86_CPUID.
++#
++# LICENSE
++#
++# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
++# Copyright (c) 2008 Matteo Frigo
++#
++# This program is free software: you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by the
++# Free Software Foundation, either version 3 of the License, or (at your
++# option) any later version.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details.
++#
++# You should have received a copy of the GNU General Public License along
++# with this program. If not, see <http://www.gnu.org/licenses/>.
++#
++# As a special exception, the respective Autoconf Macro's copyright owner
++# gives unlimited permission to copy, distribute and modify the configure
++# scripts that are the output of Autoconf when processing the Macro. You
++# need not follow the terms of the GNU General Public License when using
++# or distributing such scripts, even though portions of the text of the
++# Macro appear in them. The GNU General Public License (GPL) does govern
++# all other use of the material that constitutes the Autoconf Macro.
++#
++# This special exception to the GPL applies to versions of the Autoconf
++# Macro released by the Autoconf Archive. When you make and distribute a
++# modified version of the Autoconf Macro, you may extend this special
++# exception to the GPL to apply to your modified version as well.
++
++AC_DEFUN([AX_CC_MAXOPT],
++[
++AC_REQUIRE([AC_PROG_CC])
++AC_REQUIRE([AX_COMPILER_VENDOR])
++AC_REQUIRE([AC_CANONICAL_HOST])
++
++AC_ARG_ENABLE(portable-binary, [AC_HELP_STRING([--enable-portable-binary], [disable compiler optimizations that would produce unportable binaries])],
++ acx_maxopt_portable=$withval, acx_maxopt_portable=no)
++
++# Try to determine "good" native compiler flags if none specified via CFLAGS
++if test "$ac_test_CFLAGS" != "set"; then
++ CFLAGS=""
++ case $ax_cv_c_compiler_vendor in
++ dec) CFLAGS="-newc -w0 -O5 -ansi_alias -ansi_args -fp_reorder -tune host"
++ if test "x$acx_maxopt_portable" = xno; then
++ CFLAGS="$CFLAGS -arch host"
++ fi;;
++
++ sun) CFLAGS="-native -fast -xO5 -dalign"
++ if test "x$acx_maxopt_portable" = xyes; then
++ CFLAGS="$CFLAGS -xarch=generic"
++ fi;;
++
++ hp) CFLAGS="+Oall +Optrs_ansi +DSnative"
++ if test "x$acx_maxopt_portable" = xyes; then
++ CFLAGS="$CFLAGS +DAportable"
++ fi;;
++
++ ibm) if test "x$acx_maxopt_portable" = xno; then
++ xlc_opt="-qarch=auto -qtune=auto"
++ else
++ xlc_opt="-qtune=auto"
++ fi
++ AX_CHECK_COMPILER_FLAGS($xlc_opt,
++ CFLAGS="-O3 -qansialias -w $xlc_opt",
++ [CFLAGS="-O3 -qansialias -w"
++ echo "******************************************************"
++ echo "* You seem to have the IBM C compiler. It is *"
++ echo "* recommended for best performance that you use: *"
++ echo "* *"
++ echo "* CFLAGS=-O3 -qarch=xxx -qtune=xxx -qansialias -w *"
++ echo "* ^^^ ^^^ *"
++ echo "* where xxx is pwr2, pwr3, 604, or whatever kind of *"
++ echo "* CPU you have. (Set the CFLAGS environment var. *"
++ echo "* and re-run configure.) For more info, man cc. *"
++ echo "******************************************************"])
++ ;;
++
++ intel) CFLAGS="-O3 -ansi_alias"
++ if test "x$acx_maxopt_portable" = xno; then
++ icc_archflag=unknown
++ icc_flags=""
++ case $host_cpu in
++ i686*|x86_64*)
++ # icc accepts gcc assembly syntax, so these should work:
++ AX_GCC_X86_CPUID(0)
++ AX_GCC_X86_CPUID(1)
++ case $ax_cv_gcc_x86_cpuid_0 in # see AX_GCC_ARCHFLAG
++ *:756e6547:*:*) # Intel
++ case $ax_cv_gcc_x86_cpuid_1 in
++ *6a?:*[[234]]:*:*|*6[[789b]]?:*:*:*) icc_flags="-xK";;
++ *f3[[347]]:*:*:*|*f4[1347]:*:*:*) icc_flags="-xP -xN -xW -xK";;
++ *f??:*:*:*) icc_flags="-xN -xW -xK";;
++ esac ;;
++ esac ;;
++ esac
++ if test "x$icc_flags" != x; then
++ for flag in $icc_flags; do
++ AX_CHECK_COMPILER_FLAGS($flag, [icc_archflag=$flag; break])
++ done
++ fi
++ AC_MSG_CHECKING([for icc architecture flag])
++ AC_MSG_RESULT($icc_archflag)
++ if test "x$icc_archflag" != xunknown; then
++ CFLAGS="$CFLAGS $icc_archflag"
++ fi
++ fi
++ ;;
++
++ gnu)
++ # default optimization flags for gcc on all systems
++ CFLAGS="-O3 -fomit-frame-pointer"
++
++ # -malign-double for x86 systems
++ AX_CHECK_COMPILER_FLAGS(-malign-double, CFLAGS="$CFLAGS -malign-double")
++
++ # -fstrict-aliasing for gcc-2.95+
++ AX_CHECK_COMPILER_FLAGS(-fstrict-aliasing,
++ CFLAGS="$CFLAGS -fstrict-aliasing")
++
++ # note that we enable "unsafe" fp optimization with other compilers, too
++ AX_CHECK_COMPILER_FLAGS(-ffast-math, CFLAGS="$CFLAGS -ffast-math")
++
++ AX_GCC_ARCHFLAG($acx_maxopt_portable)
++ ;;
++ esac
++
++ if test -z "$CFLAGS"; then
++ echo ""
++ echo "********************************************************"
++ echo "* WARNING: Don't know the best CFLAGS for this system *"
++ echo "* Use ./configure CFLAGS=... to specify your own flags *"
++ echo "* (otherwise, a default of CFLAGS=-O3 will be used) *"
++ echo "********************************************************"
++ echo ""
++ CFLAGS="-O3"
++ fi
++
++ AX_CHECK_COMPILER_FLAGS($CFLAGS, [], [
++ echo ""
++ echo "********************************************************"
++ echo "* WARNING: The guessed CFLAGS don't seem to work with *"
++ echo "* your compiler. *"
++ echo "* Use ./configure CFLAGS=... to specify your own flags *"
++ echo "********************************************************"
++ echo ""
++ CFLAGS=""
++ ])
++
++fi
++])
+diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4
+new file mode 100644
+index 0000000..026c6e9
+--- /dev/null
++++ b/m4/ax_cflags_warn_all.m4
+@@ -0,0 +1,149 @@
++# ===========================================================================
++# http://www.nongnu.org/autoconf-archive/ax_cflags_warn_all.html
++# ===========================================================================
++#
++# SYNOPSIS
++#
++# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
++#
++# DESCRIPTION
++#
++# Try to find a compiler option that enables most reasonable warnings.
++#
++# For the GNU CC compiler it will be -Wall (and -ansi -pedantic) The
++# result is added to the shellvar being CFLAGS by default.
++#
++# Currently this macro knows about GCC, Solaris C compiler, Digital Unix C
++# compiler, C for AIX Compiler, HP-UX C compiler, IRIX C compiler, NEC
++# SX-5 (Super-UX 10) C compiler, and Cray J90 (Unicos 10.0.0.8) C
++# compiler.
++#
++# - $1 shell-variable-to-add-to : CFLAGS
++# - $2 add-value-if-not-found : nothing
++# - $3 action-if-found : add value to shellvariable
++# - $4 action-if-not-found : nothing
++#
++# LICENSE
++#
++# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
++#
++# This program is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by the
++# Free Software Foundation; either version 2 of the License, or (at your
++# option) any later version.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details.
++#
++# You should have received a copy of the GNU General Public License along
++# with this program. If not, see <http://www.gnu.org/licenses/>.
++#
++# As a special exception, the respective Autoconf Macro's copyright owner
++# gives unlimited permission to copy, distribute and modify the configure
++# scripts that are the output of Autoconf when processing the Macro. You
++# need not follow the terms of the GNU General Public License when using
++# or distributing such scripts, even though portions of the text of the
++# Macro appear in them. The GNU General Public License (GPL) does govern
++# all other use of the material that constitutes the Autoconf Macro.
++#
++# This special exception to the GPL applies to versions of the Autoconf
++# Macro released by the Autoconf Archive. When you make and distribute a
++# modified version of the Autoconf Macro, you may extend this special
++# exception to the GPL to apply to your modified version as well.
++
++AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
++AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl
++AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_warn_all])dnl
++AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
++VAR,[VAR="no, unknown"
++ AC_LANG_SAVE
++ AC_LANG_C
++ ac_save_[]FLAGS="$[]FLAGS"
++for ac_arg dnl
++in "-pedantic % -Wall" dnl GCC
++ "-xstrconst % -v" dnl Solaris C
++ "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
++ "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
++ "-ansi -ansiE % -fullwarn" dnl IRIX
++ "+ESlit % +w1" dnl HP-UX C
++ "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
++ "-h conform % -h msglevel 2" dnl Cray C (Unicos)
++ #
++do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
++ AC_TRY_COMPILE([],[return 0;],
++ [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
++done
++ FLAGS="$ac_save_[]FLAGS"
++ AC_LANG_RESTORE
++])
++case ".$VAR" in
++ .ok|.ok,*) m4_ifvaln($3,$3) ;;
++ .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
++ AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
++ m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
++ *) m4_ifvaln($3,$3,[
++ if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
++ then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
++ else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
++ m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
++ fi ]) ;;
++esac
++AS_VAR_POPDEF([VAR])dnl
++AS_VAR_POPDEF([FLAGS])dnl
++])
++
++dnl the only difference - the LANG selection... and the default FLAGS
++
++AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
++AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl
++AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_warn_all])dnl
++AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
++VAR,[VAR="no, unknown"
++ AC_LANG_SAVE
++ AC_LANG_CPLUSPLUS
++ ac_save_[]FLAGS="$[]FLAGS"
++for ac_arg dnl
++in "-pedantic % -Wall" dnl GCC
++ "-xstrconst % -v" dnl Solaris C
++ "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
++ "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
++ "-ansi -ansiE % -fullwarn" dnl IRIX
++ "+ESlit % +w1" dnl HP-UX C
++ "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
++ "-h conform % -h msglevel 2" dnl Cray C (Unicos)
++ #
++do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
++ AC_TRY_COMPILE([],[return 0;],
++ [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
++done
++ FLAGS="$ac_save_[]FLAGS"
++ AC_LANG_RESTORE
++])
++case ".$VAR" in
++ .ok|.ok,*) m4_ifvaln($3,$3) ;;
++ .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[
++ AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])
++ m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;;
++ *) m4_ifvaln($3,$3,[
++ if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null
++ then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR])
++ else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"])
++ m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"
++ fi ]) ;;
++esac
++AS_VAR_POPDEF([VAR])dnl
++AS_VAR_POPDEF([FLAGS])dnl
++])
++
++dnl implementation tactics:
++dnl the for-argument contains a list of options. The first part of
++dnl these does only exist to detect the compiler - usually it is
++dnl a global option to enable -ansi or -extrawarnings. All other
++dnl compilers will fail about it. That was needed since a lot of
++dnl compilers will give false positives for some option-syntax
++dnl like -Woption or -Xoption as they think of it is a pass-through
++dnl to later compile stages or something. The "%" is used as a
++dnl delimimiter. A non-option comment can be given after "%%" marks
++dnl which will be shown but not added to the respective C/CXXFLAGS.
+diff --git a/m4/ax_check_compiler_flags.m4 b/m4/ax_check_compiler_flags.m4
+new file mode 100644
+index 0000000..7da8324
+--- /dev/null
++++ b/m4/ax_check_compiler_flags.m4
+@@ -0,0 +1,74 @@
++# ===========================================================================
++# http://www.nongnu.org/autoconf-archive/ax_check_compiler_flags.html
++# ===========================================================================
++#
++# SYNOPSIS
++#
++# AX_CHECK_COMPILER_FLAGS(FLAGS, [ACTION-SUCCESS], [ACTION-FAILURE])
++#
++# DESCRIPTION
++#
++# Check whether the given compiler FLAGS work with the current language's
++# compiler, or whether they give an error. (Warnings, however, are
++# ignored.)
++#
++# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
++# success/failure.
++#
++# LICENSE
++#
++# Copyright (c) 2009 Steven G. Johnson <stevenj@alum.mit.edu>
++# Copyright (c) 2009 Matteo Frigo
++#
++# This program is free software: you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by the
++# Free Software Foundation, either version 3 of the License, or (at your
++# option) any later version.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details.
++#
++# You should have received a copy of the GNU General Public License along
++# with this program. If not, see <http://www.gnu.org/licenses/>.
++#
++# As a special exception, the respective Autoconf Macro's copyright owner
++# gives unlimited permission to copy, distribute and modify the configure
++# scripts that are the output of Autoconf when processing the Macro. You
++# need not follow the terms of the GNU General Public License when using
++# or distributing such scripts, even though portions of the text of the
++# Macro appear in them. The GNU General Public License (GPL) does govern
++# all other use of the material that constitutes the Autoconf Macro.
++#
++# This special exception to the GPL applies to versions of the Autoconf
++# Macro released by the Autoconf Archive. When you make and distribute a
++# modified version of the Autoconf Macro, you may extend this special
++# exception to the GPL to apply to your modified version as well.
++
++AC_DEFUN([AX_CHECK_COMPILER_FLAGS],
++[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
++AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1])
++dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname:
++AS_LITERAL_IF([$1],
++ [AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1]), [
++ ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
++ _AC_LANG_PREFIX[]FLAGS="$1"
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
++ AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=yes,
++ AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=no)
++ _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])],
++ [ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
++ _AC_LANG_PREFIX[]FLAGS="$1"
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
++ eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=yes,
++ eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])=no)
++ _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])
++eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_[$1])
++AC_MSG_RESULT($ax_check_compiler_flags)
++if test "x$ax_check_compiler_flags" = xyes; then
++ m4_default([$2], :)
++else
++ m4_default([$3], :)
++fi
++])dnl AX_CHECK_COMPILER_FLAGS
+diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4
+new file mode 100644
+index 0000000..b074260
+--- /dev/null
++++ b/m4/ax_compiler_vendor.m4
+@@ -0,0 +1,61 @@
++# ===========================================================================
++# http://www.nongnu.org/autoconf-archive/ax_compiler_vendor.html
++# ===========================================================================
++#
++# SYNOPSIS
++#
++# AX_COMPILER_VENDOR
++#
++# DESCRIPTION
++#
++# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
++# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
++# watcom, etc. The vendor is returned in the cache variable
++# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
++#
++# LICENSE
++#
++# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
++# Copyright (c) 2008 Matteo Frigo
++#
++# This program is free software: you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by the
++# Free Software Foundation, either version 3 of the License, or (at your
++# option) any later version.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details.
++#
++# You should have received a copy of the GNU General Public License along
++# with this program. If not, see <http://www.gnu.org/licenses/>.
++#
++# As a special exception, the respective Autoconf Macro's copyright owner
++# gives unlimited permission to copy, distribute and modify the configure
++# scripts that are the output of Autoconf when processing the Macro. You
++# need not follow the terms of the GNU General Public License when using
++# or distributing such scripts, even though portions of the text of the
++# Macro appear in them. The GNU General Public License (GPL) does govern
++# all other use of the material that constitutes the Autoconf Macro.
++#
++# This special exception to the GPL applies to versions of the Autoconf
++# Macro released by the Autoconf Archive. When you make and distribute a
++# modified version of the Autoconf Macro, you may extend this special
++# exception to the GPL to apply to your modified version as well.
++
++AC_DEFUN([AX_COMPILER_VENDOR],
++[
++AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
++ [ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=unknown
++ # note: don't check for gcc first since some other compilers define __GNUC__
++ 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
++ vencpp="defined("`echo $ventest | cut -d: -f2 | sed 's/,/) || defined(/g'`")"
++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
++#if !($vencpp)
++ thisisanerror;
++#endif
++])], [ax_cv_]_AC_LANG_ABBREV[_compiler_vendor=`echo $ventest | cut -d: -f1`; break])
++ done
++ ])
++])
+diff --git a/m4/ax_gcc_archflag.m4 b/m4/ax_gcc_archflag.m4
+new file mode 100644
+index 0000000..dedeef4
+--- /dev/null
++++ b/m4/ax_gcc_archflag.m4
+@@ -0,0 +1,213 @@
++# ===========================================================================
++# http://www.nongnu.org/autoconf-archive/ax_gcc_archflag.html
++# ===========================================================================
++#
++# SYNOPSIS
++#
++# AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])
++#
++# DESCRIPTION
++#
++# This macro tries to guess the "native" arch corresponding to the target
++# architecture for use with gcc's -march=arch or -mtune=arch flags. If
++# found, the cache variable $ax_cv_gcc_archflag is set to this flag and
++# ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is is set to
++# "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is
++# to add $ax_cv_gcc_archflag to the end of $CFLAGS.
++#
++# PORTABLE? should be either [yes] (default) or [no]. In the former case,
++# the flag is set to -mtune (or equivalent) so that the architecture is
++# only used for tuning, but the instruction set used is still portable. In
++# the latter case, the flag is set to -march (or equivalent) so that
++# architecture-specific instructions are enabled.
++#
++# The user can specify --with-gcc-arch=<arch> in order to override the
++# macro's choice of architecture, or --without-gcc-arch to disable this.
++#
++# When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is
++# called unless the user specified --with-gcc-arch manually.
++#
++# Requires macros: AX_CHECK_COMPILER_FLAGS, AX_GCC_X86_CPUID
++#
++# (The main emphasis here is on recent CPUs, on the principle that doing
++# high-performance computing on old hardware is uncommon.)
++#
++# LICENSE
++#
++# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
++# Copyright (c) 2008 Matteo Frigo
++#
++# This program is free software: you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by the
++# Free Software Foundation, either version 3 of the License, or (at your
++# option) any later version.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details.
++#
++# You should have received a copy of the GNU General Public License along
++# with this program. If not, see <http://www.gnu.org/licenses/>.
++#
++# As a special exception, the respective Autoconf Macro's copyright owner
++# gives unlimited permission to copy, distribute and modify the configure
++# scripts that are the output of Autoconf when processing the Macro. You
++# need not follow the terms of the GNU General Public License when using
++# or distributing such scripts, even though portions of the text of the
++# Macro appear in them. The GNU General Public License (GPL) does govern
++# all other use of the material that constitutes the Autoconf Macro.
++#
++# This special exception to the GPL applies to versions of the Autoconf
++# Macro released by the Autoconf Archive. When you make and distribute a
++# modified version of the Autoconf Macro, you may extend this special
++# exception to the GPL to apply to your modified version as well.
++
++AC_DEFUN([AX_GCC_ARCHFLAG],
++[AC_REQUIRE([AC_PROG_CC])
++AC_REQUIRE([AC_CANONICAL_HOST])
++
++AC_ARG_WITH(gcc-arch, [AC_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
++ ax_gcc_arch=$withval, ax_gcc_arch=yes)
++
++AC_MSG_CHECKING([for gcc architecture flag])
++AC_MSG_RESULT([])
++AC_CACHE_VAL(ax_cv_gcc_archflag,
++[
++ax_cv_gcc_archflag="unknown"
++
++if test "$GCC" = yes; then
++
++if test "x$ax_gcc_arch" = xyes; then
++ax_gcc_arch=""
++if test "$cross_compiling" = no; then
++case $host_cpu in
++ i[[3456]]86*|x86_64*) # use cpuid codes, in part from x86info-1.7 by D. Jones
++ AX_GCC_X86_CPUID(0)
++ AX_GCC_X86_CPUID(1)
++ case $ax_cv_gcc_x86_cpuid_0 in
++ *:756e6547:*:*) # Intel
++ case $ax_cv_gcc_x86_cpuid_1 in
++ *5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
++ *5??:*:*:*) ax_gcc_arch=pentium ;;
++ *6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
++ *6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
++ *6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
++ *6[[9d]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
++ *6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
++ *6??:*:*:*) ax_gcc_arch=pentiumpro ;;
++ *f3[[347]]:*:*:*|*f4[1347]:*:*:*)
++ case $host_cpu in
++ x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
++ *) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
++ esac ;;
++ *f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";;
++ esac ;;
++ *:68747541:*:*) # AMD
++ case $ax_cv_gcc_x86_cpuid_1 in
++ *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
++ *5[[8d]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
++ *5[[9]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
++ *60?:*:*:*) ax_gcc_arch=k7 ;;
++ *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
++ *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
++ *67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;;
++ *6[[68a]]?:*:*:*)
++ AX_GCC_X86_CPUID(0x80000006) # L2 cache size
++ case $ax_cv_gcc_x86_cpuid_0x80000006 in
++ *:*:*[[1-9a-f]]??????:*) # (L2 = ecx >> 16) >= 256
++ ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
++ *) ax_gcc_arch="athlon-4 athlon k7" ;;
++ esac ;;
++ *f[[4cef8b]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
++ *f5?:*:*:*) ax_gcc_arch="opteron k8" ;;
++ *f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;;
++ *f??:*:*:*) ax_gcc_arch="k8" ;;
++ esac ;;
++ *:746e6543:*:*) # IDT
++ case $ax_cv_gcc_x86_cpuid_1 in
++ *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
++ *58?:*:*:*) ax_gcc_arch=winchip2 ;;
++ *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
++ *69?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
++ esac ;;
++ esac
++ if test x"$ax_gcc_arch" = x; then # fallback
++ case $host_cpu in
++ i586*) ax_gcc_arch=pentium ;;
++ i686*) ax_gcc_arch=pentiumpro ;;
++ esac
++ fi
++ ;;
++
++ sparc*)
++ AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
++ 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`
++ cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters`
++ case $cputype in
++ *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
++ *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
++ *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
++ *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
++ *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
++ *cypress*) ax_gcc_arch=cypress ;;
++ esac ;;
++
++ alphaev5) ax_gcc_arch=ev5 ;;
++ alphaev56) ax_gcc_arch=ev56 ;;
++ alphapca56) ax_gcc_arch="pca56 ev56" ;;
++ alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
++ alphaev6) ax_gcc_arch=ev6 ;;
++ alphaev67) ax_gcc_arch=ev67 ;;
++ alphaev68) ax_gcc_arch="ev68 ev67" ;;
++ alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
++ alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
++ alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
++
++ powerpc*)
++ 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`
++ cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
++ case $cputype in
++ *750*) ax_gcc_arch="750 G3" ;;
++ *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
++ *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
++ *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
++ *970*) ax_gcc_arch="970 G5 power4";;
++ *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
++ *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
++ 603ev|8240) ax_gcc_arch="$cputype 603e 603";;
++ *) ax_gcc_arch=$cputype ;;
++ esac
++ ax_gcc_arch="$ax_gcc_arch powerpc"
++ ;;
++esac
++fi # not cross-compiling
++fi # guess arch
++
++if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
++for arch in $ax_gcc_arch; do
++ if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
++ flags="-mtune=$arch"
++ # -mcpu=$arch and m$arch generate nonportable code on every arch except
++ # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr.
++ case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac
++ else
++ flags="-march=$arch -mcpu=$arch -m$arch"
++ fi
++ for flag in $flags; do
++ AX_CHECK_COMPILER_FLAGS($flag, [ax_cv_gcc_archflag=$flag; break])
++ done
++ test "x$ax_cv_gcc_archflag" = xunknown || break
++done
++fi
++
++fi # $GCC=yes
++])
++AC_MSG_CHECKING([for gcc architecture flag])
++AC_MSG_RESULT($ax_cv_gcc_archflag)
++if test "x$ax_cv_gcc_archflag" = xunknown; then
++ m4_default([$3],:)
++else
++ m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
++fi
++])
+diff --git a/m4/ax_gcc_x86_cpuid.m4 b/m4/ax_gcc_x86_cpuid.m4
+new file mode 100644
+index 0000000..5420b09
+--- /dev/null
++++ b/m4/ax_gcc_x86_cpuid.m4
+@@ -0,0 +1,77 @@
++# ===========================================================================
++# http://www.nongnu.org/autoconf-archive/ax_gcc_x86_cpuid.html
++# ===========================================================================
++#
++# SYNOPSIS
++#
++# AX_GCC_X86_CPUID(OP)
++#
++# DESCRIPTION
++#
++# On Pentium and later x86 processors, with gcc or a compiler that has a
++# compatible syntax for inline assembly instructions, run a small program
++# that executes the cpuid instruction with input OP. This can be used to
++# detect the CPU type.
++#
++# On output, the values of the eax, ebx, ecx, and edx registers are stored
++# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
++# ax_cv_gcc_x86_cpuid_OP.
++#
++# If the cpuid instruction fails (because you are running a
++# cross-compiler, or because you are not using gcc, or because you are on
++# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP
++# is set to the string "unknown".
++#
++# This macro mainly exists to be used in AX_GCC_ARCHFLAG.
++#
++# LICENSE
++#
++# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
++# Copyright (c) 2008 Matteo Frigo
++#
++# This program is free software: you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by the
++# Free Software Foundation, either version 3 of the License, or (at your
++# option) any later version.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details.
++#
++# You should have received a copy of the GNU General Public License along
++# with this program. If not, see <http://www.gnu.org/licenses/>.
++#
++# As a special exception, the respective Autoconf Macro's copyright owner
++# gives unlimited permission to copy, distribute and modify the configure
++# scripts that are the output of Autoconf when processing the Macro. You
++# need not follow the terms of the GNU General Public License when using
++# or distributing such scripts, even though portions of the text of the
++# Macro appear in them. The GNU General Public License (GPL) does govern
++# all other use of the material that constitutes the Autoconf Macro.
++#
++# This special exception to the GPL applies to versions of the Autoconf
++# Macro released by the Autoconf Archive. When you make and distribute a
++# modified version of the Autoconf Macro, you may extend this special
++# exception to the GPL to apply to your modified version as well.
++
++AC_DEFUN([AX_GCC_X86_CPUID],
++[AC_REQUIRE([AC_PROG_CC])
++AC_LANG_PUSH([C])
++AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
++ [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
++ int op = $1, eax, ebx, ecx, edx;
++ FILE *f;
++ __asm__("cpuid"
++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
++ : "a" (op));
++ f = fopen("conftest_cpuid", "w"); if (!f) return 1;
++ fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
++ fclose(f);
++ return 0;
++])],
++ [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
++ [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
++ [ax_cv_gcc_x86_cpuid_$1=unknown])])
++AC_LANG_POP([C])
++])
+diff --git a/m4/ax_submodule.m4 b/m4/ax_submodule.m4
+new file mode 100644
+index 0000000..57e3a56
+--- /dev/null
++++ b/m4/ax_submodule.m4
+@@ -0,0 +1,63 @@
++AC_DEFUN([AX_SUBMODULE],
++[
++
++AC_ARG_WITH($1,
++ [AS_HELP_STRING([--with-$1=$2],
++ [Which $1 to use])])
++case "system" in
++$2)
++ AC_ARG_WITH($1_prefix,
++ [AS_HELP_STRING([--with-$1-prefix=DIR],
++ [Prefix of $1 installation])])
++ AC_ARG_WITH($1_exec_prefix,
++ [AS_HELP_STRING([--with-$1-exec-prefix=DIR],
++ [Exec prefix of $1 installation])])
++esac
++case "build" in
++$2)
++ AC_ARG_WITH($1_builddir,
++ [AS_HELP_STRING([--with-$1-builddir=DIR],
++ [Location of $1 builddir])])
++esac
++if test "x$with_$1_prefix" != "x" -a "x$with_$1_exec_prefix" = "x"; then
++ with_$1_exec_prefix=$with_$1_prefix
++fi
++if test "x$with_$1_prefix" != "x" -o "x$with_$1_exec_prefix" != "x"; then
++ if test "x$with_$1" != "x" -a "x$with_$1" != "xsystem"; then
++ AC_MSG_ERROR([Setting $with_$1_prefix implies use of system $1])
++ fi
++ with_$1="system"
++fi
++if test "x$with_$1_builddir" != "x"; then
++ if test "x$with_$1" != "x" -a "x$with_$1" != "xbuild"; then
++ AC_MSG_ERROR([Setting $with_$1_builddir implies use of build $1])
++ fi
++ with_$1="build"
++ $1_srcdir=`echo @abs_srcdir@ | $with_$1_builddir/config.status --file=-`
++ AC_MSG_NOTICE($1 sources in $$1_srcdir)
++fi
++case "$with_$1" in
++$2)
++ ;;
++*)
++ if test -d $srcdir/.git -a \
++ -d $srcdir/$1 -a \
++ ! -d $srcdir/$1/.git; then
++ AC_MSG_WARN(
++[git repo detected, but submodule $1 not initialized])
++ AC_MSG_WARN([You may want to run])
++ AC_MSG_WARN([ git submodule init])
++ AC_MSG_WARN([ git submodule update])
++ AC_MSG_WARN([ sh autogen.sh])
++ fi
++ if test -f $srcdir/$1/configure -a "$3" != "no"; then
++ with_$1="bundled"
++ else
++ with_$1="$3"
++ fi
++ ;;
++esac
++AC_MSG_CHECKING([which $1 to use])
++AC_MSG_RESULT($with_$1)
++
++])
+diff --git a/osl b/osl
+new file mode 160000
+index 0000000..46ef4ec
+--- /dev/null
++++ b/osl
+@@ -0,0 +1 @@
++Subproject commit 46ef4ec9917713d5d51dd45331c0e74870c5375d
+diff --git a/piplib b/piplib
+new file mode 160000
+index 0000000..f2cfdd3
+--- /dev/null
++++ b/piplib
+@@ -0,0 +1 @@
++Subproject commit f2cfdd3f7a7c4c0c4f7408437205fa27bfb041ba
+diff --git a/redo.sh b/redo.sh
+new file mode 100755
+index 0000000..a1cdb50
+--- /dev/null
++++ b/redo.sh
+@@ -0,0 +1,12 @@
++#!/bin/sh
++make maintainer-clean
++#./get_submodules.sh
++./autogen.sh
++./configure \
++ --prefix=$HOME/usr \
++ --with-osl=system \
++ --with-osl-prefix=$HOME/usr \
++ --with-piplib=system \
++ --with-piplib-prefix=$HOME/usr
++
++make
+diff --git a/source/Makefile.am b/source/Makefile.am
+deleted file mode 100644
+index 3909be1..0000000
+--- a/source/Makefile.am
++++ /dev/null
+@@ -1,70 +0,0 @@
+-#
+-# /**-------------------------------------------------------------------**
+-# ** CAnDL **
+-# **-------------------------------------------------------------------**
+-# ** Makefile.am **
+-# **-------------------------------------------------------------------**
+-# ** First version: september 8th 2003 **
+-# **-------------------------------------------------------------------**/
+-#
+-#/*****************************************************************************
+-# * CAnDL : the Chunky Analyser for Dependences in Loops (experimental) *
+-# *****************************************************************************
+-# * *
+-# * Copyright (C) 2003-2008 Cedric Bastoul *
+-# * *
+-# * This is free software; you can redistribute it and/or modify it under the *
+-# * terms of the GNU General Public License as published by the Free Software *
+-# * Foundation; either version 2 of the License, or (at your option) any *
+-# * later version. *
+-# * *
+-# * This software is distributed in the hope that it will be useful, but *
+-# * WITHOUT ANY WARRANTY; without even the implied warranty of *
+-# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
+-# * Public License for more details. *
+-# * *
+-# * You should have received a copy of the GNU General Public License along *
+-# * with software; if not, write to the Free Software Foundation, Inc., *
+-# * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+-# * *
+-# * CAnDL, the Chunky Dependence Analyser *
+-# * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+-# * *
+-# *****************************************************************************/
+-
+-
+-#############################################################################
+-SUBDIRS =
+-
+-#############################################################################
+-MAINTAINERCLEANFILES = Makefile.in
+-
+-INCLUDES = -I$(top_builddir) -I$(top_srcdir) \
+- -I$(top_builddir)/include \
+- -I$(top_srcdir)/include
+-
+-#############################################################################
+-
+-lib_LTLIBRARIES = libcandl.la
+-
+-
+-libcandl_la_SOURCES = \
+- dependence.c \
+- ddv.c \
+- isl-wrapper.c \
+- matrix.c \
+- options.c \
+- piplib-wrapper.c \
+- program.c \
+- pruning.c \
+- statement.c \
+- violation.c
+-
+-AM_CFLAGS = -Wall -fomit-frame-pointer -g
+-
+-
+-bin_PROGRAMS = candl
+-
+-LDADD = libcandl.la
+-
+-candl_SOURCES = candl.c
+diff --git a/source/candl.c b/source/candl.c
+index 27e8ca4..df6bf18 100644
+--- a/source/candl.c
++++ b/source/candl.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: september 8th 2003 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -33,98 +33,162 @@
+ * *
+ ******************************************************************************/
+
+-
+ #include <stdlib.h>
+ #include <stdio.h>
+-#include <candl/candl.h>
++#include <osl/scop.h>
++#include <osl/macros.h>
++#include <osl/util.h>
++#include <osl/extensions/dependence.h>
++#include <candl/macros.h>
+ #include <candl/dependence.h>
+-#include <candl/program.h>
+ #include <candl/violation.h>
+ #include <candl/options.h>
++#include <candl/scop.h>
++#include <candl/util.h>
++#include <candl/piplib.h>
+
+
+-int main(int argc, char * argv[])
+-{
+- CandlProgram * program = NULL;
+- CandlOptions * options;
+- CandlDependence * dependence;
+- CandlViolation * violation = NULL;
+- FILE * input, * output;
++int main(int argc, char * argv[]) {
++
++ osl_scop_p scop = NULL;
++ osl_scop_p orig_scop = NULL;
++ osl_dependence_p dep = NULL;
++ int num_scops = 0, i= 0;
++ candl_options_p options;
++ candl_violation_p *violations = NULL;
++ FILE *input, *output, *input_test;
++ int precision;
++ #if defined(CANDL_LINEAR_VALUE_IS_INT)
++ precision = OSL_PRECISION_SP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ precision = OSL_PRECISION_DP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ precision = OSL_PRECISION_MP;
++ #endif
+
+ /* Options and input/output file setting. */
+- candl_options_read(argc, argv, &input, &output, &options);
+-
+- /* Reading the program informations. */
+-#ifdef CANDL_SUPPORTS_SCOPLIB
+- if (options->readscop)
+- {
+- program = candl_program_read_scop(input);
+- if (options->scoptocandl)
+- {
+- if (! options->readscop)
+- program = candl_program_read_scop(input);
+- candl_program_print_candl_file(output, program);
+- candl_program_free(program);
+- candl_options_free(options);
+- return 0;
+- }
+- }
+- else
+-#endif
+- program = candl_program_read(input);
+-
++ candl_options_read(argc, argv, &input, &output, &input_test, &options);
++
++ /* Open the scop
++ * If there is no original scop (given with the -test), the input file
++ * is considered as the original scop
++ */
++ osl_interface_p registry = osl_interface_get_default_registry();
++ if (input_test != NULL) {
++ scop = osl_scop_pread(input, registry, precision);
++ orig_scop = osl_scop_pread(input_test, registry, precision);
++ } else {
++ orig_scop = osl_scop_pread(input, registry, precision);
++ }
++ osl_interface_free(registry);
++
++ if (orig_scop == NULL || (scop == NULL && input_test != NULL)) {
++ CANDL_error("Fail to open scop");
++ exit(1);
++ }
++
++ /* Check if we can compare the two scop
++ * The function compare only domains and access arrays
++ */
++ if (input_test != NULL && !candl_util_check_scop_list(orig_scop, scop))
++ CANDL_error("The two scop lists can't be compared");
++
++ /* Add more infos (depth, label, ...)
++ * Not important for the transformed scop
++ * TODO : the statements must be sorted to compute the statement label
++ * the problem is if the scop is reordered, the second transformed scop
++ * must be aligned with it
++ */
++ candl_scop_usr_init(orig_scop);
++
+ /* Calculating dependences. */
+- dependence = candl_dependence(program, options);
++ candl_dependence_add_extension(orig_scop, options);
+
++ osl_scop_p s1 = orig_scop;
++ while (s1) {num_scops++; s1 = s1->next;}
++
++ s1 = orig_scop;
++ osl_scop_p s2 = scop;
+ /* Calculating legality violations. */
+- if (options->violgraph)
+- violation = candl_violation(program, dependence, options);
++ if (input_test != NULL) {
++ CANDL_malloc(violations, candl_violation_p*, num_scops);
+
+- /* Printing data structures if asked. */
+- if (options->structure)
+- {
+- fprintf(output, "Program:\n");
+- candl_program_print(output, program);
+- fprintf(output, "\nDependences:\n");
+- candl_dependence_print(output, dependence);
+- fprintf(output, "\nViolations:\n");
+- candl_violation_print(output, violation);
++ for (i=0; i< num_scops; i++, s1 = s1->next, s2 = s2->next) {
++ dep = osl_generic_lookup(s1->extension,
++ OSL_URI_DEPENDENCE);
++ violations[i] = candl_violation(s1, dep, s2, options);
+ }
++ }
++
++ /* Printing data structures if asked. */
++ if (options->structure) {
++
++ if (input_test != NULL) {
++ s1=orig_scop; s2=scop;
++ for (i=0; i< num_scops; i++, s1=s1->next, s2=s2->next) {
++ fprintf(output, "\033[33mORIGINAL SCOP:\033[00m\n");
++ osl_scop_print(output, s1);
++ fprintf(output, "\n\033[33mTRANSFORMED SCOP:\033[00m\n");
++ osl_scop_print(output, s2);
+
+-#ifdef CANDL_SUPPORTS_SCOPLIB
+- if (options->readscop && options->writescop)
+- candl_dependence_print_scop (input, output, dependence);
+- else
+- {
+-#endif
+- /* Printing dependence graph if asked or if there is no transformation. */
+- if (options->depgraph || (program->transformation == NULL))
+- {
+- candl_dependence_pprint(output, dependence);
+- if (options->view)
+- candl_dependence_view(dependence);
+- }
+- /* Printing violation graph if asked and if there is a transformation. */
+- if (options->violgraph && (program->transformation != NULL))
+- {
+- candl_violation_pprint(output, violation);
+- if (options->view)
+- candl_violation_view(violation);
+- }
++ dep = osl_generic_lookup(s1->extension, OSL_URI_DEPENDENCE);
++ fprintf(output, "\n\033[33mDEPENDENCES GRAPH:\033[00m\n");
++ candl_dependence_pprint(output, dep);
++ fprintf(output, "\n\n\033[33mVIOLATIONS GRAPH:\033[00m\n");
++ candl_violation_pprint(output, violations[i]);
++ }
++ } else {
++ s1=orig_scop;
++ for (i=0; i< num_scops; i++, s1=s1->next) {
++ fprintf(output, "\033[33mORIGINAL SCOP:\033[00m\n");
++ osl_scop_print(output, s1);
+
+-#ifdef CANDL_SUPPORTS_SCOPLIB
++ dep = osl_generic_lookup(s1->extension, OSL_URI_DEPENDENCE);
++ fprintf(output, "\n\033[33mDEPENDENCES GRAPH:\033[00m\n");
++ candl_dependence_pprint(output, dep);
++ }
+ }
+-#endif
+
++ } else if (input_test != NULL) {
++ /* Printing violation graph */
++ for (i=0; i< num_scops; i++) {
++ candl_violation_pprint(output, violations[i]);
++ if (options->view)
++ candl_violation_view(violations[i]);
++ }
++ } else if (options->outscop) {
++ /* Export to the scop format */
++ s1=orig_scop;
++ osl_scop_print(output, s1); //prints list
++ } else {
++ /* Printing dependence graph if asked or if there is no transformation. */
++ s1=orig_scop;
++ for(i=0; i< num_scops; i++, s1=s1->next){
++ dep = osl_generic_lookup(s1->extension, OSL_URI_DEPENDENCE);
++ fprintf(output, "\033[33mSCOP #%d:\033[00m\n", i+1);
++ candl_dependence_pprint(output, dep);
++ fprintf(output, "\n");
++ if (options->view)
++ candl_dependence_view(dep);
++ }
++ }
+
+ /* Being clean. */
+- candl_violation_free(violation);
+- candl_dependence_free(dependence);
+- candl_program_free(program);
++ if (input_test != NULL) {
++ for (i=0; i< num_scops; i++)
++ candl_violation_free(violations[i]);
++ osl_scop_free(scop);
++ fclose(input_test);
++ }
++
++ // the dependence is freed with the scop
++ //osl_dependence_free(orig_dependence);
+ candl_options_free(options);
+- pip_close();
++ candl_scop_usr_cleanup(orig_scop);
++ osl_scop_free(orig_scop);
+ fclose(input);
+ fclose(output);
+-
++ pip_close();
++
+ return 0;
+ }
+diff --git a/source/ddv.c b/source/ddv.c
+index 8ac06f5..7220198 100644
+--- a/source/ddv.c
++++ b/source/ddv.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: February 4th 2010 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -41,13 +41,16 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+-#include <candl/candl.h>
+-
+ #include <assert.h>
+-
++#include <osl/statement.h>
++#include <osl/scop.h>
++#include <osl/extensions/dependence.h>
++#include <candl/macros.h>
++#include <candl/ddv.h>
++#include <candl/statement.h>
++#include <candl/piplib.h>
+ #include <candl/piplib-wrapper.h>
+
+-
+ #ifndef min
+ # define min(x,y) (x < y ? x : y)
+ #endif
+@@ -55,6 +58,7 @@
+ # define max(x,y) (x > y ? x : y)
+ #endif
+
++
+ /******************************************************************************
+ * Memory deallocation function *
+ ******************************************************************************/
+@@ -65,8 +69,7 @@
+ *
+ */
+ CandlDDV*
+-candl_ddv_malloc()
+-{
++candl_ddv_malloc() {
+ CandlDDV* dv = (CandlDDV*) malloc(sizeof(CandlDDV));
+ dv->next = NULL;
+ dv->data = NULL;
+@@ -82,19 +85,17 @@ candl_ddv_malloc()
+ *
+ */
+ CandlDDV*
+-candl_ddv_alloc(int size)
+-{
++candl_ddv_alloc(int size) {
+ CandlDDV* dv = candl_ddv_malloc();
+
+ dv->data = (s_dv_descriptor*) malloc(size * sizeof(s_dv_descriptor));
+ dv->length = size;
+
+ int i;
+- for (i = 0; i < size; ++i)
+- {
+- dv->data[i].type = candl_dv_star;
+- dv->data[i].value = 0;
+- }
++ for (i = 0; i < size; ++i) {
++ dv->data[i].type = candl_dv_star;
++ dv->data[i].value = 0;
++ }
+
+ return dv;
+ }
+@@ -106,19 +107,17 @@ candl_ddv_alloc(int size)
+ *
+ */
+ void
+-candl_ddv_free(CandlDDV* dv)
+-{
++candl_ddv_free(CandlDDV* dv) {
+ CandlDDV* tmp;
+ CandlDDV* next;
+
+- for (tmp = dv; tmp; )
+- {
+- next = tmp->next;
+- if (tmp->data)
+- free(tmp->data);
+- free(tmp);
+- tmp = next;
+- }
++ for (tmp = dv; tmp; ) {
++ next = tmp->next;
++ if (tmp->data)
++ free(tmp->data);
++ free(tmp);
++ tmp = next;
++ }
+
+ }
+
+@@ -130,8 +129,7 @@ candl_ddv_free(CandlDDV* dv)
+ *
+ */
+ void
+-candl_ddv_set_type_at(CandlDDV* dv, e_dv_type type, int pos)
+-{
++candl_ddv_set_type_at(CandlDDV* dv, e_dv_type type, int pos) {
+ dv->data[pos].type = type;
+ }
+
+@@ -143,19 +141,17 @@ candl_ddv_set_type_at(CandlDDV* dv, e_dv_type type, int pos)
+ *
+ */
+ void
+-candl_ddv_set_value_at(CandlDDV* dv, int value, int pos)
+-{
++candl_ddv_set_value_at(CandlDDV* dv, int value, int pos) {
+ dv->data[pos].value = value;
+ }
+
+ /**
+ * candl_ddv_set_type: Set the type of the dependence in
+- * CANDL_UNSET, CANDL_RAW, CANDL_WAR, CANDL_WAW, CANDL_RAR.
++ * CANDL_UNDEFINED, CANDL_RAW, CANDL_WAR, CANDL_WAW, CANDL_RAR.
+ *
+ */
+ void
+-candl_ddv_set_deptype(CandlDDV* dv, int type)
+-{
++candl_ddv_set_deptype(CandlDDV* dv, int type) {
+ dv->deptype = type;
+ }
+
+@@ -170,33 +166,30 @@ candl_ddv_set_deptype(CandlDDV* dv, int type)
+ *
+ */
+ void
+-candl_ddv_print(FILE* out, CandlDDV* dv)
+-{
+- if (!dv)
+- {
+- fprintf(out, "(null ddv)\n");
+- return;
+- }
++candl_ddv_print(FILE* out, CandlDDV* dv) {
++ if (!dv) {
++ fprintf(out, "(null ddv)\n");
++ return;
++ }
+
+ int i;
+ fprintf(out, "loop_id=%d, (", dv->loop_id);
+- for (i = 0; i < dv->length; ++i)
+- {
+- if (dv->data[i].type == candl_dv_star)
+- fprintf(out, "*");
+- else if (dv->data[i].type == candl_dv_eq)
+- fprintf(out, "=");
+- else if (dv->data[i].type == candl_dv_plus)
+- fprintf(out, ">");
+- else if (dv->data[i].type == candl_dv_minus)
+- fprintf(out, "<");
+- else if (dv->data[i].type == candl_dv_scalar)
+- fprintf(out, "%d", dv->data[i].value);
+- if (i < dv->length - 1)
+- fprintf(out, ", ");
+- else
+- fprintf(out, ")\n");
+- }
++ for (i = 0; i < dv->length; ++i) {
++ if (dv->data[i].type == candl_dv_star)
++ fprintf(out, "*");
++ else if (dv->data[i].type == candl_dv_eq)
++ fprintf(out, "=");
++ else if (dv->data[i].type == candl_dv_plus)
++ fprintf(out, ">");
++ else if (dv->data[i].type == candl_dv_minus)
++ fprintf(out, "<");
++ else if (dv->data[i].type == candl_dv_scalar)
++ fprintf(out, "%d", dv->data[i].value);
++ if (i < dv->length - 1)
++ fprintf(out, ", ");
++ else
++ fprintf(out, ")\n");
++ }
+ }
+
+
+@@ -206,24 +199,11 @@ candl_ddv_print(FILE* out, CandlDDV* dv)
+
+
+ /**
+- * Integer emptiness test on a given polyhedron.
+- *
+- */
+-static
+-int
+-candl_ddv_has_point(CandlMatrix* system)
+-{
+- return pip_has_rational_point (system, NULL, 1);
+-}
+-
+-
+-/**
+ * Recursively count the number of leaves in a QUAST.
+ *
+ */
+ static
+-int count_quast_leaves(PipQuast* q)
+-{
++int count_quast_leaves(PipQuast* q) {
+ if (!q)
+ return 0;
+ if (q->condition == NULL)
+@@ -238,22 +218,19 @@ int count_quast_leaves(PipQuast* q)
+ *
+ */
+ static
+-void get_quast_leaves(PipQuast* q, PipList** leaves)
+-{
++void get_quast_leaves(PipQuast* q, PipList** leaves) {
+ if (!q)
+ return;
+- if (q->condition == NULL)
+- {
+- int i;
+- for (i = 0; leaves[i]; ++i)
+- ;
+- leaves[i] = q->list;
+- }
+- else
+- {
+- get_quast_leaves(q->next_else, leaves);
+- get_quast_leaves(q->next_then, leaves);
+- }
++ if (q->condition == NULL) {
++ int i;
++ for (i = 0; leaves[i]; ++i)
++ ;
++ leaves[i] = q->list;
++ }
++ else {
++ get_quast_leaves(q->next_else, leaves);
++ get_quast_leaves(q->next_then, leaves);
++ }
+ }
+
+
+@@ -266,15 +243,16 @@ void get_quast_leaves(PipQuast* q, PipList** leaves)
+ */
+ static
+ int
+-candl_ddv_constant_val(CandlMatrix* system, int* val, int nb_par)
+-{
++candl_ddv_constant_val(osl_relation_p system, int* val, int nb_par) {
+ PipOptions * options;
+ PipQuast * solution;
++ osl_relation_p context;
+ int is_constant_val = 1;
+ int cst;
+ int cst_base = 42;
+ int first = 1;
+ int i, j;
++ int precision = system->precision;
+
+ // 1- Comute the lexmin of the system, to get a QUAST.
+ options = pip_options_init();
+@@ -282,54 +260,51 @@ candl_ddv_constant_val(CandlMatrix* system, int* val, int nb_par)
+ options->Urs_parms = -1;
+ options->Urs_unknowns = -1;
+ options->Nq = 0;
+- CandlMatrix* context = candl_matrix_malloc(0, nb_par + 2);
+- solution = pip_solve(system, context, -1, options);
++
++ context = osl_relation_pmalloc(precision, 0, nb_par + 2);
++ solution = pip_solve_osl(system, context, -1, options);
+
+ if ((solution != NULL) &&
+- ((solution->list != NULL) || (solution->condition != NULL)))
+- {
+- // 2- Traverse all leaves, ensure they have the same value.
+- int nb_leaves = count_quast_leaves(solution);
+- PipList* leaveslist[nb_leaves + 1];
+- for (i = 0; i < nb_leaves + 1; ++i)
+- leaveslist[i] = NULL;
+- get_quast_leaves(solution, leaveslist);
+-
+- for (i = 0; i < nb_leaves; ++i)
+- {
+- PipList* list = leaveslist[i];
+- if (list && list->vector)
+- {
+- PipVector* vect = list->vector;
+- for (j = 0; j < nb_par; ++j)
+- if (CANDL_get_si(vect->the_vector[j]) != 0)
+- {
+- is_constant_val = 0;
+- break;
+- }
+- if (is_constant_val)
+- {
+- cst = CANDL_get_si(vect->the_vector[vect->nb_elements - 1]);
+- if (first)
+- {
+- first = 0;
+- cst_base = cst;
+- }
+- else if (! first && cst != cst_base)
+- {
+- is_constant_val = 0;
+- break;
+- }
+- }
+- else
+- break;
+- }
+- }
++ ((solution->list != NULL) || (solution->condition != NULL))) {
++ // 2- Traverse all leaves, ensure they have the same value.
++ int nb_leaves = count_quast_leaves(solution);
++ PipList* leaveslist[nb_leaves + 1];
++ for (i = 0; i < nb_leaves + 1; ++i)
++ leaveslist[i] = NULL;
++ get_quast_leaves(solution, leaveslist);
++
++ for (i = 0; i < nb_leaves; ++i) {
++ PipList* list = leaveslist[i];
++ if (list && list->vector) {
++ PipVector* vect = list->vector;
++
++ // FIXME : check if precision is correct to use piplib
++
++ for (j = 0; j < nb_par; ++j)
++ if (!CANDL_zero_p(vect->the_vector[j])) {
++ is_constant_val = 0;
++ break;
++ }
++ if (is_constant_val) {
++ cst = CANDL_get_si(vect->the_vector[vect->nb_elements-1]);
++ if (first) {
++ first = 0;
++ cst_base = cst;
++ }
++ else if (! first && cst != cst_base) {
++ is_constant_val = 0;
++ break;
++ }
++ }
++ else
++ break;
++ }
+ }
++ }
+
+ pip_quast_free(solution);
+ pip_options_free(options);
+- candl_matrix_free(context);
++ osl_relation_free(context);
+
+ if (is_constant_val)
+ *val = cst_base;
+@@ -345,98 +320,97 @@ candl_ddv_constant_val(CandlMatrix* system, int* val, int nb_par)
+ */
+ static
+ CandlDDV*
+-candl_ddv_create_from_dep(CandlDependence* dep, int loop_id, int ddv_size)
+-{
++candl_ddv_create_from_dep(osl_dependence_p dep, int loop_id, int ddv_size) {
++ osl_relation_p mat = dep->domain;
++ osl_statement_p src = dep->stmt_source_ptr;
++ candl_statement_usr_p usr = src->usr;
++ CandlDDV* dv = candl_ddv_alloc(ddv_size);
++ int precision = src->domain->precision;
+ int i, j;
+ int pos;
+- CandlMatrix* mat = dep->domain;
+- CandlStatement* src = dep->source;
+- CandlDDV* dv = candl_ddv_alloc(ddv_size);
++
+ dv->loop_id = loop_id;
+ dv->deptype = dep->type;
+
+ // Create the template of the system to operate on.
+ // Add one dimension at the beginning, and one row for the extra constraint.
+- int nb_par = src->domain->NbColumns - 2 - src->depth;
+- CandlMatrix* testsyst =
+- candl_matrix_malloc(mat->NbRows + 1, mat->NbColumns + 1);
+- for (pos = 0; pos < mat->NbRows; ++pos)
+- {
+- CANDL_assign(testsyst->p[pos][0], mat->p[pos][0]);
+- for (j = 1; j < mat->NbColumns; ++j)
+- CANDL_assign(testsyst->p[pos][j + 1], mat->p[pos][j]);
+- }
++ int nb_par = src->domain->nb_parameters;
++ osl_relation_p testsyst = osl_relation_pmalloc(precision,
++ mat->nb_rows + 1,
++ mat->nb_columns + 1);
++ for (pos = 0; pos < mat->nb_rows; ++pos) {
++ osl_int_assign(precision, &testsyst->m[pos][0], mat->m[pos][0]);
++ for (j = 1; j < mat->nb_columns; ++j)
++ osl_int_assign(precision, &testsyst->m[pos][j + 1],mat->m[pos][j]);
++ }
++
+ int has_eq, has_pos, has_neg, has_cst;
+ int scal1, scal2;
+- for (i = 1; i <= ddv_size; ++i)
+- {
+- // Test for '='.
+- CANDL_set_si(testsyst->p[pos][0], 0);
+- CANDL_set_si(testsyst->p[pos][1 + i], 1);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
+- CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0);
+- has_eq = candl_ddv_has_point(testsyst);
+-
+- // Test for '>'.
+- CANDL_set_si(testsyst->p[pos][0], 1);
+- CANDL_set_si(testsyst->p[pos][1 + i], 1);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
+- CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1);
+- has_pos = candl_ddv_has_point(testsyst);
+-
+- // Test for '<'.
+- CANDL_set_si(testsyst->p[pos][0], 1);
+- CANDL_set_si(testsyst->p[pos][1 + i], -1);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1);
+- CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1);
+- has_neg = candl_ddv_has_point(testsyst);
+-
+- // Test for constant distance.
+- // min(x_R^i - x_S^i)
+- // max(x_R^i - x_S^i) = - min(- x_R^i + x_S^i)
+- CANDL_set_si(testsyst->p[pos][0], 0);
+- CANDL_set_si(testsyst->p[pos][1], 1);
+- CANDL_set_si(testsyst->p[pos][1 + i], -1);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1);
+- CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0);
+- has_cst = candl_ddv_constant_val(testsyst, &scal1, nb_par);
+-
++ for (i = 1; i <= ddv_size; ++i) {
++ // Test for '='.
++ osl_int_set_si(precision, &testsyst->m[pos][0], 0);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1);
++ osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0);
++ has_eq = pip_has_rational_point(testsyst, NULL, 1);
++
++ // Test for '>'.
++ osl_int_set_si(precision, &testsyst->m[pos][0], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1);
++ osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1);
++ has_pos = pip_has_rational_point(testsyst, NULL, 1);
++
++ // Test for '<'.
++ osl_int_set_si(precision, &testsyst->m[pos][0], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i], -1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1);
++ has_neg = pip_has_rational_point(testsyst, NULL, 1);
++
++ // Test for constant distance.
++ // min(x_R^i - x_S^i)
++ // max(x_R^i - x_S^i) = - min(- x_R^i + x_S^i)
++ osl_int_set_si(precision, &testsyst->m[pos][0], 0);
++ osl_int_set_si(precision, &testsyst->m[pos][1], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i], -1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0);
++ has_cst = candl_ddv_constant_val(testsyst, &scal1, nb_par);
++
++ if (has_cst) {
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1);
++ osl_int_set_si(precision, &testsyst->m[pos][1], 1);
++ has_cst = candl_ddv_constant_val(testsyst, &scal2, nb_par);
++ scal2 *= -1;
+ if (has_cst)
+- {
+- CANDL_set_si(testsyst->p[pos][1 + i], 1);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
+- CANDL_set_si(testsyst->p[pos][1], 1);
+- has_cst = candl_ddv_constant_val(testsyst, &scal2, nb_par);
+- scal2 *= -1;
+- if (has_cst)
+- has_cst = (scal1 == scal2);
+- }
+-
+- if (has_cst && scal1 != 0)
+- {
+- candl_ddv_set_type_at (dv, candl_dv_scalar, i - 1);
+- candl_ddv_set_value_at (dv, scal1, i - 1);
+- }
+- else if (has_pos && has_neg)
+- candl_ddv_set_type_at (dv, candl_dv_star, i - 1);
+- else if (has_pos)
+- candl_ddv_set_type_at (dv, candl_dv_plus, i - 1);
+- else if (has_neg)
+- candl_ddv_set_type_at (dv, candl_dv_minus, i - 1);
+- else if (has_eq)
+- {
+- candl_ddv_set_type_at (dv, candl_dv_eq, i - 1);
+- candl_ddv_set_value_at (dv, 0, i - 1);
+- }
+-
+- // Reset the constraint.
+- CANDL_set_si(testsyst->p[pos][0], 0);
+- CANDL_set_si(testsyst->p[pos][1], 0);
+- CANDL_set_si(testsyst->p[pos][1 + i], 0);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 0);
+- CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0);
++ has_cst = (scal1 == scal2);
+ }
+
++ if (has_cst && scal1 != 0) {
++ candl_ddv_set_type_at(dv, candl_dv_scalar, i - 1);
++ candl_ddv_set_value_at(dv, scal1, i - 1);
++ }
++ else if (has_pos && has_neg)
++ candl_ddv_set_type_at(dv, candl_dv_star, i - 1);
++ else if (has_pos)
++ candl_ddv_set_type_at(dv, candl_dv_plus, i - 1);
++ else if (has_neg)
++ candl_ddv_set_type_at(dv, candl_dv_minus, i - 1);
++ else if (has_eq) {
++ candl_ddv_set_type_at(dv, candl_dv_eq, i - 1);
++ candl_ddv_set_value_at(dv, 0, i - 1);
++ }
++
++ // Reset the constraint.
++ osl_int_set_si(precision, &testsyst->m[pos][0], 0);
++ osl_int_set_si(precision, &testsyst->m[pos][1], 0);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i], 0);
++ osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 0);
++ osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0);
++ }
++
+ return dv;
+ }
+
+@@ -449,38 +423,39 @@ candl_ddv_create_from_dep(CandlDependence* dep, int loop_id, int ddv_size)
+ *
+ */
+ CandlDDV*
+-candl_ddv_extract_in_loop(CandlProgram* program, CandlDependence* deps,
+- int loop_id)
+-{
+- CandlDependence* tmp;
++candl_ddv_extract_in_loop(osl_scop_p scop, osl_dependence_p deps,
++ int loop_id) {
++ osl_dependence_p tmp;
++ candl_statement_usr_p src_usr, dst_usr;
+ CandlDDV* head = NULL;
+ CandlDDV* last = NULL;
+ int i;
+
+- for (tmp = deps; tmp; tmp = tmp->next)
+- {
+- CandlStatement* src = tmp->source;
+- CandlStatement* dst = tmp->target;
+-
+- // Iterate on all dependences that lie within the given loop.
+- for (i = 0; i < min(src->depth, dst->depth); ++i)
+- if (src->index[i] == dst->index[i] && dst->index[i] == loop_id)
+- break;
+- if (i == min(src->depth, dst->depth))
+- continue;
+- // The dependence involves statement carried by the loop.
+- // Convert it into dependence vector.
+- CandlDDV* dv = candl_ddv_create_from_dep(tmp, loop_id, i + 1);
+-
+- // Append the dependence vector to the list.
+- if (head == NULL)
+- head = last = dv;
+- else
+- {
+- last->next = dv;
+- last = dv;
+- }
++ for (tmp = deps; tmp; tmp = tmp->next) {
++ osl_statement_p src = tmp->stmt_source_ptr;
++ osl_statement_p dst = tmp->stmt_target_ptr;
++ src_usr = src->usr;
++ dst_usr = dst->usr;
++
++ // Iterate on all dependences that lie within the given loop.
++ for (i = 0; i < min(src_usr->depth, dst_usr->depth); ++i)
++ if (src_usr->index[i] == dst_usr->index[i] &&
++ dst_usr->index[i] == loop_id)
++ break;
++ if (i == min(src_usr->depth, dst_usr->depth))
++ continue;
++ // The dependence involves statement carried by the loop.
++ // Convert it into dependence vector.
++ CandlDDV* dv = candl_ddv_create_from_dep(tmp, loop_id, i + 1);
++
++ // Append the dependence vector to the list.
++ if (head == NULL)
++ head = last = dv;
++ else {
++ last->next = dv;
++ last = dv;
+ }
++ }
+
+ return head;
+ }
+@@ -493,11 +468,10 @@ candl_ddv_extract_in_loop(CandlProgram* program, CandlDependence* deps,
+ *
+ */
+ int
+-candl_loops_are_permutable(CandlProgram* program, CandlDependence* deps,
+- int loop_id1, int loop_id2)
+-{
+- CandlDDV* l1 = candl_ddv_extract_in_loop (program, deps, loop_id1);
+- CandlDDV* l2 = candl_ddv_extract_in_loop (program, deps, loop_id2);
++candl_loops_are_permutable(osl_scop_p scop, osl_dependence_p deps,
++ int loop_id1, int loop_id2) {
++ CandlDDV* l1 = candl_ddv_extract_in_loop(scop, deps, loop_id1);
++ CandlDDV* l2 = candl_ddv_extract_in_loop(scop, deps, loop_id2);
+
+ // One of the loop do not carry any dependence.
+ if (l1 == NULL || l2 == NULL)
+@@ -511,79 +485,75 @@ candl_loops_are_permutable(CandlProgram* program, CandlDependence* deps,
+
+ int loop_dim_1 = -1;
+ int loop_dim_2 = -1;
+- int i, j;
+- CandlStatement* stm;
+- for (j = 0; j < program->nb_statements; ++j)
+- {
+- stm = program->statement[j];
+- for (i = 0; i < stm->depth; ++i)
+- if (stm->index[i] == loop_id1)
+- loop_dim_1 = i;
+- else if (stm->index[i] == loop_id2)
+- loop_dim_2 = i;
+- if (loop_dim_1 != -1 && loop_dim_2 != -1)
+- break;
+- }
++ int i;
++ candl_statement_usr_p usr;
++ osl_statement_p stm = scop->statement;
++ for (; stm != NULL; stm = stm->next) {
++ usr = stm->usr;
++ for (i = 0; i < usr->depth; ++i)
++ if (usr->index[i] == loop_id1)
++ loop_dim_1 = i;
++ else if (usr->index[i] == loop_id2)
++ loop_dim_2 = i;
++ if (loop_dim_1 != -1 && loop_dim_2 != -1)
++ break;
++ }
+
+ int is_pos_1 = 0;
+ int is_neg_1 = 0;
+ int is_pos_2 = 0;
+ int is_neg_2 = 0;
+ int is_star = 0;
+- for (; dv; dv = dv->next)
+- {
+- switch (dv->data[loop_dim_1].type)
+- {
+- case candl_dv_plus:
+- is_pos_1 = 1;
+- break;
+- case candl_dv_minus:
+- is_neg_1 = 1;
+- break;
+- case candl_dv_scalar:
+- if (dv->data[loop_dim_1].value > 0)
+- is_pos_1 = 1;
+- else if (dv->data[loop_dim_1].value < 0)
+- is_neg_1 = 1;
+- break;
+- case candl_dv_star:
+- is_star = 1;
+- break;
+- default:
+- break;
+- }
+- switch (dv->data[loop_dim_2].type)
+- {
+- case candl_dv_plus:
+- is_pos_2 = 1;
+- break;
+- case candl_dv_minus:
+- is_neg_2 = 1;
+- break;
+- case candl_dv_scalar:
+- if (dv->data[loop_dim_2].value > 0)
+- is_pos_2 = 1;
+- else if (dv->data[loop_dim_2].value < 0)
+- is_neg_2 = 1;
+- break;
+- case candl_dv_star:
+- is_star = 1;
+- break;
+- default:
+- break;
+- }
+- if ((is_pos_1 && is_neg_1) || (is_pos_2 && is_neg_2) || is_star)
+- {
+- candl_ddv_free (l1);
+- candl_ddv_free (l2);
+- return 0;
+- }
++ for (; dv; dv = dv->next) {
++ switch (dv->data[loop_dim_1].type) {
++ case candl_dv_plus:
++ is_pos_1 = 1;
++ break;
++ case candl_dv_minus:
++ is_neg_1 = 1;
++ break;
++ case candl_dv_scalar:
++ if (dv->data[loop_dim_1].value > 0)
++ is_pos_1 = 1;
++ else if (dv->data[loop_dim_1].value < 0)
++ is_neg_1 = 1;
++ break;
++ case candl_dv_star:
++ is_star = 1;
++ break;
++ default:
++ break;
+ }
+-
+- candl_ddv_free (l1);
+- candl_ddv_free (l2);
+-
+-
++ switch (dv->data[loop_dim_2].type) {
++ case candl_dv_plus:
++ is_pos_2 = 1;
++ break;
++ case candl_dv_minus:
++ is_neg_2 = 1;
++ break;
++ case candl_dv_scalar:
++ if (dv->data[loop_dim_2].value > 0)
++ is_pos_2 = 1;
++ else if (dv->data[loop_dim_2].value < 0)
++ is_neg_2 = 1;
++ break;
++ case candl_dv_star:
++ is_star = 1;
++ break;
++ default:
++ break;
++ }
++ if ((is_pos_1 && is_neg_1) || (is_pos_2 && is_neg_2) || is_star) {
++ candl_ddv_free(l1);
++ candl_ddv_free(l2);
++ return 0;
++ }
++ }
++
++ candl_ddv_free(l1);
++ candl_ddv_free(l2);
++
++
+ return ! ((is_pos_1 && is_neg_2) || (is_neg_1 && is_pos_2));
+ }
+
+diff --git a/source/dependence.c b/source/dependence.c
+index 41afccf..c8a61dc 100644
+--- a/source/dependence.c
++++ b/source/dependence.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: september 18th 2003 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -40,11 +40,20 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+-#include <candl/candl.h>
+-
+-#include <candl/piplib-wrapper.h>
+-
+ #include <assert.h>
++#include <candl/macros.h>
++#include <candl/dependence.h>
++#include <candl/scop.h>
++#include <candl/statement.h>
++#include <candl/util.h>
++#include <candl/matrix.h>
++#include <candl/piplib.h>
++#include <candl/piplib-wrapper.h>
++#include <osl/macros.h>
++#include <osl/scop.h>
++#include <osl/statement.h>
++#include <osl/relation.h>
++#include <osl/extensions/dependence.h>
+
+ #ifdef CANDL_SUPPORTS_ISL
+ # undef Q // Thank you polylib...
+@@ -55,154 +64,106 @@
+ #endif
+
+
+-
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-
+-
+ /**
+- * candl_dependence_print_structure function:
+- * Displays a CandlDependence structure (dependence) into a file (file,
+- * possibly stdout) in a way that trends to be understandable without falling
+- * in a deep depression or, for the lucky ones, getting a headache... It
+- * includes an indentation level (level) in order to work with others
+- * print_structure functions.
+- * - 18/09/2003: first version.
++ * candl_dependence_get_relation_ref_source_in_dep function:
++ * This function return the corresponding osl_relation_p of
++ * the ref_source
+ */
+-void candl_dependence_print_structure(FILE* file,
+- candl_dependence_p dependence,
+- int level)
+-{
+- int j, first = 1;
+-
+- if (dependence != NULL)
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "+-- CandlDependence\n");
+- }
+- else
+- { for(j=0; j<level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "+-- NULL dependence\n");
+- }
+-
+- while (dependence != NULL)
+- { if (!first)
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "| CandlDependence\n");
+- }
+- else
+- first = 0;
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
+-
+- /* Go to the right level and print the type. */
+- for(j=0; j<=level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "Type: ");
+- switch (dependence->type)
+- {
+- case CANDL_UNSET : fprintf(file, "UNSET\n"); break;
+- case CANDL_RAW : fprintf(file, "RAW (flow)\n"); break;
+- case CANDL_WAR : fprintf(file, "WAR (anti)\n"); break;
+- case CANDL_WAW : fprintf(file, "WAW (output)\n"); break;
+- case CANDL_RAR : fprintf(file, "RAR (input)\n"); break;
+- case CANDL_RAW_SCALPRIV : fprintf(file, "RAW_SCALPRIV (scalar priv)\n"); break;
+- default : fprintf(file, "unknown\n"); break;
+- }
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
+-
+- /* Go to the right level and print the depth. */
+- for(j=0; j<=level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "Depth: %d\n", dependence->depth);
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
+-
+- /* Print the source statement. */
+- candl_statement_print_structure(file, dependence->source, level+1);
+-
+- /* Print the target statement. */
+- candl_statement_print_structure(file, dependence->target, level+1);
+-
+- /* Print the dependence polyhedron. */
+- candl_matrix_print_structure(file, dependence->domain, level+1);
+-
+- dependence = dependence->next;
+-
+- /* Next line. */
+- if (dependence != NULL)
+- { for (j=0; j<=level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "V\n");
+- }
+- }
++osl_relation_p
++candl_dependence_get_relation_ref_source_in_dep(osl_dependence_p tmp) {
++ if (tmp->ref_source_access_ptr != NULL)
++ return tmp->ref_source_access_ptr;
++ int count = 0;
++ osl_relation_p elt = NULL;
++ osl_relation_list_p access;
++ access = tmp->stmt_source_ptr->access;
++ for (; access != NULL ; access = access->next) {
++ elt = access->elt;
++ if (count == tmp->ref_source)
++ break;
++ count++;
++ }
++ tmp->ref_source_access_ptr = elt;
++ return elt;
++}
+
+- /* The last line. */
+- for(j=0; j<=level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
++/**
++ * candl_dependence_get_relation_ref_target_in_dep function:
++ * same as candl_dependence_get_relation_ref_source_in_dep but for the target
++ */
++osl_relation_p
++candl_dependence_get_relation_ref_target_in_dep(osl_dependence_p tmp) {
++ if (tmp->ref_target_access_ptr != NULL)
++ return tmp->ref_target_access_ptr;
++ int count = 0;
++ osl_relation_list_p access;
++ osl_relation_p elt = NULL;
++ access = tmp->stmt_target_ptr->access;
++ for (; access != NULL ; access = access->next) {
++ elt = access->elt;
++ if (count == tmp->ref_target)
++ break;
++ count++;
++ }
++ tmp->ref_target_access_ptr = elt;
++ return elt;
+ }
+
+
+-/* candl_dependence_print function:
+- * This function prints the content of a CandlDependence structure (dependence)
+- * into a file (file, possibly stdout).
++
++/**
++ * candl_dependence_get_array_refs_in_dep function:
++ * This function return the array indices referenced in the
++ * dependence.
+ */
+-void candl_dependence_print(FILE * file, candl_dependence_p dependence)
+-{
+- candl_dependence_print_structure(file, dependence, 0);
++void candl_dependence_get_array_refs_in_dep(osl_dependence_p tmp,
++ int* refs, int* reft) {
++ if (! tmp)
++ return;
++
++ osl_relation_p src, targ;
++
++ src = candl_dependence_get_relation_ref_source_in_dep(tmp);
++ targ = candl_dependence_get_relation_ref_target_in_dep(tmp);
++
++ *refs = osl_relation_get_array_id(src);
++
++ *reft = osl_relation_get_array_id(targ);
+ }
+
+
+-/* candl_dependence_pprint function:
+- * This function prints the content of a CandlDependence structure (dependence)
++/* osl_dependence_pprint function:
++ * This function prints the content of a osl_dependence_p structure (dependence)
+ * into a file (file, possibly stdout) as a Graphviz input file.
+ * See http://www.graphviz.org
+ * - 08/12/2005: first version.
+ */
+-void candl_dependence_pprint(FILE * file, candl_dependence_p dependence)
+-{
++void candl_dependence_pprint(FILE * file, osl_dependence_p dependence) {
+ int i = 0;
+-
++
+ fprintf(file, "digraph G {\n");
+
+ fprintf(file, "# Data Dependence Graph\n");
+ fprintf(file, "# Generated by Candl "CANDL_RELEASE" "CANDL_VERSION" bits\n");
+- while (dependence != NULL)
+- {
+- fprintf(file, " S%d -> S%d [label=\" ", dependence->source->label,
+- dependence->target->label);
+- switch (dependence->type)
+- {
+- case CANDL_UNSET : fprintf(file, "UNSET"); break;
+- case CANDL_RAW : fprintf(file, "RAW") ; break;
+- case CANDL_WAR : fprintf(file, "WAR") ; break;
+- case CANDL_WAW : fprintf(file, "WAW") ; break;
+- case CANDL_RAR : fprintf(file, "RAR") ; break;
+- case CANDL_RAW_SCALPRIV : fprintf(file, "RAW_SCALPRIV (scalar-priv)") ; break;
+- default : fprintf(file, "unknown"); break;
+- }
+- fprintf(file, " depth %d, ref %d->%d \"];\n", dependence->depth,
+- dependence->ref_source,
+- dependence->ref_target);
+- dependence = dependence->next;
+- i++;
++ while (dependence != NULL) {
++ fprintf(file, " S%d -> S%d [label=\" ", dependence->label_source,
++ dependence->label_target);
++ switch (dependence->type) {
++ case OSL_UNDEFINED : fprintf(file, "UNSET"); break;
++ case OSL_DEPENDENCE_RAW : fprintf(file, "RAW") ; break;
++ case OSL_DEPENDENCE_WAR : fprintf(file, "WAR") ; break;
++ case OSL_DEPENDENCE_WAW : fprintf(file, "WAW") ; break;
++ case OSL_DEPENDENCE_RAR : fprintf(file, "RAR") ; break;
++ case OSL_DEPENDENCE_RAW_SCALPRIV :
++ fprintf(file, "RAW_SCALPRIV (scalar-priv)") ; break;
++ default : fprintf(file, "unknown"); break;
+ }
++ fprintf(file, " depth %d, ref %d->%d \"];\n", dependence->depth,
++ dependence->ref_source,
++ dependence->ref_target);
++ dependence = dependence->next;
++ i++;
++ }
+
+ if (i>4)
+ fprintf(file, "# Number of edges = %i\n}\n", i);
+@@ -217,135 +178,25 @@ void candl_dependence_pprint(FILE * file, candl_dependence_p dependence)
+ * dependence graph.
+ * - 20/03/2006: first version.
+ */
+-void candl_dependence_view(candl_dependence_p dependence)
+-{
++void candl_dependence_view(osl_dependence_p dep) {
+ FILE * temp_output;
+-
+- temp_output = fopen(CANDL_TEMP_OUTPUT, "w");
+- candl_dependence_pprint(temp_output, dependence);
++ temp_output = fopen(CANDL_TEMP_OUTPUT,"w+");
++ candl_dependence_pprint(temp_output, dep);
+ fclose(temp_output);
+- system("(dot -Tps "CANDL_TEMP_OUTPUT" | gv - &) && rm -f "CANDL_TEMP_OUTPUT);
+-}
+-
+-
+-/**
+- * Returns a string containing the dependence, formatted to fit the
+- * .scop representation.
+- *
+- */
+-static
+-char*
+-candl_program_deps_to_string(CandlDependence* dependence)
+-{
+- CandlDependence* tmp = dependence;
+- int refs = 0, reft = 0;
+- int i, j, k;
+- int nb_deps;
+- int buffer_size = 2048;
+- int szbuff;
+- char* buffer = (char*) malloc(buffer_size * sizeof(char));
+- char buff[1024];
+- char* type;
+- char* pbuffer;
+-
+- for (tmp = dependence, nb_deps = 0; tmp; tmp = tmp->next, ++nb_deps)
++ /* check the return to remove the warning compilation */
++ if(system("dot -Tps "CANDL_TEMP_OUTPUT" | gv - && rm -f "CANDL_TEMP_OUTPUT" &"))
+ ;
+- sprintf(buffer, "# Number of dependences\n%d\n", nb_deps);
+- if (nb_deps)
+- {
+- for (tmp = dependence, nb_deps = 1; tmp; tmp = tmp->next, ++nb_deps)
+- {
+- /* Compute the type of the dependence, and the array id
+- accessed. */
+- switch (tmp->type)
+- {
+- case CANDL_UNSET:
+- type = "UNSET";
+- break;
+- case CANDL_RAW:
+- type = "RAW #(flow)";
+- refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
+- reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
+- break;
+- case CANDL_WAR:
+- type = "WAR #(anti)";
+- refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
+- reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
+- break;
+- case CANDL_WAW:
+- type = "WAW #(output)";
+- refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
+- reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
+- break;
+- case CANDL_RAR:
+- type = "RAR #(input)";
+- refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
+- reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
+- break;
+- case CANDL_RAW_SCALPRIV:
+- type = "RAW_SCALPRIV #(scalar priv)";
+- refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
+- reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
+- break;
+- default:
+- exit(1);
+- break;
+- }
+- /* Quick consistency check. */
+- if (refs != reft)
+- CANDL_FAIL("Internal error. refs != reft\n");
+-
+- /* Output dependence information. */
+- sprintf(buff, "# Description of dependence %d\n"
+- "# type\n%s\n# From statement id\n%d\n"
+- "# To statement id\n%d\n# Depth \n%d\n# Array id\n%d\n"
+- "# Dependence domain\n%d %d\n", nb_deps, type,
+- tmp->source->label, tmp->target->label, tmp->depth,
+- refs, tmp->domain->NbRows, tmp->domain->NbColumns);
+- strcat(buffer, buff);
+- /* Output dependence domain. */
+- pbuffer = buffer + strlen(buffer);
+- for (i = 0; i < tmp->domain->NbRows; ++i)
+- {
+- for (j = 0; j < tmp->domain->NbColumns; ++j)
+- {
+- sprintf(buff, "%lld ", CANDL_get_si(tmp->domain->p[i][j]));
+- szbuff = strlen(buff);
+- if (szbuff == 2)
+- *(pbuffer++) = ' ';
+- for (k = 0; k < szbuff; ++k)
+- *(pbuffer++) = buff[k];
+- }
+- *(pbuffer++) = '\n';
+- }
+- *(pbuffer++) = '\0';
+- /* Increase the buffer size if needed. Conservatively assume a
+- dependence is never larger than 2k. */
+- szbuff = strlen(buffer);
+- if (szbuff + 2048 > buffer_size)
+- {
+- buffer = (char*) realloc(buffer, (buffer_size *= 2) *
+- sizeof(char));
+- if (buffer == NULL)
+- CANDL_FAIL("Error: memory overflow");
+- buffer[szbuff] = '\0';
+- }
+- }
+- }
+-
+- return buffer;
+ }
+
++
+ #ifdef CANDL_SUPPORTS_ISL
+
+-struct isl_set*
+-isl_set_from_piplib_matrix(struct isl_ctx* ctx,
+- PipMatrix* matrix,
+- int nparam);
+-PipMatrix*
+-isl_set_to_piplib_matrix(struct isl_ctx* ctx,
+- struct isl_set* set,
+- int nparam);
++struct isl_set* isl_set_from_piplib_matrix(struct isl_ctx* ctx,
++ osl_relation_p matrix,
++ int nparam);
++osl_relation_p isl_set_to_piplib_matrix(struct isl_ctx* ctx,
++ struct isl_set* set,
++ int nparam);
+ /**
+ * candl_dependence_isl_simplify function:
+ *
+@@ -353,33 +204,35 @@ isl_set_to_piplib_matrix(struct isl_ctx* ctx,
+ * Useful for polyhedra that contain large coefficient values.
+ *
+ */
+-CandlDependence* candl_dependence_isl_simplify(CandlDependence* dep,
+- CandlProgram* program)
+-{
+- if (dep == NULL || program == NULL)
++osl_dependence_p candl_dependence_isl_simplify(osl_dependence_p dep,
++ osl_scop_p scop) {
++ if (dep == NULL || scop == NULL)
+ return dep;
+
+- CandlDependence* tmp;
+- PipMatrix* context = (PipMatrix*) program->context;
+- int nparam = context->NbColumns - 2;
+-
+- struct isl_ctx* ctx = isl_ctx_alloc ();
+-
+- for (tmp = dep; tmp; tmp = tmp->next)
+- {
+- // 1- Convert the dependence polyhedron into ISL set.
+- struct isl_set* set =
+- isl_set_from_piplib_matrix(ctx, tmp->domain, nparam);
+-
+- // 2- Simplify the ISL set.
+- set = isl_set_detect_equalities(set);
+-
+- // 3- Convert back into Candl matrix representation.
+- PipMatrix* newdom = isl_set_to_piplib_matrix(ctx, set, nparam);
+- isl_set_free (set);
+- candl_matrix_free (tmp->domain);
+- tmp->domain = (CandlMatrix*) newdom;
+- }
++ osl_dependence_p tmp;
++ osl_relation_p context = scop->context;
++ int nparam = context->nb_parameters;
++
++ struct isl_ctx* ctx = isl_ctx_alloc();
++
++ for (tmp = dep; tmp; tmp = tmp->next) {
++ // 1- Convert the dependence polyhedron into ISL set.
++
++ struct isl_set* set = isl_set_from_piplib_matrix(ctx, tmp->domain, nparam);
++
++ // 2- Simplify the ISL set.
++ set = isl_set_detect_equalities(set);
++
++ // 3- Convert back into Candl matrix representation.
++ osl_relation_p newdom = isl_set_to_piplib_matrix(ctx, set, nparam);
++ isl_set_free(set);
++ newdom->nb_output_dims = tmp->domain->nb_output_dims;
++ newdom->nb_input_dims = tmp->domain->nb_input_dims;
++ newdom->nb_local_dims = tmp->domain->nb_local_dims;
++ newdom->nb_parameters = tmp->domain->nb_parameters;
++ osl_relation_free(tmp->domain);
++ tmp->domain = newdom;
++ }
+
+ /// FIXME: Some dead ref.
+ //isl_ctx_free (ctx);
+@@ -390,476 +243,76 @@ CandlDependence* candl_dependence_isl_simplify(CandlDependence* dep,
+ #endif
+
+
+-
+-/**
+- * candl_dependence_print_scop function:
+- * This function adds to the .scop file provided as the 'input' the
+- * optional tags to represent the dependences 'dependence' of the
+- * program. Finally, it prints the updated .scop to the file 'output'.
+- *
+- *
+- */
+-#ifdef CANDL_SUPPORTS_SCOPLIB
+-/**
+- * Read one dependence from a string.
+- *
++/* candl_dependence_init_fields:
++ * Set the various other fields of the dependence structure
+ */
+-static
+-CandlDependence* candl_dependence_read_one_dep(char* str, char** next,
+- CandlProgram* program)
+-{
+- CandlDependence* dep = candl_dependence_malloc();
+- CandlMatrix* msource = NULL;
+- CandlMatrix* mtarget = NULL;
+- char buffer[1024];
+-
+- int i, j, k;
+- int id;
+- int id2;
+- /* # Description of dependence xxx */
+- for (; *str != '\n'; ++str);
+- ++str;
+-
+- /* # type */
+- for (; *str != '\n'; ++str);
+- ++str;
+-
+- /* {RAW,RAR,WAR,WAW} #(type) */
+- for (i = 0; *str != ' '; ++str, ++i)
+- buffer[i] = *str;
+- buffer[i] = '\0';
+- if (! strcmp(buffer, "RAW"))
+- dep->type = CANDL_RAW;
+- else if (! strcmp(buffer, "RAR"))
+- dep->type = CANDL_RAR;
+- else if (! strcmp(buffer, "WAR"))
+- dep->type = CANDL_WAR;
+- else if (! strcmp(buffer, "WAW"))
+- dep->type = CANDL_WAW;
+- else if (! strcmp(buffer, "RAW_SCALPRIV"))
+- dep->type = CANDL_RAW_SCALPRIV;
+- for (; *str != '\n'; ++str);
+- ++str;
+-
+- /* # From statement xxx */
+- for (; *str != '\n'; ++str);
+- ++str;
+- /* stmt-id */
+- for (i = 0; *str != '\n'; ++str, ++i)
+- buffer[i] = *str;
+- ++str;
+- buffer[i] = '\0';
+- id = atoi(buffer);
+- for (i = 0; i < program->nb_statements; ++i)
+- if (program->statement[i]->label == id)
+- {
+- dep->source = program->statement[i];
+- break;
+- }
+-
+- /* # To statement xxx */
+- for (; *str != '\n'; ++str);
+- ++str;
+- /* stmt-id */
+- for (i = 0; *str != '\n'; ++str, ++i)
+- buffer[i] = *str;
+- ++str;
+- buffer[i] = '\0';
+- id = atoi(buffer);
+- for (i = 0; i < program->nb_statements; ++i)
+- if (program->statement[i]->label == id)
+- {
+- dep->target = program->statement[i];
+- break;
+- }
+-
+- /* # Depth */
+- for (; *str != '\n'; ++str);
+- ++str;
+- /* depth */
+- for (i = 0; *str != '\n'; ++str, ++i)
+- buffer[i] = *str;
+- ++str;
+- buffer[i] = '\0';
+- dep->depth = atoi(buffer);
+-
+- /* # Array id */
+- for (; *str != '\n'; ++str);
+- ++str;
+- /* array-id */
+- for (i = 0; *str != '\n'; ++str, ++i)
+- buffer[i] = *str;
+- ++str;
+- buffer[i] = '\0';
+- id = atoi(buffer);
+- switch (dep->type)
+- {
+- case CANDL_RAW:
+- case CANDL_RAW_SCALPRIV:
+- msource = dep->source->written;
+- mtarget = dep->target->read;
+- break;
+- case CANDL_WAR:
+- msource = dep->source->read;
+- mtarget = dep->target->written;
+- break;
+- case CANDL_WAW:
+- msource = dep->source->written;
+- mtarget = dep->target->written;
+- break;
+- case CANDL_RAR:
+- msource = dep->source->read;
+- mtarget = dep->target->read;
+- break;
+- default:
+- exit(1);
++void candl_dependence_init_fields(osl_scop_p scop, osl_dependence_p dep) {
++
++ osl_statement_p iter;
++ candl_statement_usr_p usr;
++ osl_relation_p array_s, array_t;
++
++ /* source statement */
++ iter = scop->statement;
++ for (; iter != NULL ; iter = iter->next) {
++ usr = iter->usr;
++ if (usr->label == dep->label_source) {
++ dep->stmt_source_ptr = iter;
+ break;
+ }
+- for (i = 0; i < msource->NbRows && msource->p[i][0] != id; ++i)
+- ;
+- if (i < msource->NbRows)
+- dep->ref_source = i;
+- for (i = 0; i < mtarget->NbRows && mtarget->p[i][0] != id; ++i)
+- ;
+- if (i < mtarget->NbRows)
+- dep->ref_target = i;
+-
+- /* # Dependence domain */
+- for (; *str != '\n'; ++str);
+- ++str;
+-
+- /* nb-row nb-col */
+- for (i = 0; *str != ' '; ++str, ++i)
+- buffer[i] = *str;
+- ++str;
+- buffer[i] = '\0';
+- id = atoi(buffer);
+- for (i = 0; *str != '\n'; ++str, ++i)
+- buffer[i] = *str;
+- ++str;
+- buffer[i] = '\0';
+- id2 = atoi(buffer);
+-
+- dep->domain = candl_matrix_malloc(id, id2);
+- /* Read matrix elements. */
+- for (j = 0; j < id; ++j)
+- {
+- for (k = 0; k < id2; ++k)
+- {
+- while (*str && *str == ' ')
+- str++;
+- for (i = 0; *str != '\n' && *str != ' '; ++str, ++i)
+- buffer[i] = *str;
+- buffer[i] = '\0';
+- ++str;
+- CANDL_set_si(dep->domain->p[j][k], atoi(buffer));
+- }
+- if (*(str - 1) != '\n')
+- {
+- for (; *str != '\n'; ++str);
+- ++str;
+- }
+- }
+- /* Store the next character in the string to be analyzed. */
+- *next = str;
+-
+- return dep;
+-}
+-
+-/**
+- * Retrieve a CandlDependence list from the option tag in the scop.
+- *
+- */
+-CandlDependence* candl_dependence_read_from_scop(scoplib_scop_p scop,
+- CandlProgram* program)
+-{
+- CandlDependence* first = NULL;
+- CandlDependence* currdep = NULL;
+-
+- char* deps = scoplib_scop_tag_content(scop,
+- "<dependence-polyhedra>",
+- "</dependence-polyhedra>");
+-
+- /* No dependence, nothing to do. */
+- if (deps == NULL)
+- return NULL;
+-
+- /* Keep the starting address of the array. */
+- char* base = deps;
+-
+- int i;
+- int depcount;
+- /* Get the number of dependences. */
+- char buffer_nb[32];
+- /* # Number of dependences */
+- for (; *deps != '\n'; ++deps);
+- ++deps;
+- for (i = 0; *deps != '\n'; ++i, ++deps)
+- buffer_nb[i] = *deps;
+- buffer_nb[i] = '\0';
+- ++deps;
+- int nbdeps = atoi (buffer_nb);
+- char* next;
+-
+- /* For each of them, read 1 and shift of the read size. */
+- for (depcount = 0; depcount < nbdeps; ++depcount)
+- {
+- CandlDependence* adep =
+- candl_dependence_read_one_dep(deps, &next, program);
+- if (first == NULL)
+- currdep = first = adep;
+- else
+- {
+- currdep->next = adep;
+- currdep = currdep->next;
+- }
+- deps = next;
+- }
+-
+- /* Be clean. */
+- free(base);
+-
+- return first;
+-}
+-
+-/**
+- * Update the scop option tag with the dependence list.
+- *
+- */
+-void candl_dependence_update_scop_with_deps(scoplib_scop_p scop,
+- CandlDependence* dependence)
+-{
+- char* start;
+- char* stop;
+- char* content;
+- char* olddeps = NULL;
+- char* newdeps;
+- char* newopttags;
+- char* curr;
+- char* tmp;
+- int size = 0;
+- int size_newdeps;
+- int size_olddeps = 0;
+- int size_optiontags;
+-
+- start = stop = scop->optiontags;
+- /* Get the candl tag, if any. */
+- content = scoplib_scop_tag_content(scop, "<candl>", "</candl>");
+- if (content)
+- {
+- /* Get the dependence tag, if any. */
+- olddeps = scoplib_scop_tag_content_from_string
+- (content, "<dependence-polyhedra>", "</dependence-polyhedra>");
+- /* Seek for the correct start/stop characters to insert
+- dependences. */
+- if (olddeps)
+- {
+- size = size_olddeps = strlen(olddeps);
+- while (start && *start && strncmp(start, olddeps, size))
+- ++start;
+- stop = start + size;
+- }
+- else
+- {
+- size = strlen(content);
+- while (start && *start && strncmp(start, content, size))
+- ++start;
+- stop = start;
+- }
+- }
+-
+- /* Convert the program dependences to dotscop representation. */
+- newdeps = candl_program_deps_to_string(dependence);
+-
+- /* Compute the new size of the full options tags, and allocate a new
+- string. */
+- size_newdeps = newdeps ? strlen(newdeps) : 0;
+- size_optiontags = scop->optiontags ? strlen(scop->optiontags) : 0;
+- if (content == NULL)
+- size = strlen("<candl>") + strlen("</candl>") +
+- strlen("<dependence-polyhedra>")
+- + strlen("</dependence-polyhedra>");
+- else if (olddeps == NULL)
+- size = strlen("<dependence-polyhedra>") + strlen("</dependence-polyhedra>");
+- else
+- size = 0;
+- newopttags = (char*) malloc((size_newdeps + size_optiontags
+- - size_olddeps + size + 1)
+- * sizeof(char));
+- if (newopttags == NULL)
+- CANDL_FAIL("Error: memory overflow");
+- curr = newopttags;
+-
+- /* Copy the beginning of the options. */
+- for (tmp = scop->optiontags; tmp != start; ++tmp)
+- *(curr++) = *tmp;
+- *curr = '\0';
+- /* Copy the candl tags, if needed. */
+- if (content == NULL)
+- {
+- strcat(newopttags, "<candl>\n");
+- curr += strlen("<candl>\n");
+- }
+- if (olddeps == NULL)
+- {
+- strcat(newopttags, "<dependence-polyhedra>\n");
+- curr += strlen("<dependence-polyhedra>\n");
+- }
+- /* Copy the program dependences. */
+- for (tmp = newdeps; tmp && *tmp; ++tmp)
+- *(curr++) = *tmp;
+- *curr = '\0';
+- /* Copy the candl tags, if needed. */
+- if (olddeps == NULL)
+- {
+- strcat(curr, "</dependence-polyhedra>\n");
+- curr += strlen("</dependence-polyhedra>\n");
+- }
+- if (content == NULL)
+- {
+- strcat(curr, "</candl>\n");
+- curr += strlen("</candl>\n");
+- }
+- /* Copy the remainder of the options. */
+- for (tmp = stop; tmp && *tmp; ++tmp)
+- *(curr++) = *tmp;
+- *curr = '\0';
+-
+- if (scop->optiontags)
+- free(scop->optiontags);
+- scop->optiontags = newopttags;
+-
+- /* Be clean. */
+- if (content)
+- free(content);
+- if (olddeps)
+- free(olddeps);
+- if (newdeps)
+- free(newdeps);
+-}
+-
+-/**
+- * Print the scop, containing the list of dependences.
+- *
+- */
+-void candl_dependence_print_scop(FILE* input, FILE* output,
+- CandlDependence* dependence)
+-{
+- scoplib_scop_p scop;
+-
+- /* Go to the beginning of the file. */
+- rewind(input);
+-
+- /* Re-read the options tags. */
+- scop = scoplib_scop_read(input);
+-
+- /* Embed the dependences in the scop option tag. */
+- candl_dependence_update_scop_with_deps(scop, dependence);
+-
+- /* Dump the .scop. */
+- scoplib_scop_print_dot_scop(output, scop);
+-}
+-#endif
+-
+-
+-/******************************************************************************
+- * Memory deallocation function *
+- ******************************************************************************/
+-
+-
+-/* candl_dependence_free function:
+- * This function frees the allocated memory for a CandlDependence structure.
+- * - 18/09/2003: first version.
+- */
+-void candl_dependence_free(candl_dependence_p dependence)
+-{
+- candl_dependence_p next;
+-
+- while (dependence != NULL)
+- {
+- next = dependence->next;
+- candl_matrix_free(dependence->domain);
+- free(dependence);
+- dependence = next;
+- }
+-}
+-
+-
+-/******************************************************************************
+- * Processing functions *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_dependence_malloc function:
+- * This function allocates the memory space for a CandlDependence structure and
+- * sets its fields with default values. Then it returns a pointer to the
+- * allocated space.
+- * - 07/12/2005: first version.
+- */
+-candl_dependence_p candl_dependence_malloc()
+-{
+- candl_dependence_p dependence;
+-
+- /* Memory allocation for the CandlDependence structure. */
+- dependence = (candl_dependence_p) malloc(sizeof(CandlDependence));
+- if (dependence == NULL)
+- CANDL_FAIL(" Error: memory overflow");
+-
+- /* We set the various fields with default values. */
+- dependence->source = NULL;
+- dependence->target = NULL;
+- dependence->depth = CANDL_UNSET;
+- dependence->type = CANDL_UNSET;
+- dependence->ref_source = CANDL_UNSET;
+- dependence->ref_target = CANDL_UNSET;
+- dependence->domain = NULL;
+- dependence->next = NULL;
+- dependence->usr = NULL;
+-
+- return dependence;
+-}
+-
+-
+-/**
+- * candl_dependence_add function:
+- * This function adds a CandlDependence structure (dependence) at a given place
+- * (now) of a NULL terminated list of CandlDependence structures. The beginning
+- * of this list is (start). This function updates (now) to the end of the loop
+- * list (loop), and updates (start) if the added element is the first one -that
+- * is when (start) is NULL-.
+- * - 18/09/2003: first version.
+- */
+-void candl_dependence_add(candl_dependence_p* start,
+- candl_dependence_p* now,
+- candl_dependence_p dependence)
+-{
+- if (dependence != NULL)
+- {
+- if (*start == NULL)
+- {
+- *start = dependence;
+- *now = *start;
+- }
+- else
+- {
+- (*now)->next = dependence;
+- *now = (*now)->next;
+- }
+-
+- while ((*now)->next != NULL)
+- *now = (*now)->next;
++ }
++ if (iter == NULL) {
++ fprintf(stderr, "[Candl] Can't find the %dth label\n", dep->label_source);
++ exit(1);
++ }
++
++ /* target statement */
++ iter = scop->statement;
++ for (; iter != NULL ; iter = iter->next) {
++ usr = iter->usr;
++ if (usr->label == dep->label_target) {
++ dep->stmt_target_ptr = iter;
++ break;
+ }
++ }
++ if (iter == NULL) {
++ fprintf(stderr, "[Candl] Can't find the %dth label\n", dep->label_target);
++ exit(1);
++ }
++
++ array_s = candl_dependence_get_relation_ref_source_in_dep(dep);
++ if (array_s == NULL) {
++ fprintf(stderr, "[Candl] Can't find the %dth access of the statement :\n",
++ dep->ref_source);
++ osl_statement_dump(stderr, dep->stmt_source_ptr);
++ exit(1);
++ }
++
++ array_t = candl_dependence_get_relation_ref_source_in_dep(dep);
++ if (array_t == NULL) {
++ fprintf(stderr, "[Candl] Can't find the %dth access of the statement :\n",
++ dep->ref_target);
++ osl_statement_dump(stderr, dep->stmt_target_ptr);
++ exit(1);
++ }
++
++ dep->source_nb_output_dims_domain = dep->stmt_source_ptr->domain->nb_output_dims;
++ dep->source_nb_output_dims_access = array_s->nb_output_dims;
++
++ dep->target_nb_output_dims_domain = dep->stmt_target_ptr->domain->nb_output_dims;
++ dep->target_nb_output_dims_access = array_t->nb_output_dims;
++
++ dep->source_nb_local_dims_domain = dep->stmt_source_ptr->domain->nb_local_dims;
++ dep->source_nb_local_dims_access = array_s->nb_local_dims;
++ dep->target_nb_local_dims_domain = dep->stmt_target_ptr->domain->nb_local_dims;
++ dep->target_nb_local_dims_access = array_t->nb_local_dims;
+ }
+
+
+ /**
+ * GCD computation.
+ */
+-static
+-int
+-candl_dependence_gcd(int a, int b)
+-{
++static int candl_dependence_gcd(int a, int b) {
+ int z = 1;
+
+ if (a < 0)
+@@ -870,19 +323,17 @@ candl_dependence_gcd(int a, int b)
+ return b;
+ if (b == 0)
+ return a;
+- if (b > a)
+- {
+- int temp = a;
+- a = b;
+- b = temp;
+- }
++ if (b > a) {
++ int temp = a;
++ a = b;
++ b = temp;
++ }
+
+- while (z != 0)
+- {
+- z = a % b;
+- a = b;
+- b = z;
+- }
++ while (z != 0) {
++ z = a % b;
++ a = b;
++ b = z;
++ }
+
+ return a;
+ }
+@@ -891,9 +342,7 @@ candl_dependence_gcd(int a, int b)
+ *
+ *
+ */
+-static
+-int candl_dependence_gcd_test_context (CandlMatrix* system, int id)
+-{
++static int candl_dependence_gcd_test_context(osl_relation_p system, int id) {
+ /* FIXME: implement me! */
+
+ return 1;
+@@ -915,16 +364,18 @@ int candl_dependence_gcd_test_context (CandlMatrix* system, int id)
+ * are also performed before the actual GCD test.
+ *
+ */
+-int candl_dependence_gcd_test(CandlStatement* source,
+- CandlStatement* target,
+- CandlMatrix* system,
+- int level)
+-{
++int candl_dependence_gcd_test(osl_statement_p source,
++ osl_statement_p target,
++ osl_relation_p system,
++ int level) {
+ int i;
+ int gcd;
+ int id;
+ int value;
+ int null_iter, null_param, null_cst, pos_iter, neg_iter;
++ int precision = source->domain->precision;
++ candl_statement_usr_p s_usr = source->usr;
++ candl_statement_usr_p t_usr = target->usr;
+
+ /* Check that the precedence constraint, if any, is not strict in a
+ self-dependence. */
+@@ -937,59 +388,63 @@ int candl_dependence_gcd_test(CandlStatement* source,
+ /* strict_pred = 0; */
+
+ /* Inspect the array access function equalities. */
+- for (id = source->domain->NbRows + target->domain->NbRows;
+- id < system->NbRows && CANDL_get_si(system->p[id][0]) == 0; ++id)
+- {
+- /* Inspect which parts of the access function equality are null,
+- positive or negative. */
+- null_iter = null_param = null_cst = pos_iter = neg_iter = 0;
+- for (i = 1; i < source->depth + target->depth + 1 &&
+- CANDL_get_si(system->p[id][i]) == 0; ++i)
+- ;
+- if (i == source->depth + target->depth + 1)
+- null_iter = 1;
+- else
+- for (pos_iter = 1, neg_iter = 1;
+- i < source->depth + target->depth + 1; ++i)
+- {
+- if (CANDL_get_si(system->p[id][i]) < 0)
+- pos_iter = 0;
+- else if (CANDL_get_si(system->p[id][i]) > 0)
+- neg_iter = 0;
+- }
+- for (; i < system->NbColumns - 1 && CANDL_get_si(system->p[id][i]) == 0;
+- ++i)
+- ;
+- if (i == system->NbColumns - 1)
+- null_param = 1;
+- null_cst = ! CANDL_get_si(system->p[id][system->NbColumns - 1]);
+-
+- /* Some useful ZIV/SIV/MIV tests. */
+- if (null_iter && null_param && !null_cst)
+- return 0;
+- if (null_iter)
+- if (! candl_dependence_gcd_test_context (system, id))
+- return 0;
+- if (null_cst || !null_param)
+- continue;
+-/* FIXME: implement the loop bound check. */
+-/* /\* A clever test on access bounds. *\/ */
+-/* if (null_param && pos_iter && */
+-/* CANDL_get_si(system->p[id][system->NbColumns - 1]) > 0) */
+-/* return 0; */
+-/* if (null_param && neg_iter && */
+-/* CANDL_get_si(system->p[id][system->NbColumns - 1]) < 0) */
+-/* return 0; */
+-
+- /* Compute GCD test for the array access equality. */
+- for (i = 1, gcd = CANDL_get_si(system->p[id][i]);
+- i < source->depth + target->depth; ++i)
+- gcd = candl_dependence_gcd(gcd, CANDL_get_si(system->p[id][i + 1]));
+- value = CANDL_get_si(system->p[id][system->NbColumns - 1]);
+- value = value < 0 ? -value : value;
+- if ((gcd == 0 && value != 0) || value % gcd)
+- return 0;
+- }
++ for (id = source->domain->nb_rows + target->domain->nb_rows;
++ id < system->nb_rows &&
++ osl_int_zero(precision, system->m[id][0]);
++ ++id) {
++ /* Inspect which parts of the access function equality are null,
++ positive or negative. */
++ null_iter = null_param = null_cst = pos_iter = neg_iter = 0;
++
++ for (i = 1; i < s_usr->depth + t_usr->depth + 1 &&
++ osl_int_zero(precision, system->m[id][i]); ++i)
++ ;
++
++ if (i == s_usr->depth + t_usr->depth + 1)
++ null_iter = 1;
++ else
++ for (pos_iter = 1, neg_iter = 1;
++ i < s_usr->depth + t_usr->depth + 1; ++i) {
++ if (osl_int_neg(precision, system->m[id][i]))
++ pos_iter = 0;
++ else if (osl_int_pos(precision, system->m[id][i]))
++ neg_iter = 0;
++ }
++ for (; i < system->nb_columns - 1 &&
++ osl_int_zero(precision, system->m[id][i]) == 0; ++i)
++ ;
++ if (i == system->nb_columns - 1)
++ null_param = 1;
++ null_cst = osl_int_zero(precision, system->m[id][system->nb_columns - 1]);
++
++ /* Some useful ZIV/SIV/MIV tests. */
++ if (null_iter && null_param && !null_cst)
++ return 0;
++ if (null_iter)
++ if (! candl_dependence_gcd_test_context(system, id))
++ return 0;
++ if (null_cst || !null_param)
++ continue;
++ /* FIXME: implement the loop bound check. */
++ /* /\* A clever test on access bounds. *\/ */
++ /* if (null_param && pos_iter && */
++ /* CANDL_get_si(system->p[id][system->NbColumns - 1]) > 0) */
++ /* return 0; */
++ /* if (null_param && neg_iter && */
++ /* CANDL_get_si(system->p[id][system->NbColumns - 1]) < 0) */
++ /* return 0; */
++
++ /* Compute GCD test for the array access equality. */
++ for (i = 1, gcd = osl_int_get_si(precision, system->m[id][i]);
++ i < s_usr->depth + t_usr->depth; ++i)
++ gcd = candl_dependence_gcd(gcd,
++ osl_int_get_si(precision, system->m[id][i + 1]));
++
++ value = osl_int_get_si(precision, system->m[id][system->nb_columns - 1]);
++ value = value < 0 ? -value : value;
++ if ((gcd == 0 && value != 0) || value % gcd)
++ return 0;
++ }
+
+ return 1;
+ }
+@@ -1006,135 +461,243 @@ int candl_dependence_gcd_test(CandlStatement* source,
+ * See the [bastoul and Feautrier, PPL 2005] paper for details !
+ * - source is the source iteration domain,
+ * - target is the target iteration domain,
+- * - array_s is the array list for the source,
+- * - array_t is the array list for the target,
+- * - ref_s is the position of the source reference in array_s,
+- * - ref_s is the position of the target reference in array_t,
++ * - array_s is the access array for the source,
++ * - array_t is the access array for the target,
+ * - depth is the dependence depth,
+ * - before is 1 if the source is textually before the target, 0 otherwise,
+- * - nb_par is the number of parameters.
+ ***
+ * - 13/12/2005: first version (extracted from candl_dependence_system).
+ * - 23/02/2006: a stupid bug corrected in the subscript equality.
+ * - 07/04/2007: fix the precedence condition to respect C. Bastoul PhD thesis
+ */
+-static
+-CandlMatrix * candl_dependence_build_system(source, target, array_s, array_t,
+- ref_s, ref_t, depth, before, nb_par)
+-CandlStatement * source, * target;
+-CandlMatrix * array_s, * array_t ;
+-int ref_s, ref_t, depth, before, nb_par ;
+-{ int i, j, nb_rows, nb_columns, nb_dimensions, constraint, s_dims, t_dims ;
+- CandlMatrix * system ;
+- Entier temp ;
+-
+- CANDL_init(temp) ;
+-
+- /* We calculate the number of dimensions of the considered array. */
+- nb_dimensions = 1;
+- while (((ref_s + nb_dimensions + 1) <= array_s->NbRows) &&
+- (array_s->p[ref_s + nb_dimensions][0] == 0))
+- nb_dimensions ++ ;
+-
+- /* The number of dimensions of the source and target domains. */
+- s_dims = source->domain->NbColumns - nb_par - 2 ;
+- t_dims = target->domain->NbColumns - nb_par - 2 ;
+-
+- /* The number of rows of the system is:
+- * - the number of constraints of the source iteration domain +
+- * - the number of constraints of the target iteration domain +
+- * - the number of dimensions of the considered array (subscript equality) +
+- * - the number of precedence constraints (equal to depth).
+- */
+- nb_rows = source->domain->NbRows + target->domain->NbRows +
+- nb_dimensions + depth ;
+-
+- /* The number of columns of the system is:
+- * - the number of source statement surrounding loops +
+- * - the number of target statement surrounding loops +
+- * - the number of parameters +
+- * - 2 (1 for equality/inequality identifier + 1 for the constant).
+- */
+- nb_columns = s_dims + t_dims + nb_par + 2 ;
+-
+- /* We allocate memory space for the constraint system. */
+- system = candl_matrix_malloc(nb_rows,nb_columns) ;
+-
+- /* Compute the maximal common depth. */
++static osl_dependence_p candl_dependence_build_system(
++ osl_statement_p source, osl_statement_p target,
++ osl_relation_p array_s, osl_relation_p array_t,
++ int depth, int before) {
++ osl_dependence_p dependence;
++ osl_relation_p system;
++ int i, j, k, c;
++ int constraint = 0;
++ int precision = source->domain->precision;
++ int nb_output_dims; // source column
++ int nb_input_dims; // target column
++ int nb_local_dims;
++ int nb_par;
++ int nb_rows, nb_columns;
++ int ind_source_local_domain;
++ int ind_source_local_access;
++ int ind_target_local_domain;
++ int ind_target_local_access;
++ int ind_params;
+ int min_depth = 0;
+- while (min_depth < source->depth && min_depth < target->depth &&
+- source->index[min_depth] == target->index[min_depth])
+- ++min_depth;
+-
+- /* We fill the constraint system (note that there is no need to put zeros
+- * in the empty zones since candl_matrix_alloc initialized all entries to 0):
+- */
+-
+- /* 1. The source iteration domain constraints. */
+- constraint = 0 ;
+- for (i=0;i<source->domain->NbRows;i++)
+- { for (j=0;j<=s_dims;j++)
+- CANDL_assign(system->p[constraint][j],source->domain->p[i][j]) ;
+-
+- for (j=s_dims+1;j<source->domain->NbColumns;j++)
+- CANDL_assign(system->p[constraint][j+t_dims],source->domain->p[i][j]) ;
+-
+- constraint++ ;
++
++ /* Create a new dependence structure */
++ dependence = osl_dependence_malloc();
++
++ /* Compute the maximal common depth. */
++ min_depth = CANDL_min(array_s->nb_output_dims, array_t->nb_output_dims);
++
++ /* Compute the system size */
++ dependence->source_nb_output_dims_domain = source->domain->nb_output_dims;
++ dependence->source_nb_output_dims_access = array_s->nb_output_dims;
++
++ dependence->target_nb_output_dims_domain = target->domain->nb_output_dims;
++ dependence->target_nb_output_dims_access = array_t->nb_output_dims;
++
++ dependence->source_nb_local_dims_domain = source->domain->nb_local_dims;
++ dependence->source_nb_local_dims_access = array_s->nb_local_dims;
++ dependence->target_nb_local_dims_domain = target->domain->nb_local_dims;
++ dependence->target_nb_local_dims_access = array_t->nb_local_dims;
++
++ nb_par = source->domain->nb_parameters;
++ nb_local_dims = dependence->source_nb_local_dims_domain +
++ dependence->source_nb_local_dims_access +
++ dependence->target_nb_local_dims_domain +
++ dependence->target_nb_local_dims_access;
++ nb_output_dims = dependence->source_nb_output_dims_domain +
++ dependence->source_nb_output_dims_access;
++ nb_input_dims = dependence->target_nb_output_dims_domain +
++ dependence->target_nb_output_dims_access;
++
++ nb_columns = nb_output_dims + nb_input_dims + nb_local_dims + nb_par + 2;
++ nb_rows = source->domain->nb_rows + target->domain->nb_rows +
++ array_s->nb_rows + array_t->nb_rows +
++ min_depth +
++ depth;
++
++ system = osl_relation_pmalloc(precision, nb_rows, nb_columns);
++
++ /* Compute some indexes */
++ ind_source_local_domain = 1 + nb_output_dims + nb_input_dims;
++ ind_source_local_access = ind_source_local_domain + dependence->source_nb_local_dims_domain;
++ ind_target_local_domain = ind_source_local_access + dependence->source_nb_local_dims_access;
++ ind_target_local_access = ind_target_local_domain + dependence->target_nb_local_dims_domain;
++ ind_params = ind_target_local_access + dependence->target_nb_local_dims_access;
++
++ /* 1. Copy the source domain */
++ for (i = 0 ; i < source->domain->nb_rows ; i++) {
++ /* eq/in */
++ osl_int_assign(precision,
++ &system->m[constraint][0], source->domain->m[i][0]);
++ /* output dims */
++ k = 1;
++ j = 1;
++ for (c = source->domain->nb_output_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], source->domain->m[i][j]);
++ /* local dims (no input in domain, so j is the same) */
++ k = ind_source_local_domain;
++ for (c = source->domain->nb_local_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], source->domain->m[i][j]);
++ /* params + const */
++ k = ind_params;
++ for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], source->domain->m[i][j]);
++ constraint++;
+ }
+-
+- /* 2. The target iteration domain constraints. */
+- for (i = 0; i < target->domain->NbRows; i++)
+- { CANDL_assign(system->p[constraint][0],target->domain->p[i][0]) ;
+-
+- for (j = 1; j < target->domain->NbColumns; j++)
+- CANDL_assign(system->p[constraint][j + s_dims], target->domain->p[i][j]) ;
+-
+- constraint++ ;
++
++ /* 2. Copy the target domain */
++ for (i = 0 ; i < target->domain->nb_rows ; i++) {
++ /* eq/in */
++ osl_int_assign(precision,
++ &system->m[constraint][0], target->domain->m[i][0]);
++ /* output dims */
++ k = 1 + nb_output_dims;
++ j = 1;
++ for (c = target->domain->nb_output_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], target->domain->m[i][j]);
++ /* local dims (no input in domain, so j is the same) */
++ k = ind_target_local_domain;
++ for (c = target->domain->nb_local_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], target->domain->m[i][j]);
++ /* params + const */
++ k = ind_params;
++ for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], target->domain->m[i][j]);
++ constraint++;
+ }
+-
+- int subeq = 0;
+-
+- /* 3. The equality of the subscripts. */
+- for (i = 0; i < nb_dimensions; i++)
+- { /* Source iterator coefficients part. */
+- for (j = 1; j <= s_dims; j++)
+- CANDL_assign(system->p[constraint][j], array_s->p[ref_s + i][j]) ;
+-
+- /* Target iterator coefficients part (negative). */
+- for (j = 1; j <= t_dims; j++)
+- { CANDL_oppose(temp, array_t->p[ref_t + i][j]) ;
+- CANDL_assign(system->p[constraint][j + s_dims], temp) ;
++
++ /* 3. Copy the source access */
++ for (i = 0 ; i < array_s->nb_rows ; i++) {
++ /* eq/in */
++ osl_int_assign(precision,
++ &system->m[constraint][0], array_s->m[i][0]);
++ /* output dims */
++ k = 1 + source->domain->nb_output_dims;
++ j = 1;
++ for (c = array_s->nb_output_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_s->m[i][j]);
++ /* link input dims access to the output dims domain */
++ k = 1;
++ for (c = array_s->nb_input_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_s->m[i][j]);
++ /* local dims */
++ k = ind_source_local_access;
++ for (c = array_s->nb_local_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_s->m[i][j]);
++ /* params + const */
++ k = ind_params;
++ for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_s->m[i][j]);
++
++ constraint++;
++ }
++
++ /* 4. Copy the target access */
++ for (i = 0 ; i < array_t->nb_rows ; i++) {
++ /* eq/in */
++ osl_int_assign(precision,
++ &system->m[constraint][0], array_t->m[i][0]);
++ /* output dims */
++ k = 1 + nb_output_dims + target->domain->nb_output_dims;
++ j = 1;
++ for (c = array_t->nb_output_dims ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_t->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k], system->m[constraint][k]);
+ }
+-
+- /* Parameters and constant coefficients part. */
+- for (j = 1; j <= nb_par + 1; j++)
+- CANDL_subtract(system->p[constraint][j + s_dims + t_dims],
+- array_s->p[ref_s + i][j + s_dims],
+- array_t->p[ref_t + i][j + t_dims]) ;
+- constraint++ ;
+- subeq++;
++ /* link input dims access to the output dims domain */
++ k = 1 + nb_output_dims;
++ for (c = array_t->nb_input_dims ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_t->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k], system->m[constraint][k]);
++ }
++ /* local dims */
++ k = ind_target_local_access;
++ for (c = array_t->nb_local_dims ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_t->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k], system->m[constraint][k]);
++ }
++ /* params + const */
++ k = ind_params;
++ for (c = nb_par+1 ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k], array_t->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k], system->m[constraint][k]);
++ }
++ constraint++;
+ }
+-
+- /* 4. The precedence constraints (their number is equal to depth). */
+- for (i = 0; i < depth; i++)
+- { /* i = i' for all dimension less than depth. */
+- CANDL_set_si(system->p[constraint][i + 1], -1) ;
+- CANDL_set_si(system->p[constraint][s_dims + i + 1], 1) ;
+- if (i == depth - 1)
+- {
+- /* i <= i' at dimension depth if source is textually before target. */
+- CANDL_set_si(system->p[constraint][0], 1) ;
+- /* If source is textually after target, this is obviously i < i'. */
+- if (before || depth < min_depth)
+- //if (before)
+- CANDL_set_si(system->p[constraint][nb_columns - 1], -1);
+- }
+-
+- constraint++ ;
++
++
++ /* 5. Set the equality between the output access */
++ /* Note here that the equality between the 2 Arr are necessarily equal */
++ k = 1 + source->domain->nb_output_dims;
++ j = 1 + nb_output_dims + target->domain->nb_output_dims;
++ for (i = 0 ; i < min_depth ; i++, k++, j++) {
++ osl_int_set_si(precision, &system->m[constraint][k], -1);
++ osl_int_set_si(precision, &system->m[constraint][j], 1);
++ constraint++;
+ }
++
++ /* 6. The precedence constraints */
++ int min_dim = 0;
++ while (min_dim < ((candl_statement_usr_p)source->usr)->depth &&
++ min_dim < ((candl_statement_usr_p)target->usr)->depth &&
++ ((candl_statement_usr_p)source->usr)->index[min_dim] ==
++ ((candl_statement_usr_p)target->usr)->index[min_dim])
++ ++min_dim;
++
++ k = 1;
++ j = 1 + nb_output_dims;
++ for (i = 0; i < depth; i++, k++, j++) {
++ /* i = i' for all dimension less than depth. */
++ osl_int_set_si(precision, &system->m[constraint][k], -1);
++ osl_int_set_si(precision, &system->m[constraint][j], 1);
++ if (i == depth - 1) {
++ /* i <= i' at dimension depth if source is textually before target. */
++ osl_int_set_si(precision, &system->m[constraint][0], 1);
++ /* If source is textually after target, this is obviously i < i'. */
++ if (before || depth < min_dim) // sub 1 for the Arr dim
++ osl_int_set_si(precision, &system->m[constraint][nb_columns - 1], -1);
++ }
+
+- CANDL_clear(temp) ;
+- return system ;
++ constraint++;
++ }
++
++ system->nb_output_dims = nb_output_dims;
++ system->nb_input_dims = nb_input_dims;
++ system->nb_parameters = nb_par;
++ system->nb_local_dims = nb_local_dims;
++ system->type = OSL_UNDEFINED;
++
++ dependence->domain = system;
++
++ return dependence;
+ }
+
+
+@@ -1157,49 +720,53 @@ int ref_s, ref_t, depth, before, nb_par ;
+ * - 18/09/2003: first version.
+ * - 09/12/2005: few corrections and polishing.
+ */
+-candl_dependence_p candl_dependence_system(CandlStatement* source,
+- CandlStatement* target,
+- CandlMatrix* context,
+- CandlMatrix* array_s,
+- CandlMatrix* array_t,
+- int ref_s, int ref_t,
+- int type, int depth)
+-{
+- candl_dependence_p dependence = NULL;
+- CandlMatrix * system;
++osl_dependence_p candl_dependence_system(osl_statement_p source,
++ osl_statement_p target,
++ osl_relation_p context,
++ osl_relation_p array_s,
++ osl_relation_p array_t,
++ int ref_s, int ref_t,
++ int type, int depth) {
++ candl_statement_usr_p s_usr = source->usr;
++ candl_statement_usr_p t_usr = target->usr;
++ osl_dependence_p dependence = NULL;
+
+ /* First, a trivial case: for two different statements at depth 0, there is
+ * a dependence only if the source is textually before the target.
+ */
+- if ((source != target) && (depth == 0) && (source->label > target->label))
++ if ((source != target) && (depth == 0) &&
++ (s_usr->label > t_usr->label))
+ return NULL;
+-
++
+ /* We build the system of constraints. */
+- system = candl_dependence_build_system(source, target,
+- array_s, array_t, ref_s, ref_t,
+- depth,
+- (source->label >= target->label),
+- context->NbColumns-2);
++ dependence = candl_dependence_build_system(source, target,
++ array_s, array_t,
++ depth,
++ (s_usr->label >=
++ t_usr->label));
+
+ /* We start by simple SIV/ZIV/GCD tests. */
+- if (! candl_dependence_gcd_test(source, target, system, depth))
++ if (!candl_dependence_gcd_test(source, target, dependence->domain, depth)) {
++ osl_dependence_free(dependence);
+ return NULL;
++ }
+
+- if (pip_has_rational_point (system, context, 1))
+- {
+- dependence = candl_dependence_malloc();
+-
+- /* We set the various fields with corresponding values. */
+- dependence->type = type;
+- dependence->depth = depth;
+- dependence->source = source;
+- dependence->target = target;
+- dependence->ref_source = ref_s;
+- dependence->ref_target = ref_t;
+- dependence->domain = system;
+- }
+- else
+- candl_matrix_free(system);
++ if (pip_has_rational_point(dependence->domain, context, 1)) {
++ /* We set the various fields with corresponding values. */
++ dependence->ref_source = ref_s;
++ dependence->ref_target = ref_t;
++ dependence->label_source = ((candl_statement_usr_p)source->usr)->label;
++ dependence->label_target = ((candl_statement_usr_p)target->usr)->label;
++ dependence->type = type;
++ dependence->depth = depth;
++ dependence->stmt_source_ptr = source;
++ dependence->stmt_target_ptr = target;
++ dependence->ref_source_access_ptr = array_s;
++ dependence->ref_target_access_ptr = array_t;
++ } else {
++ osl_dependence_free(dependence);
++ dependence = NULL;
++ }
+
+ return dependence;
+ }
+@@ -1215,20 +782,25 @@ candl_dependence_p candl_dependence_system(CandlStatement* source,
+ * - 07/12/2005: (debug) correction of depth bounds.
+ * - 09/12/2005: We may take commutativity into consideration.
+ */
+-candl_dependence_p candl_dependence_between(CandlStatement* source,
+- CandlStatement* target,
+- CandlMatrix* context,
+- CandlOptions* options)
+-{
+- int i, j, k, min_depth, max_depth;
+- candl_dependence_p new;
+- candl_dependence_p dependence = NULL;
+- candl_dependence_p now;
+-
++osl_dependence_p candl_dependence_between(osl_statement_p source,
++ osl_statement_p target,
++ osl_relation_p context,
++ candl_options_p options) {
++ osl_dependence_p new;
++ osl_dependence_p dependence = NULL;
++ osl_dependence_p now;
++ osl_relation_list_p access_src, access_targ;
++ osl_relation_p elt_src, elt_targ;
++ candl_statement_usr_p s_usr = source->usr;
++ candl_statement_usr_p t_usr = target->usr;
++ int i, min_depth, max_depth;
++ int src_id, targ_id;
++ int ref_s, ref_t;
++
+ /* If the statements commute and the user asks to use this information to
+ * simplify the dependence graph, we return no dependences.
+ */
+- if (options->commute && candl_statement_commute(source, target))
++ if (options->commute && candl_util_statement_commute(source, target))
+ return NULL;
+
+ /* In the case of a self-dependence, the dependence depth can be as low as 1
+@@ -1237,155 +809,209 @@ candl_dependence_p candl_dependence_between(CandlStatement* source,
+ * In the case of different statements, the dependence depth can be as low
+ * as 0 and as high as the number of shared loops.
+ */
+- if (source == target)
+- {
+- min_depth = 1;
+- max_depth = source->depth;
+- }
+- else
+- {
+- /* Depth 0 is for statements that don't share any loop. */
+- min_depth = (source->index[0] == target->index[0]) ? 1 : 0;
+-
+- max_depth = 0;
+- while ((max_depth < source->depth) &&
+- (max_depth < target->depth) &&
+- (source->index[max_depth] == target->index[max_depth]))
+- max_depth++;
+- }
+-
+- /* Flow and output-dependences analysis. */
+- for (j = 0; j < source->written->NbRows; j++)
+- if (CANDL_notzero_p(source->written->p[j][0]))
+- {
+- /* Flow-dependences analysis. */
+- if (options->raw)
+- for (k = 0; k < target->read->NbRows; k++)
+- if (CANDL_eq(target->read->p[k][0], source->written->p[j][0]))
+- for (i = min_depth; i <= max_depth; i++)
+- {
+- new = candl_dependence_system(source, target, context,
+- source->written, target->read,
+- j, k, CANDL_RAW, i);
+- candl_dependence_add(&dependence, &now, new);
+- }
+- /* Output-dependences analysis. */
+- if (options->waw)
+- for (k = 0; k < target->written->NbRows; k++)
+- if (CANDL_eq(target->written->p[k][0], source->written->p[j][0]))
+- for (i = min_depth; i <= max_depth; i++)
+- {
+- new = candl_dependence_system(source, target, context,
+- source->written,
+- target->written, j, k,
+- CANDL_WAW, i);
+- candl_dependence_add(&dependence, &now, new);
+- }
+- }
+-
+- /* Anti and input-dependences analysis. */
+- for (j = 0; j < source->read->NbRows; j++)
+- if (source->read->p[j][0] != 0)
+- {
+- /* Anti-dependences analysis. */
+- if (options->war)
+- for (k = 0; k < target->written->NbRows; k++)
+- if (CANDL_eq(target->written->p[k][0], source->read->p[j][0]))
+- for (i = min_depth; i <= max_depth; i++)
+- {
+- new = candl_dependence_system(source, target, context,
+- source->read, target->written,
+- j, k, CANDL_WAR, i);
+- candl_dependence_add(&dependence, &now, new);
+- }
+- /* Input-dependences analysis. */
+- if (options->rar)
+- for (k = 0; k < target->read->NbRows; k++)
+- if (CANDL_eq(target->read->p[k][0], source->read->p[j][0]))
+- for (i = min_depth; i <= max_depth; i++)
+- {
+- new = candl_dependence_system(source, target, context,
+- source->read, target->read,
+- j, k, CANDL_RAR, i);
+- candl_dependence_add(&dependence, &now, new);
+- }
+- }
++ if (source == target) {
++ min_depth = 1;
++ max_depth = s_usr->depth;
++ } else {
++ /* Depth 0 is for statements that don't share any loop. */
++ if (s_usr->depth > 0 && t_usr->depth > 0)
++ min_depth = (s_usr->index[0] == t_usr->index[0]) ? 1 : 0;
++ else
++ min_depth = 0;
+
++ max_depth = 0;
++ while ((max_depth < s_usr->depth) &&
++ (max_depth < t_usr->depth) &&
++ (s_usr->index[max_depth] == t_usr->index[max_depth]))
++ max_depth++;
++ }
++
++ ref_s = 0;
++ access_src = source->access;
++
++ for (; access_src != NULL; access_src = access_src->next, ref_s++) {
++ elt_src = access_src->elt;
++ src_id = osl_relation_get_array_id(elt_src);
++
++ switch(elt_src->type) {
++
++ /* Anti and input-dependences analysis. */
++ case OSL_TYPE_READ: /* source READ */
++ if (!options->war && !options->rar)
++ break;
++ access_targ = target->access;
++ ref_t = 0;
++ for (; access_targ != NULL; access_targ = access_targ->next, ref_t++) {
++ elt_targ = access_targ->elt;
++ targ_id = osl_relation_get_array_id(elt_targ);
++
++ /* Anti-dependences analysis. */
++ if (elt_targ->type != OSL_TYPE_READ) { /* target WRITE | MAY_WRITE */
++ if (options->war && src_id == targ_id) {
++ for (i = min_depth; i <= max_depth; i++) {
++ new = candl_dependence_system(source, target, context,
++ elt_src, elt_targ,
++ ref_s, ref_t,
++ OSL_DEPENDENCE_WAR, i);
++ osl_dependence_add(&dependence, &now, new);
++ }
++ }
++ }
++ /* Input-dependences analysis. */
++ else { /* target READ */
++ if (options->rar && src_id == targ_id) {
++ for (i = min_depth; i <= max_depth; i++) {
++ new = candl_dependence_system(source, target, context,
++ elt_src, elt_targ,
++ ref_s, ref_t,
++ OSL_DEPENDENCE_RAR, i);
++ osl_dependence_add(&dependence, &now, new);
++ }
++ }
++ }
++ }
++ break;
++
++ default: /* source WRITE | MAY-WRITE */
++ if (!options->raw && !options->waw)
++ break;
++ access_targ = target->access;
++ ref_t = 0;
++ for (; access_targ != NULL; access_targ = access_targ->next, ref_t++) {
++ elt_targ = access_targ->elt;
++ targ_id = osl_relation_get_array_id(elt_targ);
++
++ /* Anti-dependences analysis. */
++ if (elt_targ->type != OSL_TYPE_READ) { /* target WRITE | MAY_WRITE */
++ if (options->waw && src_id == targ_id) {
++ for (i = min_depth; i <= max_depth; i++) {
++ new = candl_dependence_system(source, target, context,
++ elt_src, elt_targ,
++ ref_s, ref_t,
++ OSL_DEPENDENCE_WAW, i);
++ osl_dependence_add(&dependence, &now, new);
++ }
++ }
++ }
++ /* Input-dependences analysis. */
++ else { /* target READ */
++ if (options->raw && src_id == targ_id) {
++ for (i = min_depth; i <= max_depth; i++) {
++ new = candl_dependence_system(source, target, context,
++ elt_src, elt_targ,
++ ref_s, ref_t,
++ OSL_DEPENDENCE_RAW, i);
++ osl_dependence_add(&dependence, &now, new);
++ }
++ }
++ }
++ }
++ break;
++ }
++ }
++
+ return dependence;
+ }
+
+
+-
+-
+-
+ /**
+ * candl_dependence function:
+- * this function builds the dependence graph of a program (program)
++ * this function builds the dependence graph of a scop
+ * according to some user options (options).
+ * - 18/09/2003: first version.
+ */
+-candl_dependence_p candl_dependence(candl_program_p program,
+- CandlOptions* options)
+-{
+- int i, j;
+- candl_dependence_p dependence = NULL;
+- candl_dependence_p new = NULL;
+- candl_dependence_p now;
+- CandlStatement ** statement;
+- CandlMatrix * context;
+-
+- statement = program->statement;
+- context = program->context;
++osl_dependence_p candl_dependence(osl_scop_p scop, candl_options_p options) {
++ if (scop == NULL) { return NULL; }
++
++ osl_dependence_p dependence = NULL;
++ osl_dependence_p new = NULL;
++ osl_dependence_p now;
++ osl_statement_p stmt_i, stmt_j;
++ osl_relation_p context = scop->context;
++
+ if (options->scalar_privatization || options->scalar_expansion)
+- candl_dependence_analyze_scalars (program, options);
+-
+- for (i = 0; i < program->nb_statements; i++)
+- { /* We add self dependence. */
+- /* S->S */
+- new = candl_dependence_between(statement[i], statement[i],
+- context, options);
+- candl_dependence_add(&dependence, &now, new);
+-
+- for (j = i + 1; j < program->nb_statements; j++)
+- { /* And dependences with other statements. */
+- /* S1->S2 */
+- new = candl_dependence_between(statement[i], statement[j],
+- context, options);
+- candl_dependence_add(&dependence, &now, new);
+-
+- /* S2->S1 */
+- new = candl_dependence_between(statement[j], statement[i],
+- context, options);
+- candl_dependence_add(&dependence, &now, new);
+- }
++ candl_dependence_analyze_scalars(scop, options);
++
++ stmt_i = scop->statement;
++ for (; stmt_i != NULL; stmt_i = stmt_i->next) {
++ /* We add self dependence. */
++ /* S->S */
++ new = candl_dependence_between(stmt_i, stmt_i, context, options);
++ osl_dependence_add(&dependence, &now, new);
++
++ stmt_j = stmt_i->next;
++ for (; stmt_j != NULL; stmt_j = stmt_j ->next) {
++ /* And dependences with other statements. */
++ /* S1->S2 */
++ new = candl_dependence_between(stmt_i, stmt_j, context, options);
++ osl_dependence_add(&dependence, &now, new);
++
++ /* S2->S1 */
++ new = candl_dependence_between(stmt_j, stmt_i, context, options);
++ osl_dependence_add(&dependence, &now, new);
+ }
+-
++ }
++
+ /* If scalar analysis is called, remove some useless dependences. */
+ /* LNP: This is subsubmed by the updated prune-with-privatization function. */
+- /* if (options->scalar_privatization || options->scalar_expansion || */
+- /* options->scalar_renaming) */
+- /* candl_dependence_prune_scalar_waw (program, options, &dependence); */
++ /* if (options->scalar_privatization || options->scalar_expansion || */
++ /* options->scalar_renaming) */
++ /* candl_dependence_prune_scalar_waw(scop, options, &dependence); */
+
+ /* Final treatment for scalar analysis. */
+ int check = 0;
+ if (options->scalar_renaming)
+- check = candl_dependence_scalar_renaming (program, options, &dependence);
++ check = candl_dependence_scalar_renaming(scop, options, &dependence);
++
+ if (! check && options->scalar_privatization)
+- candl_dependence_prune_with_privatization (program, options, &dependence);
++ candl_dependence_prune_with_privatization(scop, options, &dependence);
+
+ /* Compute the last writer */
+- if (options->lastwriter) {
+- candl_compute_last_writer(dependence, program);
+- }
++ if (options->lastwriter)
++ candl_compute_last_writer(dependence, scop);
+
++ #if defined(CANDL_COMPILE_PRUNNING_C)
+ /* Remove some transitively covered dependences (experimental). */
+ if (options->prune_dups)
+- dependence = candl_dependence_prune_transitively_covered (dependence);
++ dependence = candl_dependence_prune_transitively_covered(dependence);
++ #endif
+
+ return dependence;
+ }
+
+
++
++/**
++ * candl_dependence_add_extension function:
++ * this function builds the dependence graph for a scop list
++ * according to some user options (options).
++ * For each scop the dependence graph is added in the extension of the scop.
++ * Any old dependence graph in the extension is deleted.
++ *
++ * @param[in,out] scop A osl scop
++ * @param[in] options Candl options
++ */
++void candl_dependence_add_extension(osl_scop_p scop, candl_options_p options) {
++
++ while (scop) {
++ /* Calculating dependences. */
++ osl_dependence_p dep = osl_generic_lookup(scop->extension,
++ OSL_URI_DEPENDENCE);
++ if (dep != NULL) {
++ osl_generic_remove(&scop->extension, OSL_URI_DEPENDENCE);
++ CANDL_info("Deleting old dependences found in the options tag.");
++ }
++
++ dep = candl_dependence(scop, options);
++
++ osl_generic_p data = osl_generic_shell(dep, osl_dependence_interface());
++ data->next = scop->extension;
++ scop->extension = data;
++
++ scop = scop->next;
++ }
++}
++
+ /******************************************************************************
+ * Scalar analysis functions *
+ ******************************************************************************/
+@@ -1393,29 +1019,39 @@ candl_dependence_p candl_dependence(candl_program_p program,
+ /**
+ * candl_dependence_var_is_scalar function:
+ * This function returns true if the variable indexed by 'var_index'
+- * is a scalar in the whole program.
++ * is a scalar in the whole scop.
+ */
+-int
+-candl_dependence_var_is_scalar (candl_program_p program, int var_index)
+-{
+- CandlMatrix* m;
+- int i, j, k, cpt;
+-
+- for (i = 0; i < program->nb_statements; ++i)
+- for (m = program->statement[i]->read, cpt = 0; cpt < 2; ++cpt,
+- m = program->statement[i]->written)
+- for (j = 0; j < m->NbRows; ++j)
+- if (CANDL_get_si(m->p[j][0]) == var_index)
+- {
+- /* Ensure it is not an array. */
+- if (j < m->NbRows - 1 && CANDL_get_si(m->p[j + 1][0]) == 0)
+- return 0;
+- /* Ensure the access function is '0'. */
+- for (k = 1; k < m->NbColumns; ++k)
+- if (CANDL_get_si(m->p[j][k]) != 0)
+- return 0;
+- }
+-
++int candl_dependence_var_is_scalar(osl_scop_p scop, int var_index) {
++ osl_statement_p statement;
++ osl_relation_list_p access;
++ osl_relation_p elt;
++ int precision = scop->context->precision;
++ int i;
++ int id, row;
++
++ statement = scop->statement;
++ while (statement != NULL) {
++ access = statement->access;
++ while (access != NULL) {
++ elt = access->elt;
++ id = osl_relation_get_array_id(elt);
++ row = candl_util_relation_get_line(elt, 0);
++ if (id == var_index) {
++ /* Ensure it is not an array. */
++ if (elt->nb_output_dims > 1)
++ return 0;
++ /* Ensure the access function is '0'. */
++ if (!osl_int_zero(precision, elt->m[row][0]))
++ return 0;
++ for (i = 2; i < elt->nb_columns-2; ++i) /* jmp the 'Arr' */
++ if (!osl_int_zero(precision, elt->m[row][i]))
++ return 0;
++ }
++ access = access->next;
++ }
++ statement = statement->next;
++ }
++
+ return 1;
+ }
+
+@@ -1427,61 +1063,33 @@ candl_dependence_var_is_scalar (candl_program_p program, int var_index)
+ * variable in the statement list.
+ *
+ */
+-static
+-void
+-candl_dependence_expand_scalar(CandlStatement** sl,
+- int scalar_idx)
+-{
+- CandlMatrix* m;
+- int i, l, n, j;
++static void candl_dependence_expand_scalar(osl_statement_p* sl,
++ int scalar_idx) {
++ osl_relation_list_p access;
++ osl_relation_p elt;
++ int id, row;
++ int precision = sl[0]->scattering->precision;
++ int i;
+
+ /* Iterate on all statements of the list. */
+- for (i = 0; sl[i] != NULL; ++i)
+- {
+- /* Check if the scalar is referenced in the 'read' access
+- function. */
+- for (j = 0; j < sl[i]->read->NbRows &&
+- CANDL_get_si(sl[i]->read->p[j][0]) != scalar_idx; ++j)
+- ;
+- /* It is. */
+- if (j < sl[i]->read->NbRows)
+- {
+- /* Add a row to the 'read' matrix, just after the reference
+- to 'scalar_idx'. */
+- m = candl_matrix_malloc (sl[i]->read->NbRows +1,
+- sl[i]->read->NbColumns);
+- for (l = 0; l <= j; ++l)
+- for (n = 0; n < m->NbColumns; ++n)
+- CANDL_assign(m->p[l][n], sl[i]->read->p[l][n]);
+- for (++l; l < m->NbRows; ++l)
+- for (n = 0; n < m->NbColumns; ++n)
+- CANDL_assign(m->p[l][n], sl[i]->read->p[l - 1][n]);
+- for (n = 0; n < m->NbColumns; ++n)
+- CANDL_set_si(m->p[j + 1][n], 0);
+- candl_matrix_free (sl[i]->read);
+- sl[i]->read = m;
+- }
+-
+- /* Same for 'written' access function. */
+- for (j = 0; j < sl[i]->written->NbRows &&
+- CANDL_get_si(sl[i]->written->p[j][0]) != scalar_idx;++j)
+- ;
+- if (j < sl[i]->written->NbRows)
+- {
+- m = candl_matrix_malloc (sl[i]->written->NbRows +1,
+- sl[i]->written->NbColumns);
+- for (l = 0; l <= j; ++l)
+- for (n = 0; n < m->NbColumns; ++n)
+- CANDL_assign(m->p[l][n], sl[i]->written->p[l][n]);
+- for (++l; l < m->NbRows; ++l)
+- for (n = 0; n < m->NbColumns; ++n)
+- CANDL_assign(m->p[l][n], sl[i]->written->p[l - 1][n]);
+- for (n = 0; n < m->NbColumns; ++n)
+- CANDL_set_si(m->p[j + 1][n], 0);
+- candl_matrix_free (sl[i]->written);
+- sl[i]->written = m;
+- }
++ for (i = 0; sl[i] != NULL; ++i) {
++
++ /* Check if the scalar is referenced in the 'read' access
++ function. */
++ access = sl[i]->access;
++ for (; access != NULL ; access = access->next) {
++ elt = access->elt;
++ id = osl_relation_get_array_id(elt);
++ row = candl_util_relation_get_line(elt, 0);
++ if (id == scalar_idx) {
++ row = elt->nb_rows;
++ osl_relation_insert_blank_row(elt, row);
++ osl_relation_insert_blank_column(elt, 1 + elt->nb_output_dims);
++ osl_int_set_si(precision, &elt->m[row][1 + elt->nb_output_dims], -1);
++ elt->nb_output_dims++;
++ }
+ }
++ }
+ }
+
+
+@@ -1490,51 +1098,70 @@ candl_dependence_expand_scalar(CandlStatement** sl,
+ * This function returns a chain of statements as a feshly allocated
+ * array of pointer on statements, of all statements reading or
+ * writing the variable 'var_index', surrounded by the 'level' common
+- * loops of 'dom'. Output is a NULL-terminated array.
++ * loops of 'dom'.
++ * Output is a NULL-terminated array. We don't create a chained list,
++ * because it demands to clone every statements each time, and we need
++ * to clone the field usr too.
+ */
+-CandlStatement**
+-candl_dependence_refvar_chain(candl_program_p program, CandlStatement* dom,
+- int var_index, int level)
+-{
+- /* No or empty program -> no chain! */
+- if (program == NULL || program->nb_statements == 0)
++osl_statement_p* candl_dependence_refvar_chain(osl_scop_p scop,
++ osl_statement_p dom, int var_index, int level) {
++ /* No or empty scop -> no chain! */
++ if (scop == NULL || scop->statement == NULL)
+ return NULL;
+
++ osl_statement_p* res; /* not a chained list, but an array of statement */
++ osl_statement_p statement;
++ candl_statement_usr_p dom_usr;
++ candl_statement_usr_p stmt_usr;
++ int i;
+ int buffer_size = 64;
+- CandlStatement** res =
+- (CandlStatement**) malloc(buffer_size * sizeof(CandlStatement*));
+- int i, j, count = 0;
+- CandlStatement* s;
++ int count = 0;
+
+ /* If no dominator is provided, assume we start with the first statement. */
+ if (dom == NULL)
+- dom = program->statement[0];
+- for (i = 0; i < program->nb_statements && program->statement[i] != dom; ++i)
+- ;
++ dom = scop->statement;
++
++ dom_usr = dom->usr;
++
++ statement = scop->statement;
++ while (statement != NULL && statement != dom)
++ statement = statement->next;
++
+ /* The dominator is not in the list of statements. */
+- if (i == program->nb_statements)
++ if (statement == NULL)
+ return NULL;
+- for (; i < program->nb_statements; ++i)
+- {
+- s = program->statement[i];
+- /* We look for exactly 'level' common loops. */
+- if (s->depth < level)
+- continue;
+- /* Ensure it has 'level' common loop(s) with the dominator. */
+- for (j = 0; j < level&& s->index[j] == dom->index[j]; ++j)
+- ;
+- if (j < level)
+- continue;
+- /* Ensure the variable is referenced. */
+- if (candl_dependence_var_is_ref (s, var_index) != CANDL_VAR_UNDEF)
+- {
+- res[count++] = s;
+- if (count == buffer_size)
+- res = realloc(res, (buffer_size*=2) * sizeof(CandlStatement*));
+- }
++
++ CANDL_malloc(res, osl_statement_p*, sizeof(osl_statement_p) * buffer_size);
++
++ for (; statement != NULL; statement = statement->next) {
++ stmt_usr = statement->usr;
++
++ /* We look for exactly 'level' common loops. */
++ if (stmt_usr->depth < level)
++ continue;
++
++ /* Ensure it has 'level' common loop(s) with the dominator. */
++ for (i = 0; i < level &&
++ stmt_usr->index[i] == dom_usr->index[i];
++ ++i)
++ ;
++
++ if (i < level)
++ continue;
++
++ /* Ensure the variable is referenced. */
++ if (candl_dependence_var_is_ref(statement, var_index) != CANDL_VAR_UNDEF) {
++ if (count == buffer_size) {
++ buffer_size *= 2;
++ CANDL_realloc(res, osl_statement_p*,
++ sizeof(osl_statement_p) * buffer_size);
++ }
++ res[count++] = statement;
+ }
++ }
+
+- res = realloc(res, (count + 1) * sizeof(CandlStatement*));
++ CANDL_realloc(res, osl_statement_p*,
++ sizeof(osl_statement_p) * (count+1));
+ res[count] = NULL;
+
+ return res;
+@@ -1546,30 +1173,44 @@ candl_dependence_refvar_chain(candl_program_p program, CandlStatement* dom,
+ * This function checks if a var 'var_index' is referenced (DEF or
+ * USE) by the statement.
+ */
+-int
+-candl_dependence_var_is_ref(CandlStatement* s, int var_index)
+-{
+- int j;
++int candl_dependence_var_is_ref(osl_statement_p s, int var_index) {
++ osl_relation_list_p access;
++ osl_relation_p elt;
++ int id;
+ int ret = CANDL_VAR_UNDEF;
+-
+- if (s)
+- {
+- for (j = 0; s->read && j < s->read->NbRows; ++j)
+- if (CANDL_get_si(s->read->p[j][0]) == var_index)
+- {
+- ret = CANDL_VAR_IS_USED;
+- break;
+- }
+- for (j = 0; s->written && j < s->written->NbRows; ++j)
+- if (CANDL_get_si(s->written->p[j][0]) == var_index)
+- {
+- if (ret == CANDL_VAR_IS_USED)
+- ret = CANDL_VAR_IS_DEF_USED;
+- else
+- ret = CANDL_VAR_IS_DEF;
+- break;
+- }
++
++ if (s) {
++ /* read access */
++ access = s->access;
++ while (access != NULL) {
++ elt = access->elt;
++ if (elt->type == OSL_TYPE_READ) {
++ id = osl_relation_get_array_id(elt);
++ if (id == var_index) {
++ ret = CANDL_VAR_IS_USED;
++ break;
++ }
++ }
++ access = access->next;
++ }
++
++ /* right access */
++ access = s->access;
++ while (access != NULL) {
++ elt = access->elt;
++ if (elt->type != OSL_TYPE_READ) {
++ id = osl_relation_get_array_id(elt);
++ if (id == var_index) {
++ if (ret == CANDL_VAR_IS_USED)
++ ret = CANDL_VAR_IS_DEF_USED;
++ else
++ ret = CANDL_VAR_IS_DEF;
++ break;
++ }
++ }
++ access = access->next;
+ }
++ }
+
+ return ret;
+ }
+@@ -1580,29 +1221,26 @@ candl_dependence_var_is_ref(CandlStatement* s, int var_index)
+ * This function assigns to the Entier 'lb' the lexmin of variable
+ * 'col'-1 in the polyhedron 'm'.
+ */
+-static
+-void
+-candl_dependence_compute_lb (CandlMatrix* m, Entier* lb, int col)
+-{
++static void candl_dependence_compute_lb(osl_relation_p m, Entier* lb, int col) {
+ PipOptions* options;
+ PipQuast* solution;
+ PipList* l;
+- options = pip_options_init ();
++ options = pip_options_init();
+ options->Simplify = 1;
+ options->Urs_parms = -1;
+ options->Urs_unknowns = -1;
+ /* Compute lexmin. */
+- solution = pip_solve (m, NULL, -1, options);
++ solution = pip_solve_osl(m, NULL, -1, options);
++
+ if ((solution != NULL) &&
+- ((solution->list != NULL) || (solution->condition != NULL)))
+- {
+- l = solution->list;
+- while (col-- > 1)
+- l = l->next;
+- CANDL_assign(*lb, l->vector->the_vector[0]);
+- }
+- pip_options_free (options);
+- pip_quast_free (solution);
++ ((solution->list != NULL) || (solution->condition != NULL))) {
++ l = solution->list;
++ while (col-- > 1)
++ l = l->next;
++ CANDL_assign(*lb, l->vector->the_vector[0]);
++ }
++ pip_options_free(options);
++ pip_quast_free(solution);
+ }
+
+
+@@ -1613,66 +1251,95 @@ candl_dependence_compute_lb (CandlMatrix* m, Entier* lb, int col)
+ * considered iterator dimensions.
+ *
+ */
+-int
+-candl_dependence_check_domain_is_included(CandlStatement* s1,
+- CandlStatement* s2,
+- CandlMatrix* context,
+- int level)
+-{
++int candl_dependence_check_domain_is_included(osl_statement_p s1,
++ osl_statement_p s2,
++ osl_relation_p context,
++ int level) {
++ candl_statement_usr_p s1_usr = s1->usr;
++ candl_statement_usr_p s2_usr = s2->usr;
++ osl_relation_p matrix;
+ int max = level;
+- Entier lb; CANDL_init(lb);
+- max = s1->depth < max ? s1->depth : max;
+- max = s2->depth < max ? s2->depth : max;
+- CandlMatrix* m = candl_matrix_malloc(s2->domain->NbRows + s2->depth - max +1,
+- s2->domain->NbColumns);
+ int i, j;
++ int precision = s2->domain->precision;
++ Entier lb;
++ osl_int_t osl_lb;
++
++ CANDL_init(lb);
++ osl_int_init(precision, &osl_lb);
++
++ if (s1_usr->depth < max) max = s1_usr->depth;
++ if (s2_usr->depth < max) max = s2_usr->depth;
++
++ matrix = osl_relation_pmalloc(precision,
++ s2->domain->nb_rows + s2_usr->depth - max + 1,
++ s2->domain->nb_columns);
++
+ /* Duplicate s2 to the dest matrix. */
+- for (i = 0; i < s2->domain->NbRows; ++i)
+- for (j = 0; j < s2->domain->NbColumns; ++j)
+- CANDL_assign(m->p[i][j], s2->domain->p[i][j]);
++ for (i = 0; i < s2->domain->nb_rows; ++i) {
++ for (j = 0; j < s2->domain->nb_columns; ++j)
++ osl_int_assign(precision,
++ &matrix->m[i][j], s2->domain->m[i][j]);
++ }
++
+ /* Make useless dimensions equal to 1. */
+- for (j = 0; j < s2->depth - max; ++j)
+- {
+- candl_dependence_compute_lb (s2->domain, &lb, j + 1 + max);
+- CANDL_assign(m->p[i][m->NbColumns - 1], lb);
+- CANDL_set_si(m->p[i++][j + 1 + max], -1);
+- }
++ for (j = 0; j < s2_usr->depth - max; ++j) {
++ candl_dependence_compute_lb(s2->domain, &lb, j + 1 + max);
++ #ifdef CANDL_LINEAR_VALUE_IS_INT
++ osl_lb.sp = lb;
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ osl_lb.dp = lb;
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ mpz_set(*((mpz_t*)osl_lb.mp), lb);
++ #endif
++ osl_int_assign(precision,
++ &matrix->m[i][matrix->nb_columns - 1], osl_lb);
++ osl_int_set_si(precision,
++ &matrix->m[i++][j+1+max], -1);
++ }
++
+ /* Iterate on all constraints of s1, and check them. */
+- for (i = 0; i < s1->domain->NbRows; ++i)
+- {
+- /* Skip constraints defining other iterators. */
+- for (j = max + 1; j <= s1->depth; ++j)
+- if (CANDL_get_si(s1->domain->p[i][j]) != 0)
+- break;
+- if (j <= s1->depth)
+- continue;
+- /* Invert the constraint, and add it to m. */
+- for (j = 0; j <= max; ++j)
+- {
+- CANDL_assign(m->p[m->NbRows - 1][j], s1->domain->p[i][j]);
+- CANDL_oppose(m->p[m->NbRows - 1][j], m->p[m->NbRows - 1][j]);
+- }
+- for (j = s1->depth + 1; j < s1->domain->NbColumns; ++j)
+- {
+- CANDL_assign(m->p[m->NbRows - 1][j - s1->depth + s2->depth],
+- s1->domain->p[i][j]);
+- CANDL_oppose(m->p[m->NbRows - 1][j - s1->depth + s2->depth],
+- m->p[m->NbRows - 1][j - s1->depth + s2->depth]);
+- }
+- /* Make the inequality strict. */
+- CANDL_decrement(m->p[m->NbRows - 1][m->NbColumns - 1],
+- m->p[m->NbRows - 1][m->NbColumns - 1]);
+- if (candl_matrix_check_point (m, context))
+- {
+- /* There is a point. dom(s1) - dom(s2) > 0. */
+- CANDL_clear(lb);
+- candl_matrix_free(m);
+- return 0;
+- }
++ for (i = 0; i < s1->domain->nb_rows; ++i) {
++ /* Skip constraints defining other iterators. */
++ for (j = max + 1; j <= s1_usr->depth; ++j) {
++ if (!osl_int_zero(precision, s1->domain->m[i][j]))
++ break;
++ }
++ if (j <= s1_usr->depth)
++ continue;
++ /* Invert the constraint, and add it to matrix. */
++ for (j = 0; j <= max; ++j) {
++ osl_int_assign(precision,
++ &matrix->m[matrix->nb_rows - 1][j],
++ s1->domain->m[i][j]);
++ osl_int_oppose(precision,
++ &matrix->m[matrix->nb_rows - 1][j],
++ matrix->m[matrix->nb_rows - 1][j]);
++ }
++ for (j = s1_usr->depth + 1; j < s1->domain->nb_columns; ++j) {
++ osl_int_assign(precision,
++ &matrix->m[matrix->nb_rows - 1][j - s1_usr->depth + s2_usr->depth],
++ s1->domain->m[i][j]);
++ osl_int_oppose(precision,
++ &matrix->m[matrix->nb_rows - 1][j - s1_usr->depth + s2_usr->depth],
++ matrix->m[matrix->nb_rows - 1][j - s1_usr->depth + s2_usr->depth]);
++ }
++ /* Make the inequality strict. */
++ osl_int_decrement(precision,
++ &matrix->m[matrix->nb_rows - 1][matrix->nb_columns - 1],
++ matrix->m[matrix->nb_rows - 1][matrix->nb_columns - 1]);
++
++ if (candl_matrix_check_point(matrix, context)) {
++ /* There is a point. dom(s1) - dom(s2) > 0. */
++ CANDL_clear(lb);
++ osl_int_clear(precision, &osl_lb);
++ osl_relation_free(matrix);
++ return 0;
+ }
++ }
+
+ CANDL_clear(lb);
+- candl_matrix_free(m);
++ osl_int_clear(precision, &osl_lb);
++ osl_relation_free(matrix);
+
+ return 1;
+ }
+@@ -1680,49 +1347,48 @@ candl_dependence_check_domain_is_included(CandlStatement* s1,
+
+ /**
+ * candl_dependence_extract_scalar_variables function:
+- * This functions returns a -1-terminated array of the program scalar
++ * This functions returns a -1-terminated array of the scop scalar
+ * variables.
+ */
+-int*
+-candl_dependence_extract_scalar_variables (candl_program_p program)
+-{
+- /* FIXME: implement a real buffer. */
+- int scalars[1024];
++int* candl_dependence_extract_scalar_variables(osl_scop_p scop) {
++ osl_statement_p statement;
++ osl_relation_p elt;
++ osl_relation_list_p access;
++ int scalars[1024]; /* FIXME: implement a real buffer. */
+ int checked[1024];
+- int i, j, k, idx, cpt;
++ int i, idx;
+ int count_s = 0, count_c = 0;
+- CandlMatrix* m;
+-
++
+ /* Detect all scalar variables. */
+- for (i = 0; i < program->nb_statements; ++i)
+- for (m = program->statement[i]->read, cpt = 0; cpt < 2; ++cpt,
+- m = program->statement[i]->written)
+- for (j = 0; j < m->NbRows; ++j)
+- {
+- idx = CANDL_get_si(m->p[j][0]);
+- if (idx != 0)
+- {
+- for (k = 0; k < count_s && scalars[k] != idx; ++k)
+- ;
+- if (k == count_s)
+- {
+- for (k = 0; k < count_c && checked[k] != idx; ++k)
+- ;
+- if (k == count_c)
+- {
+- if (candl_dependence_var_is_scalar(program, idx))
+- scalars[count_s++] = idx;
+- else
+- checked[count_c++] = idx;
+- }
+- if (count_s == 1024 || count_c == 1024)
+- CANDL_FAIL("Error: Buffer size too small");
+- }
+- }
+- }
+-
++ statement = scop->statement;
++ while (statement != NULL) {
++ access = statement->access;
++ while (access != NULL) {
++ elt = access->elt;
++ idx = osl_relation_get_array_id(elt);
++
++ for (i = 0; i < count_s && scalars[i] != idx; ++i)
++ ;
++ if (i == count_s) {
++ for (i = 0; i < count_c && checked[i] != idx; ++i)
++ ;
++ if (i == count_c) {
++ if (candl_dependence_var_is_scalar(scop, idx))
++ scalars[count_s++] = idx;
++ else
++ checked[count_c++] = idx;
++ }
++ if (count_s == 1024 || count_c == 1024)
++ CANDL_error("Error: Buffer size too small");
++ }
++ access = access->next;
++ }
++ statement = statement->next;
++ }
++
+ /* Rearrange the array to the exact size. */
+- int* res = (int*) malloc((count_s + 1) * sizeof(int));
++ int *res;
++ CANDL_malloc(res, int*, (count_s + 1) * sizeof(int));
+ for (i = 0; i < count_s; ++i)
+ res[i] = scalars[i];
+ res[i] = -1;
+@@ -1732,88 +1398,46 @@ candl_dependence_extract_scalar_variables (candl_program_p program)
+
+
+ /**
+- * candl_dependence_get_array_refs_in_dep function:
+- * This function return the array indices referenced in the
+- * dependence.
+- */
+-static
+-void
+-candl_dependence_get_array_refs_in_dep (CandlDependence* tmp, int* refs,
+- int* reft)
+-{
+- if (! tmp)
+- return;
+- switch (tmp->type)
+- {
+- case CANDL_RAR:
+- *refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
+- *reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
+- break;
+- case CANDL_RAW:
+- case CANDL_RAW_SCALPRIV:
+- *refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
+- *reft = CANDL_get_si(tmp->target->read->p[tmp->ref_target][0]);
+- break;
+- case CANDL_WAR:
+- *refs = CANDL_get_si(tmp->source->read->p[tmp->ref_source][0]);
+- *reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
+- break;
+- case CANDL_WAW:
+- *refs = CANDL_get_si(tmp->source->written->p[tmp->ref_source][0]);
+- *reft = CANDL_get_si(tmp->target->written->p[tmp->ref_target][0]);
+- break;
+- default:
+- exit(1);
+- }
+-}
+-
+-
+-/**
+- * candl_dependence_prune_scalar_waw function:
++ * osl_dependence_prune_scalar_waw function:
+ * This function removes all WAW dependences between the same scalar
+ * (they are useless dependences).
+ */
+-void
+-candl_dependence_prune_scalar_waw (candl_program_p program,
+- CandlOptions* options,
+- CandlDependence** deps)
+-{
++void osl_dependence_prune_scalar_waw(osl_scop_p scop,
++ candl_options_p options,
++ osl_dependence_p* deps) {
+ int* scalars;
+ int i;
+ int refs, reft;
+- CandlDependence* tmp;
+- CandlDependence* next;
+- CandlDependence* pred = NULL;
++ osl_dependence_p tmp;
++ osl_dependence_p next;
++ osl_dependence_p pred = NULL;
+
+ if (options->verbose)
+ fprintf (stderr, "[Candl] Scalar Analysis: Remove all WAW between the same"
+- " scalar\n");
+-
+- scalars = candl_dependence_extract_scalar_variables (program);
+-
+- for (tmp = *deps; tmp; )
+- {
+- candl_dependence_get_array_refs_in_dep (tmp, &refs, &reft);
+- if (refs == reft && tmp->type == CANDL_WAW)
+- {
+- for (i = 0; scalars[i] != -1 && scalars[i] != refs; ++i)
+- ;
+- if (scalars[i] != -1)
+- {
+- candl_matrix_free (tmp->domain);
+- next = tmp->next;
+- if (pred == NULL)
+- *deps = next;
+- else
+- pred->next = next;
+- free (tmp);
+- tmp = next;
+- continue;
+- }
+- }
+- pred = tmp;
+- tmp = tmp->next;
++ " scalar\n");
++
++ scalars = candl_dependence_extract_scalar_variables(scop);
++
++ for (tmp = *deps; tmp; ) {
++ candl_dependence_get_array_refs_in_dep(tmp, &refs, &reft);
++ if (refs == reft && tmp->type == OSL_DEPENDENCE_WAW) {
++ for (i = 0; scalars[i] != -1 && scalars[i] != refs; ++i)
++ ;
++ if (scalars[i] != -1) {
++ osl_relation_free(tmp->domain);
++ next = tmp->next;
++ if (pred == NULL)
++ *deps = next;
++ else
++ pred->next = next;
++ free(tmp);
++ tmp = next;
++ continue;
++ }
+ }
++ pred = tmp;
++ tmp = tmp->next;
++ }
+
+ free(scalars);
+ }
+@@ -1824,160 +1448,189 @@ candl_dependence_prune_scalar_waw (candl_program_p program,
+ * This function renames scalars in the program. In case scalars have
+ * been renamed, the dependence analysis is re-run.
+ */
+-int
+-candl_dependence_scalar_renaming (candl_program_p program,
+- CandlOptions* options,
+- CandlDependence** deps)
+-{
++int candl_dependence_scalar_renaming(osl_scop_p scop,
++ candl_options_p options,
++ osl_dependence_p* deps) {
++ osl_statement_p *statement; /* not a chained list */
++ osl_statement_p iter;
++ osl_statement_p defs[1024];
++ osl_statement_p uses[1024];
++ osl_statement_p last_def;
++ osl_statement_p *current; /* not a chained list */
++ osl_relation_p elt;
++ osl_relation_list_p access;
++ candl_statement_usr_p usr;
++ candl_statement_usr_p last_usr;
+ int i, j, k;
+- CandlStatement** stmts;
+- CandlStatement* defs[1024];
+- CandlStatement* uses[1024];
+- CandlStatement* current[program->nb_statements];
+- int parts[program->nb_statements];
+- CandlStatement* s;
+- CandlStatement* last_def;
+- CandlMatrix* m;
++ int nb_statements = 0;
++ int *parts;
+ int defs_c, uses_c;
+- int val, cpt, tmp, has_changed = 0;
++ int *scalars;
++ int precision = scop->context->precision;
++ int row;
++ int tmp, has_changed = 0;
+ int newvar = 0;
+
+- for (i = 0; i < program->nb_statements; ++i)
+- current[i] = NULL;
+-
+ if (options->verbose)
+ fprintf (stderr, "[Candl] Scalar Analysis: Perform scalar renaming\n");
+-
++
+ /* Compute the first free variable index seed. */
+- for (i = 0; i < program->nb_statements; ++i)
+- for (m = program->statement[i]->read, cpt = 0; cpt < 2;
+- ++cpt, m = program->statement[i]->written)
+- for (j = 0; j < m->NbRows; ++j)
+- if (CANDL_get_si(m->p[j][0]) >= newvar)
+- newvar = CANDL_get_si(m->p[j][0]) + 1;
++ for (iter = scop->statement; iter != NULL; iter = iter->next) {
++ access = iter->access;
++ for (; access != NULL; access = access->next) {
++ elt = access->elt;
++ tmp = osl_relation_get_array_id(elt);
++ if (tmp >= newvar)
++ newvar = tmp + 1;
++ }
++ nb_statements++;
++ }
+
++ /* Init */
++ CANDL_malloc(current, osl_statement_p*, sizeof(osl_statement_p) * nb_statements);
++ CANDL_malloc(parts, int*, sizeof(int) * nb_statements);
++
+ /* Get the list of scalars. */
+- int* scalars = candl_dependence_extract_scalar_variables (program);
++ scalars = candl_dependence_extract_scalar_variables(scop);
+
+ /* Iterate on all scalars. */
+- for (i = 0; scalars[i] != -1; ++i)
+- {
+- /* Get all statements referencing the scalar. */
+- stmts = candl_dependence_refvar_chain (program, NULL, scalars[i], 0);
+-
+- /* If the chain starts by a USE, we can't do anything. */
+- if (stmts[0] == NULL || candl_dependence_var_is_ref (stmts[0], scalars[i])
+- != CANDL_VAR_IS_DEF)
+- {
+- free (stmts);
+- continue;
+- }
+-
+- /* Get all defs. */
+- for (j = 0, defs_c = 0; stmts[j]; ++j)
+- if (candl_dependence_var_is_ref (stmts[j], scalars[i])
+- == CANDL_VAR_IS_DEF)
+- defs[defs_c++] = stmts[j];
+- /* Get all uses. */
+- for (j = 0, uses_c = 0; stmts[j]; ++j)
+- {
+- val = candl_dependence_var_is_ref (stmts[j], scalars[i]);
+- if (val == CANDL_VAR_IS_USED || val == CANDL_VAR_IS_DEF_USED)
+- uses[uses_c++] = stmts[j];
+- }
+-
+- /* Clean buffer. */
+- for (j = 0; j < program->nb_statements; ++j)
+- current[j] = NULL;
+-
+- free (stmts);
+-
+- /* Iterate on all DEFs. */
+- for (j = 0, last_def = NULL; j < defs_c; ++j)
+- {
+- if (last_def == NULL)
+- last_def = defs[j];
+- else
+- {
+- /* Ensure the current DEF covers all iterations covered
+- by the last checked one. */
+- for (k = 0; k < last_def->depth && k < defs[j]->depth &&
+- last_def->index[k] == defs[j]->index[k]; ++k)
+- ;
+- /* We only need to check when there are common loops. */
+- if (k && ! candl_dependence_check_domain_is_included
+- (last_def, defs[j], program->context, k + 1))
+- {
+- current[defs[j]->label] = last_def;
+- continue;
+- }
+- else
+- last_def = defs[j];
+- }
+- /* Create DEF-USE table. */
+- for (k = 0; k < uses_c; ++k)
+- if (uses[k]->label > defs[j]->label)
+- current[uses[k]->label] = defs[j];
+- }
+-
+- /* Initialize partition table. */
+- for (j = 0; j < program->nb_statements; ++j)
+- parts[j] = -1;
+-
+- /* Create partitions. */
+- for (j = 0; j < defs_c; ++j)
+- for (k = 0; k < program->nb_statements; ++k)
+- if ((current[k] && current[k] == defs[j]) ||
+- (k == defs[j]->label && current[defs[j]->label] == NULL))
+- parts[k] = j;
+-
+- /* Check if it is needed to rename the scalar. */
+- for (j = 0, tmp = -1; j < program->nb_statements; ++j)
+- if (tmp == -1)
+- {
+- if (parts[j] != -1)
+- tmp = parts[j];
+- }
+- else
+- if (parts[j] != -1 && tmp != parts[j])
+- break;
+-
+- /* Rename scalar variable. */
+- if (j != program->nb_statements)
+- for (j = 0, tmp = -1; j < program->nb_statements; ++j)
+- if (parts[j] != -1)
+- {
+- if (tmp == -1)
+- tmp = parts[j];
+- else
+- if (tmp != parts[j])
+- has_changed = 1;
+- s = program->statement[j];
+- for (m = s->read, cpt = 0; cpt < 2; ++cpt, m = s->written)
+- for (k = 0; k < m->NbRows; ++k)
+- if (CANDL_get_si(m->p[k][0]) == scalars[i])
+- {
+- if (options->verbose)
+- fprintf (stderr, "[Candl] Scalar analysis: Renamed "
+- "variable %d to %d at statement S%d\n",
+- scalars[i], newvar + parts[j], j);
+- CANDL_set_si(m->p[k][0], newvar + parts[j]);
+- }
+- }
++ for (i = 0; scalars[i] != -1; ++i) {
++ /* Get all statements referencing the scalar. */
++ statement = candl_dependence_refvar_chain(scop, NULL, scalars[i], 0);
++
++ /* If the chain starts by a USE, we can't do anything. */
++ if (statement[0] == NULL ||
++ candl_dependence_var_is_ref(statement[0], scalars[i])
++ != CANDL_VAR_IS_DEF) {
++ free(statement);
++ continue;
+ }
+
+- /* Redo the full dependence analysis, if needed. */
+- if (has_changed)
+- {
+- int bopt = options->scalar_renaming;
+- options->scalar_renaming = 0;
+- if (options->scalar_privatization)
+- free (program->scalars_privatizable);
+- candl_dependence_free (*deps);
+- *deps = candl_dependence (program, options);
+- options->scalar_renaming = bopt;
++ /* Get all defs and all uses. */
++ defs_c = 0;
++ uses_c = 0;
++ for (j = 0; statement[j]; ++j) {
++ tmp = candl_dependence_var_is_ref(statement[j], scalars[i]);
++ switch (tmp) {
++ case CANDL_VAR_IS_USED:
++ case CANDL_VAR_IS_DEF_USED:
++ uses[uses_c++] = statement[j];
++ break;
++ case CANDL_VAR_IS_DEF:
++ defs[defs_c++] = statement[j];
++ break;
++ }
++ }
++
++ /* Clean buffer. */
++ j = 0;
++ for (iter = scop->statement; iter != NULL; iter = iter->next)
++ current[j++] = NULL;
++
++ free(statement);
++
++ /* Iterate on all DEFs. */
++ last_def = NULL;
++ for (j = 0; j < defs_c; ++j) {
++ if (last_def == NULL) {
++ last_def = defs[j];
++ } else {
++ /* Ensure the current DEF covers all iterations covered
++ by the last checked one. */
++ last_usr = last_def->usr;
++ usr = defs[j]->usr;
++ for (k = 0; k < last_usr->depth && k < usr->depth &&
++ last_usr->index[k] == usr->index[k];
++ ++k)
++ ;
++ /* We only need to check when there are common loops. */
++ if (k && ! candl_dependence_check_domain_is_included
++ (last_def, defs[j], scop->context, k + 1)) {
++ usr = defs[j]->usr;
++ current[usr->label] = last_def;
++ continue;
++ } else {
++ last_def = defs[j];
++ }
++ }
++ /* Create DEF-USE table. */
++ for (k = 0; k < uses_c; ++k) {
++ usr = uses[k]->usr;
++ if (usr->label > ((candl_statement_usr_p)defs[j]->usr)->label)
++ current[usr->label] = defs[j];
++ }
++ }
++
++ /* Initialize partition table. */
++ for (j = 0; j < nb_statements; ++j)
++ parts[j] = -1;
++
++ /* Create partitions. */
++ for (j = 0; j < defs_c; ++j) {
++ usr = defs[j]->usr;
++ for (k = 0; k < nb_statements; ++k)
++ if ((current[k] && current[k] == defs[j]) ||
++ (k == usr->label && current[usr->label] == NULL))
++ parts[k] = j;
++ }
++
++ /* Check if it is needed to rename the scalar. */
++ tmp = -1;
++ for (j = 0; j < nb_statements; ++j)
++ if (tmp == -1) {
++ if (parts[j] != -1)
++ tmp = parts[j];
++ } else {
++ if (parts[j] != -1 && tmp != parts[j])
++ break;
++ }
++
++ /* Rename scalar variable. */
++ if (j != nb_statements) {
++ tmp = -1;
++ j = 0;
++ for (iter = scop->statement ; iter != NULL ; iter = iter->next) {
++ if (parts[j] != -1) {
++ if (tmp == -1)
++ tmp = parts[j];
++ else if (tmp != parts[j])
++ has_changed = 1;
++
++ access = iter->access;
++ for (; access != NULL; access = access->next) {
++ elt = access->elt;
++ row = candl_util_relation_get_line(elt, 0);
++ tmp = osl_relation_get_array_id(elt);
++ if (tmp == scalars[i]) {
++ if (options->verbose)
++ fprintf (stderr, "[Candl] Scalar analysis: Renamed "
++ "variable %d to %d at statement S%d\n",
++ scalars[i], newvar + parts[j], j);
++ osl_int_set_si(precision,
++ &elt->m[row][elt->nb_columns - 1],
++ newvar + parts[j]);
++ }
++ }
++ }
++ j++;
++ }
+ }
+- free (scalars);
++ } /* end Iterate on all scalars */
++
++ /* Redo the full dependence analysis, if needed. */
++ if (has_changed) {
++ int bopt = options->scalar_renaming;
++ options->scalar_renaming = 0;
++ if (options->scalar_privatization)
++ free(((candl_scop_usr_p)scop->usr)->scalars_privatizable);
++ osl_dependence_free(*deps);
++ *deps = candl_dependence(scop, options);
++ options->scalar_renaming = bopt;
++ }
++
++ free(scalars);
++ free(current);
++ free(parts);
+
+ return has_changed;
+ }
+@@ -1988,188 +1641,171 @@ candl_dependence_scalar_renaming (candl_program_p program,
+ * This function returns true if the dependence 'dep' is loop-carried
+ * for loop 'loop_index', false otherwise.
+ */
+-int
+-candl_dependence_is_loop_carried (candl_program_p program,
+- CandlDependence* dep,
+- int loop_index)
+-{
++int candl_dependence_is_loop_carried(osl_scop_p scop,
++ osl_dependence_p dep,
++ int loop_index) {
++ osl_relation_p msrc = NULL, mtarg = NULL;
++ candl_statement_usr_p s_usr = dep->stmt_source_ptr->usr;
++ candl_statement_usr_p t_usr = dep->stmt_target_ptr->usr;
+ int i, j;
++ int k, kp, l;
++ int row_k, row_kp;
++ int precision = scop->context->precision;
++
+ /* Ensure source and sink share common loop 'loop_index', and that
+ dependence depth is consistent with the considered loop. */
+- for (i = 0; i < dep->source->depth; ++i)
+- if (dep->source->index[i] == loop_index)
++ for (i = 0; i < s_usr->depth; ++i)
++ if (s_usr->index[i] == loop_index)
+ break;
+- if (i != dep->depth - 1 || i >= dep->target->depth)
++ if (i != dep->depth - 1 || i >= t_usr->depth)
+ return 0;
+- for (j = 0; j < dep->target->depth; ++j)
+- if (dep->target->index[j] == loop_index)
++ for (j = 0; j < t_usr->depth; ++j)
++ if (t_usr->index[j] == loop_index)
+ break;
+ if (j != i)
+ return 0;
+-
+- int k = 0;
+- int l = 0;
+- CandlMatrix* mats;
+- if (dep->type == CANDL_WAR || dep->type == CANDL_RAR)
+- mats = dep->source->read;
+- else
+- mats = dep->source->written;
+- CandlMatrix* matt;
+- if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV
+- || dep->type == CANDL_RAR)
+- matt = dep->target->read;
+- else
+- matt = dep->target->written;
+-
+- int src_ref_iter = 0;
+- int dst_ref_iter = 0;
+- for (k = 0; k == 0 ||
+- (dep->ref_source + k < mats->NbRows &&
+- CANDL_get_si(mats->p[dep->ref_source + k][0]) == 0); ++k)
+- if (CANDL_get_si(mats->p[dep->ref_source + k][i + 1]) != 0)
+- {
+- src_ref_iter = 1;
+- break;
+- }
+- for (k = 0; k == 0 ||
+- (dep->ref_target + k < matt->NbRows &&
+- CANDL_get_si(matt->p[dep->ref_target + k][0]) == 0); ++k)
+- if (CANDL_get_si(matt->p[dep->ref_target + k][j + 1]) != 0)
+- {
+- dst_ref_iter = 1;
+- break;
+- }
++
++ msrc = candl_dependence_get_relation_ref_source_in_dep(dep);
++ mtarg = candl_dependence_get_relation_ref_target_in_dep(dep);
++
++ /* plus one for the Arr output dim */
++ int src_ref_iter = (candl_util_relation_get_line(msrc, i+1) != -1);
++ int dst_ref_iter = (candl_util_relation_get_line(mtarg,j+1) != -1);
+
+ /* Ensure it is not a basic loop-independent dependence (pure
+ equality of the access functions for the surrounding iterators +
+ parameters + constant, no occurence of the inner loop iterators,
+ and contain the current loop iterator. */
+ int must_test = 0;
+- k = 0;
+- do
+- {
+- // Ensure the reference do reference the current loop iterator
+- // to be tested.
+- if (CANDL_get_si(mats->p[dep->ref_source + k][i + 1]) != 0)
+- {
+- int kp = 0;
+- do
+- {
+- if (CANDL_get_si(matt->p[dep->ref_target + kp][j + 1]) != 0)
+- {
+- // Ensure the access functions are equal for the
+- // surrounding loop iterators, and no inner iterator
+- // is referenced.
+- for (l = 0; l <= i + 1; ++l)
+- if (CANDL_get_si(mats->p[dep->ref_source + k][l]) !=
+- CANDL_get_si(matt->p[dep->ref_target + kp][l]))
+- {
+- must_test = 1;
+- break;
+- }
+- int m = l;
+- if (!must_test)
+- for (; l <= dep->source->depth; ++l)
+- if (CANDL_get_si(mats->p[dep->ref_source + k][l]) != 0)
+- {
+- must_test = 1;
+- break;
+- }
+- if (!must_test)
+- for (; m <= dep->target->depth; ++m)
+- if (CANDL_get_si(matt->p[dep->ref_target + kp][m]) != 0)
+- {
+- must_test = 1;
+- break;
+- }
+- if (!must_test)
+- for (; l < mats->NbColumns; ++l, ++m)
+- if (CANDL_get_si(mats->p[dep->ref_source + k][l]) !=
+- CANDL_get_si(matt->p[dep->ref_target + kp][m]))
+- {
+- must_test = 1;
+- break;
+- }
+- }
+- ++kp;
+- }
+- while (!must_test &&
+- dep->ref_target + kp < matt->NbRows &&
+- CANDL_get_si(matt->p[dep->ref_target + kp][0]) == 0);
+- }
+- ++k;
+- }
++ k = 1; // start after the Arr column
++ row_k = candl_util_relation_get_line(msrc, k);
+ while (!must_test &&
+- dep->ref_source + k < mats->NbRows &&
+- CANDL_get_si(mats->p[dep->ref_source + k][0]) == 0);
++ k < msrc->nb_output_dims &&
++ osl_int_zero(precision, msrc->m[row_k][0])) {
++
++ // Ensure the reference do reference the current loop iterator
++ // to be tested.
++ if (!osl_int_zero(precision, msrc->m[row_k][i])) {
++ kp = 1;
++ row_kp = candl_util_relation_get_line(mtarg, kp);
++
++ while (!must_test &&
++ kp < mtarg->nb_output_dims &&
++ osl_int_zero(precision, mtarg->m[row_kp][0])) {
++
++ if (!osl_int_zero(precision, mtarg->m[row_kp][j])) {
++ // Ensure the access functions are equal for the
++ // surrounding loop iterators, and no inner iterator
++ // is referenced.
++ if (!osl_int_eq(precision,
++ msrc->m[row_k][0], mtarg->m[row_kp][0])) {
++ must_test = 1;
++ } else {
++ for (l = 1; l <= i; ++l)
++ if (!osl_int_eq(precision,
++ msrc->m[row_k][msrc->nb_output_dims + l],
++ mtarg->m[row_kp][mtarg->nb_output_dims + l])) {
++ must_test = 1;
++ break;
++ }
++ }
++ int m = l;
++ if (!must_test)
++ for (; l <= s_usr->depth+1; ++l)
++ if (!osl_int_zero(precision, msrc->m[row_k][msrc->nb_output_dims + l])) {
++ must_test = 1;
++ break;
++ }
++ if (!must_test)
++ for (; m <= t_usr->depth+1; ++m)
++ if (!osl_int_zero(precision, mtarg->m[row_kp][mtarg->nb_output_dims + m])) {
++ must_test = 1;
++ break;
++ }
++ if (!must_test)
++ for (; l < msrc->nb_columns-1; ++l, ++m)
++ if (!osl_int_eq(precision,
++ msrc->m[row_k][msrc->nb_output_dims + l],
++ mtarg->m[row_kp][mtarg->nb_output_dims + m])) {
++ must_test = 1;
++ break;
++ }
++ }
++ ++kp;
++ row_kp = candl_util_relation_get_line(mtarg, kp);
++ }
++ }
++ ++k;
++ row_k = candl_util_relation_get_line(msrc, k);
++ }
++
+ if (src_ref_iter && dst_ref_iter && !must_test)
+ return 0;
+
+-
+ /* Final check. For loop i, the dependence is loop carried if there exists
+ x_i^R != x_i^S in the dependence polyhedron, with
+ x_{1..i-1}^R = x_{1..i-1}^S
+- */
++ */
+ int pos;
+- CandlMatrix* mat = dep->domain;
+- CandlStatement* src = dep->source;
+- CandlMatrix* testsyst =
+- candl_matrix_malloc(mat->NbRows + 1 + dep->source->depth, mat->NbColumns);
+- for (pos = 0; pos < mat->NbRows; ++pos)
+- for (j = 0; j < mat->NbColumns; ++j)
+- CANDL_assign(testsyst->p[pos][j], mat->p[pos][j]);
+- for (j = 0; j < i; ++j)
+- {
+- CANDL_set_si(testsyst->p[pos + j + 1][0], 0);
+- CANDL_set_si(testsyst->p[pos + j + 1][1 + j], -1);
+- CANDL_set_si(testsyst->p[pos + j + 1][1 + j + dep->source->depth], 1);
+- }
++ osl_relation_p mat = dep->domain;
++
++ osl_relation_p testsyst = osl_relation_pmalloc(precision,
++ mat->nb_rows + 1 + s_usr->depth,
++ mat->nb_columns);
++ for (pos = 0; pos < mat->nb_rows; ++pos)
++ for (j = 0; j < mat->nb_columns; ++j)
++ osl_int_assign(precision,
++ &testsyst->m[pos][j], mat->m[pos][j]);
++ for (j = 0; j < i; ++j) {
++ osl_int_set_si(precision, &testsyst->m[pos+j+1][0], 0);
++ osl_int_set_si(precision, &testsyst->m[pos+j+1][1+j], -1);
++ osl_int_set_si(precision, &testsyst->m[pos+j+1][1+j+mat->nb_output_dims], 1);
++ }
+
+ int has_pt = 0;
+ // Test for '>'.
+- CANDL_set_si(testsyst->p[pos][0], 1);
+- CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1);
+- CANDL_set_si(testsyst->p[pos][1 + i], 1);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1);
+- has_pt = pip_has_rational_point (testsyst, NULL, 1);
+- if (! has_pt)
+- {
+- // Test for '<'.
+- CANDL_set_si(testsyst->p[pos][1 + i], -1);
+- CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1);
+- has_pt = pip_has_rational_point (testsyst, NULL, 1);
+- }
+-
+- candl_matrix_free (testsyst);
+-
++ osl_int_set_si(precision, &testsyst->m[pos][0], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1);
++ osl_int_set_si(precision, &testsyst->m[pos][1+i], 1);
++ osl_int_set_si(precision, &testsyst->m[pos][1+i+mat->nb_output_dims], -1);
++
++ has_pt = pip_has_rational_point(testsyst, NULL, 1);
++ if (!has_pt) {
++ // Test for '<'.
++ osl_int_set_si(precision, &testsyst->m[pos][1+i], -1);
++ osl_int_set_si(precision, &testsyst->m[pos][1+i+mat->nb_output_dims], 1);
++ has_pt = pip_has_rational_point(testsyst, NULL, 1);
++ }
++
+ return has_pt;
+
+- /* LNP: OLD VERSION. The above is more robust. */
+-/* /\* Final check. The dependence exists only because the loop */
+-/* iterates. Make the loop not iterate and check if there's still */
+-/* dependent iterations. *\/ */
+-/* CandlMatrix* m = candl_matrix_malloc(dep->domain->NbRows + 2, */
+-/* dep->domain->NbColumns); */
+-/* CANDL_set_si(m->p[m->NbRows - 2][i + 1], -1); */
+-/* CANDL_set_si(m->p[m->NbRows - 1][dep->source->depth + 1 + j], -1); */
+-/* /\* Copy the rest of the matrix. *\/ */
+-/* int ii, jj; */
+-/* for (ii = 0; ii < dep->domain->NbRows; ++ii) */
+-/* for (jj = 0; jj < dep->domain->NbColumns; ++jj) */
+-/* CANDL_assign(m->p[ii][jj], dep->domain->p[ii][jj]); */
+-/* /\* Compute real lb of loops. *\/ */
+-/* Entier lb; CANDL_init(lb); */
+-/* candl_dependence_compute_lb (m, &lb, i + 1); */
+-/* CANDL_assign(m->p[m->NbRows - 2][m->NbColumns - 1], lb); */
+-/* candl_dependence_compute_lb (m, &lb, dep->source->depth + 1 + j); */
+-/* CANDL_assign(m->p[m->NbRows - 1][m->NbColumns - 1], lb); */
+-/* int ret = candl_matrix_check_point(m, program->context); */
+-/* CANDL_clear(lb); */
+-
+-/* /\* Be clean. *\/ */
+-/* candl_matrix_free(m); */
+-
+-/* return !ret; */
++ /* LNP: OLD VERSION */
++ /* The above is more robust. */
++ /* /\* Final check. The dependence exists only because the loop */
++ /* iterates. Make the loop not iterate and check if there's still */
++ /* dependent iterations. *\/ */
++ /* CandlMatrix* m = candl_matrix_malloc(dep->domain->NbRows + 2, */
++ /* dep->domain->NbColumns); */
++ /* CANDL_set_si(m->p[m->NbRows - 2][i + 1], -1); */
++ /* CANDL_set_si(m->p[m->NbRows - 1][dep->source->depth + 1 + j], -1); */
++ /* /\* Copy the rest of the matrix. *\/ */
++ /* int ii, jj; */
++ /* for (ii = 0; ii < dep->domain->NbRows; ++ii) */
++ /* for (jj = 0; jj < dep->domain->NbColumns; ++jj) */
++ /* CANDL_assign(m->p[ii][jj], dep->domain->p[ii][jj]); */
++ /* /\* Compute real lb of loops. *\/ */
++ /* Entier lb; CANDL_init(lb); */
++ /* candl_dependence_compute_lb (m, &lb, i + 1); */
++ /* CANDL_assign(m->p[m->NbRows - 2][m->NbColumns - 1], lb); */
++ /* candl_dependence_compute_lb (m, &lb, dep->source->depth + 1 + j); */
++ /* CANDL_assign(m->p[m->NbRows - 1][m->NbColumns - 1], lb); */
++ /* int ret = candl_matrix_check_point(m, program->context); */
++ /* CANDL_clear(lb); */
++
++ /* /\* Be clean. *\/ */
++ /* candl_matrix_free(m); */
++
++ /* return !ret; */
+ }
+
+
+@@ -2178,98 +1814,100 @@ candl_dependence_is_loop_carried (candl_program_p program,
+ * prunes the dependence graph 'deps' by removing loop-carried
+ * dependences involving a scalar variable privatizable for that loop.
+ */
+-void
+-candl_dependence_prune_with_privatization (candl_program_p program,
+- CandlOptions* options,
+- CandlDependence** deps)
+-{
+- CandlDependence* next;
+- CandlDependence* tmp;
+- CandlDependence* pred = NULL;
++void candl_dependence_prune_with_privatization(osl_scop_p scop,
++ candl_options_p options,
++ osl_dependence_p* deps) {
++ osl_dependence_p next;
++ osl_dependence_p tmp;
++ osl_dependence_p pred = NULL;
++ candl_statement_usr_p s_usr;
++ candl_statement_usr_p t_usr;
++ candl_scop_usr_p scop_usr = scop->usr;
+ int is_priv;
+- int i, j;
++ int i;
++ int row;
+ int loop_idx = 0;
+ int refs, reft;
+ int loop_pos_priv;
+-
++ int precision = scop->context->precision;
+
+ if (options->verbose)
+ fprintf (stderr, "[Candl] Scalar Analysis: Remove loop-carried dependences"
+- " on privatizable scalars\n");
++ " on privatizable scalars\n");
+
+- if (program->nb_statements == 0)
++ if (scop->statement == NULL)
+ return;
++
+ /* Perform the scalar analysis, if not done before. */
+- if (program->scalars_privatizable == NULL)
+- {
+- CandlOptions* options = candl_options_malloc ();
+- options->scalar_privatization = 1;
+- candl_dependence_analyze_scalars (program, options);
+- candl_options_free (options);
++ if (scop_usr->scalars_privatizable == NULL) {
++ candl_options_p options = candl_options_malloc();
++ options->scalar_privatization = 1;
++ candl_dependence_analyze_scalars(scop, options);
++ candl_options_free(options);
++ }
++
++ for (tmp = *deps; tmp; ) {
++ s_usr = tmp->stmt_source_ptr->usr;
++ t_usr = tmp->stmt_target_ptr->usr;
++
++ /* Check if the dependence is involving a privatizable scalar. */
++ is_priv = 1;
++ candl_dependence_get_array_refs_in_dep(tmp, &refs, &reft);
++ for (i = 0; i < s_usr->depth; ++i) {
++ if (candl_dependence_scalar_is_privatizable_at(scop, refs,
++ s_usr->index[i]))
++ break;
+ }
+-
+- for (tmp = *deps; tmp; )
+- {
+- /* Check if the dependence is involving a privatizable scalar. */
+- is_priv = 1;
+- candl_dependence_get_array_refs_in_dep (tmp, &refs, &reft);
+- for (i = 0; i < tmp->source->depth; ++i)
+- if (candl_dependence_scalar_is_privatizable_at (program, refs,
+- tmp->source->index[i]))
+- break;
+- if (i == tmp->source->depth)
+- {
+- for (i = 0; i < tmp->target->depth; ++i)
+- if (candl_dependence_scalar_is_privatizable_at
+- (program, reft, tmp->target->index[i]))
+- break;
+- if (i == tmp->target->depth)
+- is_priv = 0;
+- else
+- loop_idx = tmp->target->index[i];
+- }
++ if (i == s_usr->depth) {
++ for (i = 0; i < t_usr->depth; ++i) {
++ if (candl_dependence_scalar_is_privatizable_at
++ (scop, reft, t_usr->index[i]))
++ break;
++ }
++ if (i == t_usr->depth)
++ is_priv = 0;
+ else
+- loop_idx = tmp->source->index[i];
+- loop_pos_priv = i;
+- /* Check if the dependence is loop-carried at loop i. */
+- if (is_priv && candl_dependence_is_loop_carried (program, tmp, loop_idx))
+- {
+- /* If so, make the dependence loop-independent. */
+- CandlMatrix* m = candl_matrix_malloc (tmp->domain->NbRows + 1,
+- tmp->domain->NbColumns);
+- for (i = 0; i < tmp->domain->NbRows; ++i)
+- for (j = 0; j < tmp->domain->NbColumns; ++j)
+- CANDL_assign(m->p[i][j], tmp->domain->p[i][j]);
+- candl_matrix_free (tmp->domain);
+- tmp->domain = m;
+- CANDL_set_si(tmp->domain->p[tmp->domain->NbRows - 1]
+- [1 + loop_pos_priv], 1);
+- CANDL_set_si(tmp->domain->p[tmp->domain->NbRows - 1]
+- [1 + loop_pos_priv + tmp->source->depth], -1);
+- /* Set the type of the dependence as special
+- scalar-privatization one. */
+- if (tmp->type == CANDL_RAW)
+- tmp->type = CANDL_RAW_SCALPRIV;
+- next = tmp->next;
+- if (!candl_matrix_check_point (tmp->domain, NULL))
+- {
+- /* It is, the dependence can be removed. */
+- candl_matrix_free (tmp->domain);
+- if (pred == NULL)
+- *deps = next;
+- else
+- pred->next = next;
+- free (tmp);
+- }
+- pred = tmp;
+- tmp = next;
+-
+- continue;
+- }
+- /* Go to the next victim. */
++ loop_idx = t_usr->index[i];
++ } else {
++ loop_idx = s_usr->index[i];
++ }
++ loop_pos_priv = i;
++
++ /* Check if the dependence is loop-carried at loop i. */
++ if (is_priv && candl_dependence_is_loop_carried(scop, tmp, loop_idx)) {
++ /* If so, make the dependence loop-independent. */
++ row = tmp->domain->nb_rows;
++ osl_relation_insert_blank_row(tmp->domain, row);
++ osl_int_set_si(precision,
++ &tmp->domain->m[row][1 + loop_pos_priv],
++ 1);
++ osl_int_set_si(precision,
++ &tmp->domain->m[row][1 + loop_pos_priv + s_usr->depth],
++ -1);
++
++ /* Set the type of the dependence as special
++ scalar-privatization one. */
++ if (tmp->type == OSL_DEPENDENCE_RAW)
++ tmp->type = OSL_DEPENDENCE_RAW_SCALPRIV;
++ next = tmp->next;
++ if (!candl_matrix_check_point(tmp->domain, NULL)) {
++ /* It is, the dependence can be removed. */
++ osl_relation_free(tmp->domain);
++ if (pred == NULL)
++ *deps = next;
++ else
++ pred->next = next;
++ free(tmp);
++ }
+ pred = tmp;
+- tmp = tmp->next;
++ tmp = next;
++
++ continue;
+ }
++ /* Go to the next victim. */
++ pred = tmp;
++ tmp = tmp->next;
++ }
+ }
+
+
+@@ -2278,27 +1916,29 @@ candl_dependence_prune_with_privatization (candl_program_p program,
+ * This function checks if a given scalar 'var_index' is privatizable
+ * for loop 'loop_index'.
+ */
+-int
+-candl_dependence_scalar_is_privatizable_at (candl_program_p program,
+- int var_index,
+- int loop_index)
+-{
++int candl_dependence_scalar_is_privatizable_at(osl_scop_p scop,
++ int var_index,
++ int loop_index) {
++ candl_scop_usr_p scop_usr = scop->usr;
+ int i;
+
+ /* If the scalar analysis wasn't performed yet, do it. */
+- if (program->scalars_privatizable == NULL)
+- {
+- CandlOptions* options = candl_options_malloc();
+- options->scalar_privatization = 1;
+- candl_dependence_analyze_scalars (program, options);
+- candl_options_free (options);
+- }
++ if (scop_usr->scalars_privatizable == NULL) {
++ candl_options_p options = candl_options_malloc();
++ options->scalar_privatization = 1;
++ candl_dependence_analyze_scalars(scop, options);
++ candl_options_free(options);
++ }
++
++ i = 0;
++ while (scop_usr->scalars_privatizable[i] != -1)
++ i++;
+
+ /* Check in the array of privatizable scalar variables for the tuple
+ (var,loop). */
+- for (i = 0; program->scalars_privatizable[i] != -1; i += 2)
+- if (program->scalars_privatizable[i] == var_index &&
+- program->scalars_privatizable[i + 1] == loop_index)
++ for (i = 0; scop_usr->scalars_privatizable[i] != -1; i += 2)
++ if (scop_usr->scalars_privatizable[i] == var_index &&
++ scop_usr->scalars_privatizable[i + 1] == loop_index)
+ return 1;
+
+ return 0;
+@@ -2307,320 +1947,222 @@ candl_dependence_scalar_is_privatizable_at (candl_program_p program,
+
+ /**
+ * candl_dependence_analyze_scalars function:
+- * This function checks, for all scalar variables of the program, and
++ * This function checks, for all scalar variables of the scop, and
+ * all loop levels, if the scalar can be privatized at that level.
+ */
+-int
+-candl_dependence_analyze_scalars(candl_program_p program,
+- CandlOptions* options)
+-{
++int candl_dependence_analyze_scalars(osl_scop_p scop,
++ candl_options_p options) {
+ int* scalars;
+- CandlStatement** stmts;
+- CandlStatement** fullchain = NULL;
+- int i, j, k, l, n;
+- CandlMatrix* m;
+- int max, is_priv, cpt, offset, was_priv;
+- CandlStatement* curlast;
+- CandlStatement* last;
++ osl_statement_p* statement; /* not a chained list, but an array of */
++ osl_statement_p* fullchain; /* statement to not realloc the usr field */
++ osl_statement_p s;
++ osl_statement_p curlast;
++ osl_statement_p last;
++ osl_statement_p iter; /* used to iterate on the scop */
++ osl_relation_list_p access;
++ osl_relation_p elt;
++ candl_scop_usr_p scop_usr = scop->usr;
++ candl_statement_usr_p stmt_usr;
++ int i, j, k;
++ int max, is_priv, offset, was_priv;
+ int nb_priv = 0;
+ int priv_buff_size = 64;
++ int id, row;
+
+ /* Initialize the list of privatizable scalars to empty. */
+- if (options->scalar_privatization)
+- {
+- program->scalars_privatizable = (int*) malloc(2 * sizeof(int));
+- program->scalars_privatizable[0] = program->scalars_privatizable[1] = -1;
+- }
++ if (options->scalar_privatization) {
++ CANDL_malloc(scop_usr->scalars_privatizable, int*, 2 * sizeof(int));
++ scop_usr->scalars_privatizable[0] = -1;
++ scop_usr->scalars_privatizable[1] = -1;
++ }
+
+ /* Retrieve all scalar variables. */
+- scalars = candl_dependence_extract_scalar_variables (program);
++ scalars = candl_dependence_extract_scalar_variables(scop);
+
+ /* For each of those, detect (at any level) if it can be privatized
+ / expanded / renamed. */
+- for (i = 0; scalars[i] != -1; ++i)
+- {
+- /* Go to the first statement referencing the scalar. */
+- for (j = 0; j < program->nb_statements; ++j)
+- if (candl_dependence_var_is_ref (program->statement[j], scalars[i])
+- != CANDL_VAR_UNDEF)
+- break;
+- /* A weird error occured. */
+- if (j == program->nb_statements)
+- continue;
+-
+- /* Take all statements referencing the scalar. */
+- fullchain = candl_dependence_refvar_chain (program, program->statement[j],
+- scalars[i], 0);
+- /* Compute the maximum loop depth of the chain. */
+- for (k = 0, max = 0; fullchain[k]; ++k)
+- max = max < fullchain[k]->depth ? fullchain[k]->depth : max;
+- last = fullchain[k - 1];
+- /* Initialize the offset for expansion. */
+- offset = 0;
+- was_priv = 0;
+- /* Iterate on all possible depth for analysis. */
+- for (k = 1; k <= max; ++k)
+- {
+- CandlStatement* s = fullchain[0];
+- if (was_priv)
+- {
+- ++offset;
+- was_priv = 0;
+- }
+- do
+- {
+- /* Take all statements dominated by s referencing the
+- current scalar variable. */
+- stmts = candl_dependence_refvar_chain (program, s, scalars[i], k);
+- /* No more statement in the chain, exit. */
+- if (stmts[0] == NULL)
+- break;
+- int c = 0;
+- is_priv = candl_dependence_var_is_ref (stmts[c], scalars[i])
+- == CANDL_VAR_IS_DEF;
+- /* Ensure we have a use in the chain. */
+- for (l = c + 1; stmts[l - 1] && stmts[l]; ++l)
+- if (candl_dependence_var_is_ref (stmts[l], scalars[i]) ==
+- CANDL_VAR_IS_USED)
+- break;
+- if (stmts[l - 1] == NULL || stmts[l] == NULL)
+- is_priv = 0;
+- /* Check for privatization, while the entry of the chain
+- is a DEF. */
+- while (stmts[c] && candl_dependence_var_is_ref
+- (stmts[c], scalars[i]) == CANDL_VAR_IS_DEF)
+- {
+- /* From the current DEF node, ensure the rest of the
+- chain covers not more than the iteration domain
+- of the DEF. */
+- for (l = c + 1; stmts[l - 1] && stmts[l]; ++l)
+- /* FIXME: we should deal with
+- def_1->use->def_2->use chains where dom(def_2)
+- > dom(def_1). */
+- if (! candl_dependence_check_domain_is_included
+- (stmts[c], stmts[l], program->context, k))
+- {
+- /* dom(use) - dom(def) > 0. Check if there is
+- another DEF to test at the entry of the
+- block. */
+- if (stmts[c + 1])
+- if (candl_dependence_var_is_ref
+- (stmts[c + 1], scalars[i]) != CANDL_VAR_IS_DEF)
+- /* No. The variable is not privatizable. */
+- is_priv = 0;
+- break;
+- }
+- if (! is_priv || ! stmts[l])
+- break;
+- /* The chain dominated by stmts[c] is not
+- privatizable. Go for the next DEF at the
+- beginning of the block, if any. */
+- ++c;
+- }
+- if (is_priv)
+- {
+- /* Perform the privatization / expansion. */
+- if (options->verbose)
+- fprintf (stderr, "[Candl] Scalar Analysis: The variable %d"
+- " can be privatized at loop %d\n",
+- scalars[i], stmts[0]->index[k - 1]);
+- if (options->scalar_expansion)
+- /* Traverse all statements in the chain. */
+- for (l = c; stmts[l]; ++l)
+- {
+- /* It's not the first expansion of the scalar,
+- we need to increase its dimension all along
+- the program. */
+- if (offset && !was_priv)
+- candl_dependence_expand_scalar (fullchain,
+- scalars[i]);
+- /* Perform scalar expansion in the array
+- access functions. */
+- for (cpt = 0, m = stmts[l]->read; cpt < 2;
+- ++cpt, m = stmts[l]->written)
+- for (n = 0; n < m->NbRows; ++n)
+- if (CANDL_get_si(m->p[n][0]) == scalars[i])
+- CANDL_set_si(m->p[n + offset][k], 1);
+- was_priv = 1;
+- }
+- if (options->scalar_privatization)
+- {
+- /* Memory management for the array of
+- privatizable scalars. */
+- if (nb_priv == 0)
+- {
+- free (program->scalars_privatizable);
+- program->scalars_privatizable =
+- (int*)malloc(priv_buff_size * sizeof(int));
+- for (l = 0; l < priv_buff_size; ++l)
+- program->scalars_privatizable[l] = -1;
+- }
+- if (nb_priv == priv_buff_size)
+- {
+- program->scalars_privatizable =
+- realloc(program->scalars_privatizable,
+- (priv_buff_size *= 2) * sizeof(int));
+- for (l = nb_priv; l < priv_buff_size; ++l)
+- program->scalars_privatizable[l] = -1;
+- }
+- /* Memorize the scalar information in the
+- privatizable list. */
+- program->scalars_privatizable[nb_priv++] = scalars[i];
+- program->scalars_privatizable[nb_priv++] =
+- stmts[0]->index[k - 1];
+- }
+- }
+- /* Go to the next block, if any. */
+- for (l = 0; stmts[l]; ++l)
+- ;
+- curlast = stmts[l - 1];
+- if (curlast != last)
+- {
+- for (l = 0; fullchain[l]; ++l)
+- if (fullchain[l] == curlast)
+- s = fullchain[l + 1];
+- }
+- free (stmts);
+- }
+- while (curlast != last);
+- }
+- free (fullchain);
++ for (i = 0; scalars[i] != -1; ++i) {
++ /* Go to the first statement referencing the scalar in the scop. */
++ for (iter = scop->statement; iter != NULL; iter = iter->next) {
++ if (candl_dependence_var_is_ref(iter, scalars[i])
++ != CANDL_VAR_UNDEF)
++ break;
+ }
+-
+- return 0;
+-}
+-
+-
+-/**
+- * candl_num_dependences function:
+- * This function returns the number of dependences in the dependence
+- * list
+- * \param dependence The first dependence of the dependence list.
+- **
+- */
+-int
+-candl_num_dependences(CandlDependence *candl_deps)
+-{
+- CandlDependence *candl_dep = candl_deps;
+-
+- int num = 0;
+- while (candl_dep != NULL)
+- {
+- num++;
+- candl_dep = candl_dep->next;
++
++ /* A weird error occured. */
++ if (iter == NULL)
++ continue;
++
++ /* Take all statements referencing the scalar. */
++ fullchain = candl_dependence_refvar_chain(scop, iter, scalars[i], 0);
++
++ /* Compute the maximum loop depth of the chain. */
++ max = 0;
++ for (k = 0; fullchain[k]; ++k) {
++ stmt_usr = fullchain[k]->usr;
++ if (max < stmt_usr->depth)
++ max = stmt_usr->depth;
+ }
+- return num;
+-}
+-
+-
+-/*
+- * Convert a PIP quast to a union of polyhedra (Pip matrices)
+- *
+- * num: number of Pip matrices returned
+- *
+- **/
+-static
+-PipMatrix **quast_to_polyhedra (PipQuast *quast, int *num,
+- int nvar, int npar)
+-{
+- int num1, num2;
+- PipMatrix** ep;
+- PipMatrix** tp;
+- PipMatrix** qp;
+- int i, j;
+- if (quast == NULL)
+- {
+- *num = 0;
+- return NULL;
+- }
+-
+- if (quast->condition != NULL)
+- {
+- tp = quast_to_polyhedra(quast->next_then, &num1, nvar, npar);
+- ep = quast_to_polyhedra(quast->next_else, &num2, nvar, npar);
+-
+- /* Each of the matrices in the then tree needs to be augmented with
+- * the condition */
+- for (i = 0; i < num1; i++)
+- {
+- int nrows = tp[i]->NbRows;
+- CANDL_set_si(tp[i]->p[nrows][0], 1);
+- for (j = 1; j < 1 + nvar; j++)
+- CANDL_set_si(tp[i]->p[nrows][j], 0);
+- for (j = 0; j < npar + 1; j++)
+- CANDL_assign(tp[i]->p[nrows][1+nvar+j],
+- quast->condition->the_vector[j]);
+- (tp[i]->NbRows)++;
+- }
+-
+- for (i = 0; i < num2; i++)
+- {
+- int nrows = ep[i]->NbRows;
+- /* Inequality */
+- CANDL_set_si(ep[i]->p[nrows][0], 1);
+- for (j = 1; j < 1 + nvar; j++)
+- CANDL_set_si(ep[i]->p[nrows][j], 0);
+- for (j = 0; j < npar + 1; j++)
+- CANDL_set_si(ep[i]->p[nrows][1+nvar+j],
+- -CANDL_get_si(quast->condition->the_vector[j]));
+- (ep[i]->NbRows)++;
+- }
+-
+- qp = (PipMatrix **) malloc((num1 + num2) * sizeof(PipMatrix*));
+- for (i = 0; i < num1; ++i)
+- qp[i] = tp[i];
+- for (i = 0; i < num2; ++i)
+- qp[i + num1] = ep[i];
+-
+- *num = num1 + num2;
+-
+- return qp;
+-
++ last = fullchain[k-1];
++
++ /* Initialize the offset for expansion. */
++ offset = 0;
++ was_priv = 0;
++
++ /* Iterate on all possible depth for analysis. */
++ for (j = 1; j <= max; ++j) {
++ s = fullchain[0];
++
++ if (was_priv) {
++ ++offset;
++ was_priv = 0;
+ }
+- else
+- {
+- /* quast condition is NULL */
+- PipMatrix *lwmatrix = pip_matrix_alloc(nvar+npar+1, nvar+npar+2);
+-
+- PipList *vecList = quast->list;
+-
+- int count=0;
+- while (vecList != NULL) {
+- /* Equality */
+- CANDL_set_si(lwmatrix->p[count][0], 0);
+- for (j=0; j<nvar; j++)
+- if (j == count)
+- CANDL_set_si(lwmatrix->p[count][j+1], 1);
+- else
+- CANDL_set_si(lwmatrix->p[count][j+1], 0);
+-
+- for (j=0; j<npar; j++)
+- CANDL_set_si(lwmatrix->p[count][j+1+nvar],
+- -CANDL_get_si(vecList->vector->the_vector[j]));
+- /* Constant portion */
+- if (quast->newparm != NULL)
+- /* Don't handle newparm for now */
+- CANDL_set_si(lwmatrix->p[count][npar+1+nvar],
+- -CANDL_get_si(vecList->vector->the_vector[npar+1]));
+- else
+- CANDL_set_si(lwmatrix->p[count][npar+1+nvar],
+- -CANDL_get_si(vecList->vector->the_vector[npar]));
+-
+- count++;
+-
+- vecList = vecList->next;
++
++ do {
++ /* Take all statements dominated by s referencing the
++ current scalar variable. */
++ statement = candl_dependence_refvar_chain(scop, s, scalars[i], j);
++
++ /* No more statement in the chain, exit. */
++ if (statement[0] == NULL) {
++ free(statement);
++ break;
+ }
+- lwmatrix->NbRows = count;
+-
+- if (count > 0)
+- *num = 1;
+- else
+- *num = 0;
++
++ int c = 0;
++
++ is_priv = candl_dependence_var_is_ref(statement[0], scalars[i]) ==
++ CANDL_VAR_IS_DEF;
++
++ /* Ensure we have a use in the chain. */
++ /* here statement[c] is not NULL */
++ for (k = c + 1; statement[k]; ++k) {
++ if (candl_dependence_var_is_ref(statement[k], scalars[i]) ==
++ CANDL_VAR_IS_USED)
++ break;
++ }
++
++ if (statement[k] == NULL)
++ is_priv = 0;
++
++ /* Check for privatization, while the entry of the chain
++ is a DEF. */
++ while (statement[c] && candl_dependence_var_is_ref
++ (statement[c], scalars[i]) == CANDL_VAR_IS_DEF) {
++ /* From the current DEF node, ensure the rest of the
++ chain covers not more than the iteration domain
++ of the DEF. */
++ for (k = c + 1; statement[k]; ++k) {
++ /* FIXME: we should deal with
++ def_1->use->def_2->use chains where dom(def_2)
++ > dom(def_1). */
++ if (! candl_dependence_check_domain_is_included
++ (statement[c], statement[k], scop->context, j)) {
++ /* dom(use) - dom(def) > 0. Check if there is
++ another DEF to test at the entry of the
++ block. */
++ if (candl_dependence_var_is_ref
++ (statement[c+1], scalars[i]) != CANDL_VAR_IS_DEF)
++ /* No. The variable is not privatizable. */
++ is_priv = 0;
++ break;
++ }
++ }
++
++ if (! is_priv || ! statement[k])
++ break;
++
++ /* The chain dominated by statement is not
++ privatizable. Go for the next DEF at the
++ beginning of the block, if any. */
++ ++c;
++ }
++
++ if (is_priv) {
++ /* Perform the privatization / expansion. */
++ if (options->verbose)
++ fprintf(stderr, "[Candl] Scalar Analysis: The variable %d"
++ " can be privatized at loop %d\n",
++ scalars[i],
++ ((candl_statement_usr_p)statement[0]->usr)->index[j-1]);
++
++ if (options->scalar_expansion) {
++ int precision = scop->context->precision;
++ /* Traverse all statements in the chain. */
++ for (k = c; statement[k]; ++k) {
++ /* It's not the first expansion of the scalar,
++ we need to increase its dimension all along
++ the program. */
++ if (!offset && !was_priv)
++ candl_dependence_expand_scalar(fullchain,
++ scalars[i]);
++ /* Perform scalar expansion in the array
++ access functions. */
++ access = statement[k]->access;
++ for (; access != NULL; access = access->next) {
++ elt = access->elt;
++ id = osl_relation_get_array_id(elt);
++ if (scalars[i] == id) {
++ row = candl_util_relation_get_line(elt, offset+1);
++ osl_int_set_si(precision, &elt->m[row][elt->nb_output_dims + j], 1);
++ }
++ }
++ was_priv = 1;
++ }
++ }
++
++ if (options->scalar_privatization) {
++ /* Memory management for the array of
++ privatizable scalars. */
++ if (nb_priv == 0) {
++ free(scop_usr->scalars_privatizable);
++ CANDL_malloc(scop_usr->scalars_privatizable,
++ int*, priv_buff_size * sizeof(int));
++ for (k = 0; k < priv_buff_size; ++k)
++ scop_usr->scalars_privatizable[k] = -1;
++ }
++
++ if (nb_priv == priv_buff_size) {
++ CANDL_realloc(scop_usr->scalars_privatizable,
++ int*, (priv_buff_size *= 2) * sizeof(int));
++ for (k = nb_priv; k < priv_buff_size; ++k)
++ scop_usr->scalars_privatizable[k] = -1;
++ }
++
++ /* Memorize the scalar information in the
++ privatizable list. */
++ scop_usr->scalars_privatizable[nb_priv++] = scalars[i];
++ scop_usr->scalars_privatizable[nb_priv++] =
++ ((candl_statement_usr_p)statement[0]->usr)->index[j - 1];
++ }
++
++ } // end is_priv
++
++
++ /* Go to the next block, if any. */
++ for (k = 0; statement[k]; ++k)
++ ;
++ curlast = statement[k-1];
++
++ if (curlast != last) {
++ for (k = 0; fullchain[k]; ++k) {
++ if (fullchain[k] == curlast) {
++ s = fullchain[k+1];
++ break;
++ }
++ }
++ }
++ free(statement);
++
++ } while (curlast != last);
++
++ } // end iterate all possible depth
++
++ free(fullchain);
++
++ } // end iterate scalars
+
+- PipMatrix** ret = (PipMatrix**) malloc(sizeof(PipMatrix*));
+- ret[0] = lwmatrix;
+- return ret;
+- }
++ return 0;
+ }
+
+
+@@ -2631,119 +2173,142 @@ PipMatrix **quast_to_polyhedra (PipQuast *quast, int *num,
+ * Returns 0 if lastwriter is computed successfully and dep domain updated,
+ * returns 1 otherwise
+ */
+-static
+-int candl_dep_compute_lastwriter (CandlDependence **dep, CandlProgram *prog)
+-{
+- PipQuast *lexmax;
+- PipMatrix *new_domain;
+-
+- int i, j;
+-
+- int npar = prog->context->NbColumns-2;
+-
+- PipOptions *pipOptions = pip_options_init();
+-
+- /* We do a parametric lexmax on the source iterators
+- * keeping the target iterators as parameters */
+- pipOptions->Maximize = 1;
+- pipOptions->Simplify = 1;
+- // pipOptions->Deepest_cut = 1;
+- // pipOptions->Urs_unknowns = -1;
+- // pipOptions->Urs_parms = -1;
+-
+- /* Build a context with equalities /inequalities only on the target
+- * variables */
+- PipMatrix *context = pip_matrix_alloc((*dep)->domain->NbRows,
+- (*dep)->target->depth + npar + 2);
+-
+- int nrows = 0;
+- for (i = 0; i < (*dep)->domain->NbRows; i++)
+- {
+- for (j = 1; j < (*dep)->source->depth+1; j++)
+- {
+- if ((*dep)->domain->p[i][j] != 0)
+- break;
+- }
+- if (j == (*dep)->source->depth+1)
+- {
+- /* Include this in the context */
+- CANDL_assign(context->p[nrows][0], (*dep)->domain->p[i][0]);
+- for (j = 1; j < 1 + (*dep)->target->depth + npar + 1; j++)
+- CANDL_assign(context->p[nrows][j],
+- (*dep)->domain->p[i][(*dep)->source->depth+j]);
+-
+- nrows++;
+- }
+- }
+- context->NbRows = nrows;
++static
++int candl_dep_compute_lastwriter(osl_dependence_p *dep, osl_scop_p scop) {
++ PipQuast *lexmax;
++ PipOptions *pipOptions = pip_options_init();
++ candl_statement_usr_p s_usr = (*dep)->stmt_source_ptr->usr;
++ candl_statement_usr_p t_usr = (*dep)->stmt_target_ptr->usr;
++ osl_relation_p new_domain;
++ int i, j;
++ int npar = scop->context->nb_parameters;
++ int precision;
++
++ #if defined(CANDL_LINEAR_VALUE_IS_INT)
++ precision = OSL_PRECISION_SP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ precision = OSL_PRECISION_DP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ precision = OSL_PRECISION_MP;
++ #endif
++
++ if (precision != scop->context->precision) {
++ CANDL_error("Precision not compatible with piplib ! (pip_relation2matrix)");
++ }
+
+- /* Parameteric lexmax */
+- lexmax = pip_solve((*dep)->domain, context, -1, pipOptions);
++ /* We do a parametric lexmax on the source iterators
++ * keeping the target iterators as parameters */
++ pipOptions->Maximize = 1;
++ pipOptions->Simplify = 1;
++ // pipOptions->Deepest_cut = 1;
++ // pipOptions->Urs_unknowns = -1;
++ // pipOptions->Urs_parms = -1;
++
++ /* Build a context with equalities /inequalities only on the target
++ * variables */
++ osl_relation_p context = osl_relation_pmalloc(precision,
++ (*dep)->domain->nb_rows,
++ (*dep)->stmt_target_ptr->domain->nb_columns);
++ int nrows = 0;
++ for (i = 0; i < (*dep)->domain->nb_rows; i++) {
++ for (j = 1; j < s_usr->depth+1; j++) {
++
++ // FIXME : new domain structure for dependence
++
++ if (!osl_int_zero(precision, (*dep)->domain->m[i][j]))
++ break;
++ }
++
++ if (j == t_usr->depth+1) {
++ /* Include this in the context */
++ osl_int_assign(precision,
++ &context->m[nrows][0], (*dep)->domain->m[i][0]);
++
++ for (j = 1; j < (*dep)->stmt_target_ptr->domain->nb_columns; j++)
++ osl_int_assign(precision,
++ &context->m[nrows][j],
++ (*dep)->domain->m[i][s_usr->depth+j]);
++
++ nrows++;
++ }
++ }
+
+- pip_options_free(pipOptions);
++ /* Parameteric lexmax */
++ lexmax = pip_solve_osl((*dep)->domain, context, -1, pipOptions);
+
+- if (lexmax == NULL)
+- {
+- printf("WARNING: last writer failed (mostly invalid dependence): %s\n",
+- "bailing out safely without modification");
+- pip_matrix_print(stdout, (*dep)->domain);
+- pip_matrix_print(stdout, context);
+- return 1;
+- }
++ pip_options_free(pipOptions);
++
++ if (lexmax == NULL) {
++ CANDL_warning("last writer failed (mostly invalid dependence): bailing out"
++ "safely without modification");
++ osl_relation_print(stderr, context);
++ osl_relation_print(stderr, (*dep)->domain);
++ return 1;
++ }
+
+- int num;
+- PipMatrix **qp = quast_to_polyhedra(lexmax, &num, (*dep)->source->depth,
+- (*dep)->target->depth + npar);
+-
+- /* Update the dependence domains */
+- if (num > 0)
+- {
+- int it_mat;
+- PipMatrix* original_domain = (*dep)->domain;
+- for (it_mat = 0; it_mat < num; ++it_mat)
+- {
+- new_domain = pip_matrix_alloc(original_domain->NbRows +
+- qp[it_mat]->NbRows,
+- original_domain->NbColumns);
+- for (i = 0; i < original_domain->NbRows; i++)
+- for (j = 0; j < original_domain->NbColumns; j++)
+- CANDL_assign(new_domain->p[i][j], original_domain->p[i][j]);
+-
+- for (i = 0; i < qp[it_mat]->NbRows; i++)
+- for (j = 0; j < original_domain->NbColumns; j++)
+- CANDL_assign(new_domain->p[i+original_domain->NbRows][j],
+- qp[it_mat]->p[i][j]);
+-
+- (*dep)->domain = new_domain;
+- /* More than 1 pipmatrix from the quast, we need to insert
+- new dependences to have the union of domains. */
+- if (it_mat < num - 1)
+- {
+- CandlDependence* newdep = candl_dependence_malloc ();
+- newdep->source = (*dep)->source;
+- newdep->target = (*dep)->target;
+- newdep->depth = (*dep)->depth;
+- newdep->type = (*dep)->type;
+- newdep->ref_source = (*dep)->ref_source;
+- newdep->ref_target = (*dep)->ref_target;
+- newdep->usr = (*dep)->usr;
+- newdep->next = (*dep)->next;
+- (*dep)->next = newdep;
+- *dep = newdep;
+- }
+- }
+-
+- pip_matrix_free(original_domain);
+- for (i = 0; i < num; ++i)
+- pip_matrix_free(qp[i]);
++ osl_relation_p qp = pip_quast_to_polyhedra(lexmax, s_usr->depth,
++ t_usr->depth + npar);
++
++ /* Update the dependence domains */
++ if (osl_relation_nb_components(qp) > 0) {
++ osl_relation_p iter;
++ osl_relation_p original_domain = (*dep)->domain;
++ for (iter = qp ; iter != NULL ; iter = iter->next) {
++
++ new_domain = osl_relation_pmalloc(precision,
++ original_domain->nb_rows +
++ qp->nb_rows,
++ original_domain->nb_columns);
++
++ for (i = 0; i < original_domain->nb_rows; i++)
++ for (j = 0; j < original_domain->nb_columns; j++)
++ osl_int_assign(precision,
++ &new_domain->m[i][j],
++ original_domain->m[i][j]);
++
++ for (i = 0; i < qp->nb_rows; i++)
++ for (j = 0; j < original_domain->nb_columns; j++)
++ osl_int_assign(precision,
++ &new_domain->m[i+original_domain->nb_rows][j],
++ qp->m[i][j]);
++
++ (*dep)->domain = new_domain;
++ /* More than 1 pipmatrix from the quast, we need to insert
++ new dependences to have the union of domains. */
++ if (qp->next != NULL) {
++ osl_dependence_p newdep = osl_dependence_malloc();
++ newdep->stmt_source_ptr = (*dep)->stmt_source_ptr;
++ newdep->stmt_target_ptr = (*dep)->stmt_target_ptr;
++ newdep->depth = (*dep)->depth;
++ newdep->type = (*dep)->type;
++ newdep->label_source = (*dep)->label_source;
++ newdep->label_target = (*dep)->label_target;
++ newdep->ref_source = (*dep)->ref_source;
++ newdep->ref_target = (*dep)->ref_target;
++ newdep->usr = (*dep)->usr;
++ newdep->source_nb_output_dims_domain = (*dep)->source_nb_output_dims_domain;
++ newdep->source_nb_output_dims_access = (*dep)->source_nb_output_dims_access;
++ newdep->target_nb_output_dims_domain = (*dep)->target_nb_output_dims_domain;
++ newdep->target_nb_output_dims_access = (*dep)->target_nb_output_dims_access;
++ newdep->source_nb_local_dims_domain = (*dep)->source_nb_local_dims_domain;
++ newdep->source_nb_local_dims_access = (*dep)->source_nb_local_dims_access;
++ newdep->target_nb_local_dims_domain = (*dep)->target_nb_local_dims_domain;
++ newdep->target_nb_local_dims_access = (*dep)->target_nb_local_dims_access;
++ newdep->next = (*dep)->next;
++ (*dep)->next = newdep;
++ *dep = newdep;
+ }
++ }
+
+- if (qp)
+- free(qp);
+- pip_quast_free(lexmax);
+- pip_matrix_free(context);
++ osl_relation_free(original_domain);
++ osl_relation_free(qp);
++ }
+
+- return 0;
++ pip_quast_free(lexmax);
++ osl_relation_free(qp);
++ osl_relation_free(context);
++
++ return 0;
+ }
+
+ /**
+@@ -2751,16 +2316,15 @@ int candl_dep_compute_lastwriter (CandlDependence **dep, CandlProgram *prog)
+ * modify the dependence polyhedra. Be careful of any references to the old
+ * dependence polyhedra. They are freed and new ones allocated.
+ */
+-void candl_compute_last_writer (CandlDependence *dep, CandlProgram *prog)
+-{
++void candl_compute_last_writer(osl_dependence_p dep, osl_scop_p scop) {
+ // int count=0;
+- while (dep != NULL) {
+- if (dep->type != CANDL_WAR) {
+- // printf("Last writer for dep %d: %d %d\n", count++, dep->source->depth, dep->target->depth);
+- // candl_matrix_print(stdout, dep->domain);
+- candl_dep_compute_lastwriter(&dep, prog);
+- // candl_matrix_print(stdout, dep->domain);
+- }
+- dep = dep->next;
++ while (dep != NULL) {
++ if (dep->type != OSL_DEPENDENCE_WAR) {
++ // printf("Last writer for dep %d: %d %d\n", count++, dep->source->usr->depth, dep->target->usr->depth);
++ // candl_matrix_print(stdout, dep->domain);
++ candl_dep_compute_lastwriter(&dep, scop);
++ // candl_matrix_print(stdout, dep->domain);
+ }
++ dep = dep->next;
++ }
+ }
+diff --git a/source/isl-wrapper.c b/source/isl-wrapper.c
+index 870c9c9..36d9b05 100644
+--- a/source/isl-wrapper.c
++++ b/source/isl-wrapper.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: January 31st 2011 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -41,19 +41,18 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+-#include <candl/candl.h>
++#include <osl/relation.h>
+
+-# ifdef CANDL_SUPPORTS_ISL
+-
+-# undef Q
+-# include <isl/constraint.h>
+-# include <isl/map.h>
+-# include <isl/map.h>
+-# include <isl/set.h>
+-# include <isl/dim.h>
+-# include <isl/seq.h>
+-# include <isl/ctx.h>
++#ifdef CANDL_SUPPORTS_ISL
+
++#undef Q
++#include <isl/constraint.h>
++#include <isl/map.h>
++#include <isl/map.h>
++#include <isl/set.h>
++#include <isl/dim.h>
++#include <isl/seq.h>
++#include <isl/ctx.h>
+
+
+ /// WARNING: This is hard-coding that ISL uses GMP.
+@@ -66,8 +65,7 @@
+ */
+ static
+ struct isl_constraint*
+-isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row)
+-{
++isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row) {
+ struct isl_constraint* constraint;
+ int j;
+ int nvariables = isl_dim_size(dim, isl_dim_set);
+@@ -79,17 +77,15 @@ isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row)
+ else
+ constraint = isl_inequality_alloc(dim);
+
+- for (j = 0; j < nvariables; ++j)
+- {
+- mpz_set_si(val, CANDL_get_si(row[1 + j]));
+- isl_constraint_set_coefficient(constraint, isl_dim_out, j, val);
+- }
++ for (j = 0; j < nvariables; ++j) {
++ mpz_set_si(val, CANDL_get_si(row[1 + j]));
++ isl_constraint_set_coefficient(constraint, isl_dim_out, j, val);
++ }
+
+- for (j = 0; j < nparam; ++j)
+- {
+- mpz_set_si(val, CANDL_get_si(row[1 + nvariables + j]));
+- isl_constraint_set_coefficient(constraint, isl_dim_param, j, val);
+- }
++ for (j = 0; j < nparam; ++j) {
++ mpz_set_si(val, CANDL_get_si(row[1 + nvariables + j]));
++ isl_constraint_set_coefficient(constraint, isl_dim_param, j, val);
++ }
+
+ mpz_set_si(val, CANDL_get_si(row[1 + nvariables + nparam]));
+ isl_constraint_set_constant(constraint, val);
+@@ -102,16 +98,16 @@ isl_constraint_read_from_matrix(struct isl_dim* dim, Entier* row)
+
+ struct isl_set*
+ isl_set_from_piplib_matrix(struct isl_ctx* ctx,
+- PipMatrix* matrix,
+- int nparam)
+-{
++ osl_relation_p matrix,
++ int nparam) {
++ PipMatrix* pmatrix = pip_relation2matrix(matrix);
+ struct isl_dim* dim;
+ struct isl_basic_set* bset;
+ int i;
+ unsigned nrows, ncolumns;
+
+- nrows = matrix->NbRows;
+- ncolumns = matrix->NbColumns;
++ nrows = pmatrix->NbRows;
++ ncolumns = pmatrix->NbColumns;
+ int nvariables = ncolumns - 2 - nparam;
+
+ dim = isl_dim_set_alloc(ctx, nparam, nvariables);
+@@ -119,36 +115,33 @@ isl_set_from_piplib_matrix(struct isl_ctx* ctx,
+ bset = isl_basic_set_universe(isl_dim_copy(dim));
+
+ for (i = 0; i < nrows; ++i) {
+- Entier* row = matrix->p[i];
++ Entier* row = pmatrix->p[i];
+ struct isl_constraint* constraint =
+- isl_constraint_read_from_matrix(isl_dim_copy(dim), row);
++ isl_constraint_read_from_matrix(isl_dim_copy(dim), row);
+ bset = isl_basic_set_add_constraint(bset, constraint);
+ }
+
+ isl_dim_free(dim);
+
+- return isl_set_from_basic_set(bset);;
++ return isl_set_from_basic_set(bset);
+ }
+
+
+ static
+-int count_cst(__isl_take isl_constraint *c, void *user)
+-{
++int count_cst(__isl_take isl_constraint *c, void *user) {
+ (*((int*)user))++;
+
+ return 0;
+ }
+
+
+-
+ static
+-int copy_cst_to_mat(__isl_take isl_constraint *c, void *user)
+-{
++int copy_cst_to_mat(__isl_take isl_constraint *c, void *user) {
+ // 1- Get the first free row of the matrix.
+ int pos;
+ PipMatrix* mat = (PipMatrix*)user;
+ for (pos = 0; pos < mat->NbRows &&
+- CANDL_get_si(mat->p[pos][0]) != -1; ++pos)
++ CANDL_get_si(mat->p[pos][0]) != -1; ++pos)
+ ;
+
+ // 2- Set the eq/ineq bit.
+@@ -161,17 +154,15 @@ int copy_cst_to_mat(__isl_take isl_constraint *c, void *user)
+ isl_int val; isl_int_init(val);
+ int j;
+ int nb_vars = isl_constraint_dim(c, isl_dim_set);
+- for (j = 0; j < nb_vars; ++j)
+- {
+- isl_constraint_get_coefficient(c, isl_dim_set, j, &val);
+- CANDL_set_si(mat->p[pos][j + 1], isl_int_get_si(val));
+- }
++ for (j = 0; j < nb_vars; ++j) {
++ isl_constraint_get_coefficient(c, isl_dim_set, j, &val);
++ CANDL_set_si(mat->p[pos][j + 1], isl_int_get_si(val));
++ }
+ int nb_param = isl_constraint_dim(c, isl_dim_param);
+- for (j = 0; j < nb_param; ++j)
+- {
+- isl_constraint_get_coefficient(c, isl_dim_param, j, &val);
+- CANDL_set_si(mat->p[pos][j + nb_vars + 1], isl_int_get_si(val));
+- }
++ for (j = 0; j < nb_param; ++j) {
++ isl_constraint_get_coefficient(c, isl_dim_param, j, &val);
++ CANDL_set_si(mat->p[pos][j + nb_vars + 1], isl_int_get_si(val));
++ }
+ isl_constraint_get_constant(c, &val);
+ CANDL_set_si(mat->p[pos][mat->NbColumns - 1], isl_int_get_si(val));
+
+@@ -181,19 +172,17 @@ int copy_cst_to_mat(__isl_take isl_constraint *c, void *user)
+ }
+
+
+-int bset_get(__isl_take isl_basic_set *bset, void *user)
+-{
++int bset_get(__isl_take isl_basic_set *bset, void *user) {
+ *((struct isl_basic_set**)user) = bset;
+
+ return 0;
+ }
+
+
+-PipMatrix*
++osl_relation_p
+ isl_set_to_piplib_matrix(struct isl_ctx* ctx,
+- struct isl_set* set,
+- int nparam)
+-{
++ struct isl_set* set,
++ int nparam) {
+ struct isl_basic_set* bset = NULL;
+ // There is only one basic set in this set.
+ isl_set_foreach_basic_set(set, bset_get, &bset);
+@@ -215,8 +204,11 @@ isl_set_to_piplib_matrix(struct isl_ctx* ctx,
+
+ // 4- Convert each constraint to a row of the matrix.
+ isl_basic_set_foreach_constraint(bset, copy_cst_to_mat, res);
+-
+- return res;
++
++ osl_relation_p tmp = pip_matrix2relation(res);
++ pip_matrix_free(res);
++
++ return tmp;
+ }
+
+
+diff --git a/source/matrix.c b/source/matrix.c
+index 03c8546..8c3a1aa 100644
+--- a/source/matrix.c
++++ b/source/matrix.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: december 9th 2005 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -36,298 +36,18 @@
+ * please feel free to correct and improve it !
+ */
+
+-# include <stdlib.h>
+-# include <stdio.h>
+-# include <ctype.h>
+-# include <string.h>
+-# include <candl/candl.h>
+-
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_matrix_print_structure function:
+- * Displays a CandlMatrix structure (matrix) into a file (file, possibly stdout)
+- * in a way that trends to be understandable without falling in a deep
+- * depression or, for the lucky ones, getting a headache... It includes an
+- * indentation level (level) in order to work with others print_structure
+- * functions.
+- * - 09/12/2005: first version (from CLooG 0.14.0).
+- */
+-void candl_matrix_print_structure(FILE * file, CandlMatrix * matrix, int level)
+-{ int i, j ;
+-
+- if (matrix != NULL)
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- CandlMatrix\n") ;
+-
+- for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"%d %d\n",matrix->NbRows,matrix->NbColumns) ;
+-
+- /* Display the matrix. */
+- for (i=0; i<matrix->NbRows; i++)
+- { for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+-
+- fprintf(file,"[ ") ;
+-
+- for (j=0; j<matrix->NbColumns; j++)
+- { CANDL_print(file,CANDL_FMT,matrix->p[i][j]) ;
+- fprintf(file," ") ;
+- }
+-
+- fprintf(file,"]\n") ;
+- }
+- }
+- else
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- NULL matrix\n") ;
+- }
+-
+- /* The last line. */
+- for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-}
+-
+-
+-/**
+- * candl_matrix_print function:
+- * This function prints the content of a CandlMatrix structure (matrix) into a
+- * file (file, possibly stdout).
+- * - 09/12/2005: first version (from CLooG 0.14.0).
+- */
+-void candl_matrix_print(FILE * file, CandlMatrix * matrix)
+-{ candl_matrix_print_structure(file,matrix,0) ;
+-}
+-
+-
+-
+-/**
+- * candl_matrix_print_data function:
+- * This function prints the content of a CandlMatrix data (matrix) into a
+- * file (file, possibly stdout).
+- */
+-void candl_matrix_print_data(FILE * file, CandlMatrix * matrix)
+-{
+- int i, j;
+-
+- fprintf (file, "%d %d\n", matrix->NbRows, matrix->NbColumns);
+- for (i = 0; i < matrix->NbRows; ++i)
+- {
+- for (j = 0; j < matrix->NbColumns; ++j)
+- CANDL_print(file,CANDL_FMT,matrix->p[i][j]);
+- fprintf (file, "\n");
+- }
+-}
+-
+-
+-/**
+- * candl_matrix_list_print_structure function:
+- * Displays a CandlMatrixList structure (list) into a file (file, possibly
+- * stdout) in a way that trends to be understandable without falling in a deep
+- * depression or, for the lucky ones, getting a headache... It includes an
+- * indentation level (level) in order to work with others print_structure
+- * functions.
+- * - 11/12/2005: first version.
+- */
+-void candl_matrix_list_print_structure(file, list, level)
+-FILE * file ;
+-CandlMatrixList *list ;
+-int level ;
+-{ int i, j, first=1 ;
+-
+- if (list != NULL)
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- CandlMatrixList\n") ;
+- }
+- else
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- NULL matrix list\n") ;
+- }
+-
+- while (list != NULL)
+- { if (!first)
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"| CandlMatrixList\n") ;
+- }
+- else
+- first = 0 ;
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-
+- /* Print the matrix. */
+- candl_matrix_print_structure(file,list->matrix,level+1) ;
+-
+- /* Next line. */
+- if (list->next != NULL)
+- { for(i=0; i<=level; i++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"V\n") ;
+- }
+- list = list->next ;
+- }
+-
+- /* The last line. */
+- for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-}
+-
+-
+-/**
+- * candl_matrix_list_print function:
+- * This function prints the content of a CandlMatrixList structure (list) into a
+- * file (file, possibly stdout).
+- * - 11/12/2005: first version.
+- */
+-void candl_matrix_list_print(FILE * file, CandlMatrixList * list)
+-{ candl_matrix_list_print_structure(file,list,0) ;
+-}
+-
+-
+-/******************************************************************************
+- * Memory deallocation function *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_matrix_free function:
+- * This function frees the allocated memory for a CandlMatrix structure.
+- * - 09/12/2005: first version.
+- */
+-void candl_matrix_free(CandlMatrix * matrix)
+-{ pip_matrix_free(matrix) ;
+-}
+-
+-
+-/**
+- * candl_matrix_list_free function:
+- * This function frees the allocated memory for a CandlMatrixList structure.
+- * - 11/12/2005: first version.
+- */
+-void candl_matrix_list_free(CandlMatrixList * list)
+-{ CandlMatrixList * next ;
+-
+- while (list != NULL)
+- { next = list->next ;
+- pip_matrix_free(list->matrix) ;
+- free(list) ;
+- list = next ;
+- }
+-}
+-
+-
+-/******************************************************************************
+- * Reading functions *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_matrix_read function:
+- * This function reads a matrix into a file (foo, posibly stdin) and returns a
+- * pointer to a CandlMatrix containing the read informations.
+- * - 09/12/2005: first version.
+- */
+-CandlMatrix * candl_matrix_read(FILE * file)
+-{ return pip_matrix_read(file) ;
+-}
+-
+-
+-/**
+- * cloog_domain_list_read function:
+- * This function reads a list of matrices into a file (foo, posibly stdin) and
+- * returns a pointer to a CandlMatrixList containing the read information.
+- * - 11/12/2005: first version (from CLooG 0.14.0's cloog_domain_list_read).
+- */
+-CandlMatrixList * candl_matrix_list_read(FILE * file)
+-{ int i, nb_matrices ;
+- char s[CANDL_MAX_STRING] ;
+- CandlMatrixList * list, * now, * next ;
+-
+- /* We read first the number of matrices in the list. */
+- while (fgets(s,CANDL_MAX_STRING,file) == 0) ;
+- while ((*s=='#' || *s=='\n') || (sscanf(s," %d",&nb_matrices)<1))
+- fgets(s,CANDL_MAX_STRING,file) ;
+-
+- /* Then we read the matrices. */
+- list = NULL ;
+- if (nb_matrices > 0)
+- { list = (CandlMatrixList *)malloc(sizeof(CandlMatrixList)) ;
+- list->matrix = candl_matrix_read(file) ;
+- list->next = NULL ;
+- now = list ;
+- for (i=1;i<nb_matrices;i++)
+- { next = (CandlMatrixList *)malloc(sizeof(CandlMatrixList)) ;
+- next->matrix = candl_matrix_read(file) ;
+- next->next = NULL ;
+- now->next = next ;
+- now = now->next ;
+- }
+- }
+-
+- return(list) ;
+-}
+-
+-
+-/******************************************************************************
+- * Processing functions *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_matrix_malloc function:
+- * This function allocates the memory space for a CandlMatrix structure and
+- * sets its fields with default values. Then it returns a pointer to the
+- * allocated space.
+- * - 09/12/2005: first version.
+- */
+-CandlMatrix * candl_matrix_malloc(int nb_rows, int nb_columns)
+-{ return pip_matrix_alloc(nb_rows,nb_columns) ;
+-}
+-
+-
+-/**
+- * candl_matrix_list_malloc function:
+- * This function allocates the memory space for a CandlMatrixList structure and
+- * sets its fields with default values. Then it returns a pointer to the
+- * allocated space.
+- * - 11/12/2005: first version.
+- */
+-CandlMatrixList * candl_matrix_list_malloc()
+-{ CandlMatrixList * list ;
+-
+- /* Memory allocation for the CandlDependence structure. */
+- list = (CandlMatrixList *)malloc(sizeof(CandlMatrixList)) ;
+- if (list == NULL)
+- { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
+- exit(1) ;
+- }
+-
+- /* We set the various fields with default values. */
+- list->matrix = NULL ;
+- list->next = NULL ;
+-
+- return list ;
+-}
+-
+-
++#include <stdlib.h>
++#include <stdio.h>
++#include <ctype.h>
++#include <string.h>
++#include <osl/macros.h>
++#include <osl/relation.h>
++#include <osl/extensions/dependence.h>
++#include <candl/macros.h>
++#include <candl/matrix.h>
++#include <candl/violation.h>
++#include <candl/piplib.h>
++#include <candl/piplib-wrapper.h>
+
+
+ /**
+@@ -335,7 +55,7 @@ CandlMatrixList * candl_matrix_list_malloc()
+ * this function builds the constraint system corresponding to a violation of a
+ * dependence, for a given transformation couple at a given depth.
+ * - dependence is the constraint system of a dependence between two
+- statements,
++ statements,
+ * - t_source is the transformation function for the source statement,
+ * - t_target is the transformation function for the target statement,
+ * - dimension is the transformation dimension checked for legality,
+@@ -343,116 +63,249 @@ CandlMatrixList * candl_matrix_list_malloc()
+ ***
+ * - 13/12/2005: first version (extracted from candl_violation).
+ */
+-CandlMatrix * candl_matrix_violation(dependence,t_source,t_target,
+- dimension,nb_par)
+-CandlMatrix * dependence, * t_source, * t_target ;
+-int dimension, nb_par ;
+-{ int i, j, nb_rows, nb_columns, constraint, s_dims, t_dims ;
+- CandlMatrix * system ;
+- Entier temp ;
+-
+- CANDL_init(temp) ;
+-
+- /* The number of dimensions of the source and target domains. */
+- s_dims = t_source->NbColumns - nb_par - 2 ;
+- t_dims = t_target->NbColumns - nb_par - 2 ;
+-
+- /* Size of the constraint system. */
+- nb_rows = dependence->NbRows + dimension + 1 ;
+- nb_columns = dependence->NbColumns ;
+-
+- /* We allocate memory space for the constraint system. */
+- system = candl_matrix_malloc(nb_rows, nb_columns) ;
+-
+- /* We fill the constraint system (there is no need to put zeros in the
+- * empty zones since candl_matrix_alloc initialized all to 0):
+- */
+-
+- /* 1. We copy the constraints of the dependence polyhedron. */
+- for (i = 0; i < dependence->NbRows; i++)
+- for (j = 0; j < dependence->NbColumns; j++)
+- CANDL_assign(system->p[i][j],dependence->p[i][j]) ;
+-
+- constraint = dependence->NbRows ;
+-
+- /* 2. We set the equality constraints (equality tag is already 0). */
+- for (i = 0; i < dimension; i++)
+- { /* The source dimension part. */
+- for (j = 1; j <= s_dims; j++)
+- CANDL_assign(system->p[constraint][j],t_source->p[i][j]) ;
++candl_violation_p candl_matrix_violation(osl_dependence_p dependence,
++ osl_relation_p source,
++ osl_relation_p target,
++ int dimension, int nb_par) {
++ candl_violation_p violation;
++ osl_relation_p system;
++ int i, j, k, c;
++ int constraint = 0;
++ int precision = dependence->domain->precision;
++ int nb_rows, nb_columns;
++ int nb_output_dims, nb_input_dims, nb_local_dims;
++ int ind_source_output_scatt;
++ int ind_target_output_scatt;
++ int ind_source_local_scatt;
++ int ind_target_local_scatt;
++ int ind_params;
++
++ /* Create a new violation structure */
++ violation = candl_violation_malloc();
++
++ violation->source_nb_output_dims_scattering = source->nb_output_dims;
++ violation->target_nb_output_dims_scattering = target->nb_output_dims;
++ violation->source_nb_local_dims_scattering = source->nb_local_dims;
++ violation->target_nb_local_dims_scattering = target->nb_local_dims;
++
++ /* Compute the system size */
++ nb_local_dims = dependence->domain->nb_local_dims +
++ violation->source_nb_local_dims_scattering +
++ violation->target_nb_local_dims_scattering;
++ nb_output_dims = dependence->domain->nb_output_dims +
++ violation->source_nb_output_dims_scattering;
++ nb_input_dims = dependence->domain->nb_input_dims +
++ violation->target_nb_output_dims_scattering;
++
++ nb_columns = nb_output_dims + nb_input_dims + nb_local_dims + nb_par + 2;
++ nb_rows = dependence->domain->nb_rows +
++ source->nb_rows + target->nb_rows +
++ dimension;
++
++ system = osl_relation_pmalloc(precision, nb_rows, nb_columns);
++
++ /* Compute some indexes */
++ ind_source_output_scatt = 1 + dependence->domain->nb_output_dims;
++ ind_target_output_scatt = ind_source_output_scatt + source->nb_output_dims +
++ dependence->domain->nb_input_dims;
++ ind_source_local_scatt = ind_target_output_scatt + target->nb_output_dims +
++ dependence->domain->nb_local_dims;
++ ind_target_local_scatt = ind_source_local_scatt + source->nb_local_dims +
++ dependence->domain->nb_local_dims;
++ ind_params = ind_target_local_scatt + target->nb_local_dims;
++
++ /* 1. Copy the dependence domain */
++ for (i = 0 ; i < dependence->domain->nb_rows ; i++) {
++ /* eq/in */
++ osl_int_assign(precision,
++ &system->m[constraint][0],
++ dependence->domain->m[i][0]);
++ /* output dims */
++ k = 1;
++ j = 1;
++ for (c = dependence->domain->nb_output_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ dependence->domain->m[i][j]);
++ /* input dims */
++ k += source->nb_output_dims;
++ for (c = dependence->domain->nb_input_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ dependence->domain->m[i][j]);
++ /* source local dims */
++ k += target->nb_output_dims;
++ for (c = dependence->source_nb_local_dims_domain +
++ dependence->source_nb_local_dims_access ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ dependence->domain->m[i][j]);
++ /* target local dims */
++ k += source->nb_local_dims;
++ for (c = dependence->target_nb_local_dims_domain +
++ dependence->target_nb_local_dims_access ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ dependence->domain->m[i][j]);
++ /* params + const */
++ k = ind_params;
++ for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ dependence->domain->m[i][j]);
++ constraint++;
++ }
++
++ /* 2. Copy the source scattering */
++ for (i = 0 ; i < source->nb_rows ; i++) {
++ /* eq/in */
++ osl_int_assign(precision,
++ &system->m[constraint][0],
++ source->m[i][0]);
++ /* output dims */
++ k = ind_source_output_scatt;
++ j = 1;
++ for (c = source->nb_output_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ source->m[i][j]);
++ /* input dims (linked with the output dims of domain) */
++ k = 1;
++ for (c = source->nb_input_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ source->m[i][j]);
++ /* local dims */
++ k = ind_source_local_scatt;
++ for (c = source->nb_local_dims ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ source->m[i][j]);
++ /* params + const */
++ k = ind_params;
++ for (c = nb_par+1 ; c > 0 ; c--, k++, j++)
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ source->m[i][j]);
++ constraint++;
++ }
+
+- /* The -target dimension part. */
+- for (; j <= s_dims + t_dims; j++)
+- { CANDL_oppose(temp,t_target->p[i][j - s_dims]) ;
+- CANDL_assign(system->p[constraint][j], temp) ;
++ /* 2. Copy the target scattering */
++ for (i = 0 ; i < target->nb_rows ; i++) {
++ /* eq/in */
++ osl_int_assign(precision,
++ &system->m[constraint][0],
++ target->m[i][0]);
++ /* output dims */
++ k = ind_target_output_scatt;
++ j = 1;
++ for (c = target->nb_output_dims ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ target->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k],
++ system->m[constraint][k]);
+ }
+-
+- /* The source-target parameter/scalar part. */
+- for (; j < nb_columns; j++)
+- CANDL_subtract(system->p[constraint][j],
+- t_source->p[i][j - t_dims],
+- t_target->p[i][j - s_dims]) ;
+- constraint++ ;
++ /* input dims (linked with the output dims of domain) */
++ k = 1 + nb_output_dims;
++ for (c = target->nb_input_dims ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ target->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k],
++ system->m[constraint][k]);
++ }
++ /* local dims */
++ k = ind_target_local_scatt;
++ for (c = target->nb_local_dims ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ target->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k],
++ system->m[constraint][k]);
++ }
++ /* params + const */
++ k = ind_params;
++ for (c = nb_par+1 ; c > 0 ; c--, k++, j++) {
++ osl_int_assign(precision,
++ &system->m[constraint][k],
++ target->m[i][j]);
++ osl_int_oppose(precision,
++ &system->m[constraint][k],
++ system->m[constraint][k]);
++ }
++ constraint++;
+ }
+-
+- /* 3. We set the target < source constraint. */
+- /* This is an inequality. */
+- CANDL_set_si(system->p[constraint][0], 1) ;
+-
+- /* The source dimension part. */
+- for (j = 1; j<= s_dims; j++)
+- CANDL_assign(system->p[constraint][j],t_source->p[dimension][j]) ;
+-
+- /* The -target dimension part. */
+- for (; j<= s_dims + t_dims; j++)
+- { CANDL_oppose(temp,t_target->p[dimension][j - s_dims]) ;
+- CANDL_assign(system->p[constraint][j],temp) ;
++
++ /* 3. We set the equality constraints */
++ k = ind_source_output_scatt;
++ j = ind_target_output_scatt;
++ for (i = 1; i < dimension; i++, k++, j++) {
++ /* source */
++ osl_int_set_si(precision, &system->m[constraint][k], 1);
++ /* target */
++ osl_int_set_si(precision, &system->m[constraint][j], -1);
++ constraint++;
+ }
+
+- /* The source-target parameter/scalar part. */
+- for (; j < nb_columns; j++)
+- CANDL_subtract(system->p[constraint][j],
+- t_source->p[dimension][j - t_dims],
+- t_target->p[dimension][j - s_dims]) ;
++ /* 4. We set the target < source constraint. */
++ osl_int_set_si(precision, &system->m[constraint][0], 1);
++ /* source */
++ osl_int_set_si(precision, &system->m[constraint][k], 1);
++ /* target */
++ osl_int_set_si(precision, &system->m[constraint][j], -1);
+ /* We subtract 1 to the scalar to achieve >0 constraint. */
+- CANDL_decrement(system->p[constraint][nb_columns - 1],
+- system->p[constraint][nb_columns - 1]) ;
+-
+- CANDL_clear(temp) ;
+- return system ;
++ osl_int_decrement(precision,
++ &system->m[constraint][nb_columns - 1],
++ system->m[constraint][nb_columns - 1]);
++
++ system->nb_output_dims = nb_output_dims;
++ system->nb_input_dims = nb_input_dims;
++ system->nb_parameters = nb_par;
++ system->nb_local_dims = nb_local_dims;
++ system->type = OSL_UNDEFINED;
++
++ violation->domain = system;
++
++ return violation;
+ }
+
+
+-
+-
+ /**
+ * candl_matrix_check_point function:
+ * This function checks if there is an integral point in the set of
+ * constraints, provided a given domain (possibly NULL).
+ *
++ * FIXME : is it the same as pip_has_rational_point ?
++ * here options->Nq = 1 (default)
+ */
+ int
+-candl_matrix_check_point (CandlMatrix* domain,
+- CandlMatrix* context)
+-{
+-#ifdef CANDL_HAS_PIPLIB_HYBRID
+- return piplib_hybrid_has_integer_point (domain, context, 0);
+-#else
++candl_matrix_check_point(osl_relation_p domain,
++ osl_relation_p context) {
++// FIXME : compatibility with osl
++//#ifdef CANDL_HAS_PIPLIB_HYBRID
++// return piplib_hybrid_has_integer_point (domain, context, 0);
++//#else
+ PipOptions* options;
+ PipQuast* solution;
+ int ret = 0;
+- options = pip_options_init ();
++ options = pip_options_init();
+ options->Simplify = 1;
+ options->Urs_parms = -1;
+ options->Urs_unknowns = -1;
+- solution = pip_solve (domain, context, -1, options);
++
++ solution = pip_solve_osl(domain, context, -1, options);
+
+ if ((solution != NULL) &&
+ ((solution->list != NULL) || (solution->condition != NULL)))
+ ret = 1;
+- pip_options_free (options);
+- pip_quast_free (solution);
++ pip_options_free(options);
++ pip_quast_free(solution);
+
+ return ret;
+-#endif
++//#endif
+ }
++
+diff --git a/source/options.c b/source/options.c
+index fea449f..91a738a 100644
+--- a/source/options.c
++++ b/source/options.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: september 8th 2003 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -37,7 +37,7 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+-#include <candl/candl.h>
++#include <candl/macros.h>
+ #include <candl/options.h>
+
+
+@@ -48,12 +48,11 @@
+
+ /**
+ * candl_option_print function:
+- * This function prints the content of a CandlOptions structure (program) into
++ * This function prints the content of a candl_options_t structure (program) into
+ * a file (foo, possibly stdout).
+ * April 19th 2003: first version.
+ */
+-void candl_options_print(FILE * foo, CandlOptions * options)
+-{
++void candl_options_print(FILE * foo, candl_options_p options) {
+ fprintf(foo, "Options:\n");
+ }
+
+@@ -65,11 +64,10 @@ void candl_options_print(FILE * foo, CandlOptions * options)
+
+ /**
+ * candl_options_free function:
+- * This function frees the allocated memory for a CandlOptions structure.
++ * This function frees the allocated memory for a candl_options_t structure.
+ * April 19th 2003: first version.
+ */
+-void candl_options_free(CandlOptions * options)
+-{
++void candl_options_free(candl_options_p options) {
+ free(options);
+ }
+
+@@ -81,19 +79,17 @@ void candl_options_free(CandlOptions * options)
+
+ /**
+ * candl_options_malloc function:
+- * This functions allocate the memory space for a CandlOptions structure and
++ * This functions allocate the memory space for a candl_options_t structure and
+ * fill its fields with the defaults values. It returns a pointer to the
+- * allocated CandlOptions structure.
++ * allocated candl_options_t structure.
+ * April 19th 2003: first version.
+ */
+-CandlOptions * candl_options_malloc(void)
+-{
+- CandlOptions * options;
+-
+- /* Memory allocation for the CandlOptions structure. */
+- options = (CandlOptions *) malloc(sizeof(CandlOptions));
+- if (options == NULL)
+- {
++candl_options_p candl_options_malloc(void) {
++ candl_options_p options;
++
++ /* Memory allocation for the candl_options_t structure. */
++ options = (candl_options_p) malloc(sizeof(candl_options_t));
++ if (options == NULL) {
+ fprintf(stderr, "[Candl]ERROR: memory overflow.\n");
+ exit(1);
+ }
+@@ -106,16 +102,13 @@ CandlOptions * candl_options_malloc(void)
+ options->rar = 0; /* RAR (input) dependences don't matter. */
+ options->commute = 0; /* Don't use commutativity to simplify dependences.*/
+ options->fullcheck = 0; /* Don't compute all violations.*/
+- options->depgraph = 0; /* Don't print the dependence graph.*/
+- options->violgraph = 0; /* Don' compute the violation graph.*/
+ options->scalar_renaming = 0; /* Don't enable scalar renaming. */
+ options->scalar_privatization = 0; /* Don't enable scalar privatization. */
+ options->scalar_expansion = 0; /* Don't enable scalar expansion. */
+ options->lastwriter = 0; /* Compute the last writer for RAW and WAW dependences */
+- options->readscop = 0; /* Don't read a .scop format for the input. */
+- options->writescop = 0; /* Don't write a .scop format for the output. */
+- options->scoptocandl = 0; /* Don't act as a .scop to candl converter. */
+ options->verbose = 0; /* Don't be verbose. */
++ options->outscop = 0; /* Don't print the scop. */
++ options->autocorrect = 0; /* Don't correct violations. */
+ /* UNDOCUMENTED OPTIONS FOR THE AUTHOR ONLY */
+ options->view = 0; /* Do not visualize the graph with dot and gv.*/
+ options->structure = 0; /* Don't print internal dependence structure. */
+@@ -132,54 +125,54 @@ CandlOptions * candl_options_malloc(void)
+ * limitation of the ISO C 89 compilers.
+ * August 5th 2002: first version.
+ */
+-void candl_options_help()
+-{ printf(
+- "Usage: candl [ options | file ] ...\n"
+- "Options for data dependence computation:\n"
+- " -waw <boolean> Consider WAW (output) dependences (1) or not (0)\n"
+- " (default setting: 1).\n"
+- " -raw <boolean> Consider RAW (flow) dependences (1) or not (0)\n"
+- " (default setting: 1).\n"
+- " -war <boolean> Consider WAR (anti) dependences (1) or not (0)\n"
+- " (default setting: 1).\n"
+- " -rar <boolean> Consider RAR (input) dependences (1) or not (0)\n"
+- " (default setting: 0).\n");
++void candl_options_help() {
++ printf(
++ "Usage: candl [ options | file ] ...\n"
++ "Options for data dependence computation:\n"
++ " -waw <boolean> Consider WAW (output) dependences (1) or not (0)\n"
++ " (default setting: 1).\n"
++ " -raw <boolean> Consider RAW (flow) dependences (1) or not (0)\n"
++ " (default setting: 1).\n"
++ " -war <boolean> Consider WAR (anti) dependences (1) or not (0)\n"
++ " (default setting: 1).\n"
++ " -rar <boolean> Consider RAR (input) dependences (1) or not (0)\n"
++ " (default setting: 0).\n");
+ printf(
+- " -commute <boolean> Consider commutativity (1) or not (0)\n"
+- " (default setting: 0).\n"
+- " -fullcheck <boolean> Compute all legality violation (1) or only one (0)\n"
+- " (default setting: 0).\n"
+- " -depgraph <boolean> Ask to print the dependence graph (1) or not (0)\n"
+- " (default setting: 0 but 1 if no transformation).\n"
+- " -violgraph <boolean> Ask to print the violation graph (1) or not (0)\n"
+- " (default setting: 1 but 0 if no transformation).\n"
+- " -scalren <boolean> Ask to enable scalar renaming (1) or not (0)\n"
+- " (default setting: 0).\n"
+- " -scalpriv <boolean> Ask to enable scalar privatization (1) or not (0)\n"
+- " (default setting: 0).\n"
+- " -scalexp <boolean> Ask to enable scalar expansion (1) or not (0)\n"
+- " (default setting: 0).\n");
++ " -commute <boolean> Consider commutativity (1) or not (0)\n"
++ " (default setting: 0).\n"
++ " -fullcheck <boolean> Compute all legality violation (1) or just the\n"
++ " first (0)\n"
++ " (default setting: 0, or 1 if autocorrect is set).\n"
++ " -scalren <boolean> Ask to enable scalar renaming (1) or not (0)\n"
++ " (default setting: 0).\n"
++ " -scalpriv <boolean> Ask to enable scalar privatization (1) or not (0)\n"
++ " (default setting: 0).\n"
++ " -scalexp <boolean> Ask to enable scalar expansion (1) or not (0)\n"
++ " (default setting: 0).\n");
+ printf(
+- " -view Ask to display the graphs (1) or not (0)\n"
+- " (requires dot -graphviz- and gv tools).\n");
++ " -view Ask to display the graphs (1) or not (0)\n"
++ " (requires dot -graphviz- and gv tools).\n");
+ printf(
+- "\nGeneral options:\n"
+-#ifdef CANDL_SUPPORTS_SCOPLIB
+- " -inscop Read a .scop formatted file as the input.\n"
+- " -outscop Output a .scop formatted file as the output.\n"
+- " -scoptocandl Output a .candl formatted file from a .scop input.\n"
+-#endif
+- " -o <output> Name of the output file; 'stdout' is a special\n"
+- " value: when used, output is standard output\n"
+- " (default setting: stdout).\n"
+- " -verbose Display a verbose output.\n"
+- " -v, --version Display the version information.\n"
+- " -h, --help Display this information.\n\n"
+- "The special value 'stdin' for 'file' makes Candl to read data on\n"
+- "standard input.\n\n"
+- "For bug reporting or any suggestions, please send an email to the author\n"
+- "<cedric.bastoul@inria.fr> or to the maintainer of Candl:\n"
+- "<pouchet@cse.ohio-state.edu>.\n");
++ "\nGeneral options:\n"
++ " -test <origscop> Test violations with the original scop.\n"
++ //" -autocorrect <boolean> Correct violations with a shifting (1) or not(0)\n"
++ " -test must be set\n"
++ " (default setting: 0).\n"
++ " -outscop Output a .scop formatted file as the output.\n"
++ " -o <output> Name of the output file; 'stdout' is a special\n"
++ " value: when used, output is standard output\n"
++ " (default setting: stdout).\n"
++ " -verbose Display a verbose output.\n"
++ " -v, --version Display the version information.\n"
++ " -h, --help Display this information.\n\n"
++ "The special value 'stdin' for 'file' makes Candl to read data on standard\n"
++ "input.\n"
++ "If the -test is not given, the dependences graph of the input 'file' will\n"
++ "be computed, otherwise it's the violation graph between 'origscop' and 'file'"
++ ".\n\n"
++ "For bug reporting or any suggestions, please send an email to the author\n"
++ "<cedric.bastoul@inria.fr> or to the maintainer of Candl:\n"
++ "<pouchet@cse.ohio-state.edu>.\n");
+ }
+
+
+@@ -190,32 +183,31 @@ void candl_options_help()
+ * characters limitation of the ISO C 89 compilers.
+ * August 5th 2002: first version.
+ */
+-void candl_options_version()
+-{ printf("Candl %s %s bits The Chunky Dependence Analyzer\n",
++void candl_options_version() { printf("Candl %s %s bits The Chunky Dependence Analyzer\n",
+ CANDL_RELEASE,CANDL_VERSION);
+ printf(
+- "-----\n"
+- "Candl is a dependence analyzer for static control programs, coming from \n"
+- "the CHUNKY project: a research tool for data-locality improvement. This \n"
+- "program is distributed under the terms of the GNU Lesser General Public\n"
+- "License (details at http://www.gnu.org/copyleft/gpl.html).\n"
+- "-----\n");
++ "-----\n"
++ "Candl is a dependence analyzer for static control programs, coming from \n"
++ "the CHUNKY project: a research tool for data-locality improvement. This \n"
++ "program is distributed under the terms of the GNU Lesser General Public\n"
++ "License (details at http://www.gnu.org/copyleft/gpl.html).\n"
++ "-----\n");
+ printf(
+- "It would be kind to refer the following paper in any publication "
+- "resulting \nfrom the use of this software or its library:\n"
+- "@Article{Bas05,\n"
+- "author = {Cedric Bastoul and Paul Feautrier},\n"
+- "title = {Adjusting a program transformation for legality},\n"
+- "journal = {Parallel Processing Letters},\n"
+- "year = 2005,\n"
+- "volume = 15,\n"
+- "number = 1,\n"
+- "pages = {3--17},\n"
+- "month = {March},\n"
+- "}\n"
+- "-----\n"
+- "For bug reporting or any suggestions, please send an email to the author\n"
+- "<cedric.bastoul@inria.fr>.\n");
++ "It would be kind to refer the following paper in any publication "
++ "resulting \nfrom the use of this software or its library:\n"
++ "@Article{Bas05,\n"
++ "author = {Cedric Bastoul and Paul Feautrier},\n"
++ "title = {Adjusting a program transformation for legality},\n"
++ "journal = {Parallel Processing Letters},\n"
++ "year = 2005,\n"
++ "volume = 15,\n"
++ "number = 1,\n"
++ "pages = {3--17},\n"
++ "month = {March},\n"
++ "}\n"
++ "-----\n"
++ "For bug reporting or any suggestions, please send an email to the author\n"
++ "<cedric.bastoul@inria.fr>.\n");
+ }
+
+
+@@ -229,20 +221,17 @@ void candl_options_version()
+ * August 5th 2002: first version.
+ * June 29th 2003: (debug) lack of argument now detected.
+ */
+-void candl_options_set(int * option, int argc, char ** argv, int * number)
+-{
++void candl_options_set(int * option, int argc, char ** argv, int * number) {
+ char ** endptr;
+
+- if (*number+1 >= argc)
+- {
++ if (*number+1 >= argc) {
+ fprintf(stderr, "[Candl]ERROR: an option lacks of argument.\n");
+ exit(1);
+ }
+
+ endptr = NULL;
+ *option = strtol(argv[*number+1],endptr,10);
+- if (endptr != NULL)
+- {
++ if (endptr != NULL) {
+ fprintf(stderr, "[Candl]ERROR: %s option value is not valid.\n",
+ argv[*number]);
+ exit(1);
+@@ -254,155 +243,167 @@ void candl_options_set(int * option, int argc, char ** argv, int * number)
+ /**
+ * candl_options_read function:
+ * This functions reads all the options and the input/output files thanks
+- * the the user's calling line elements (in argc). It fills a CandlOptions
++ * the the user's calling line elements (in argc). It fills a candl_options_t
+ * structure and the FILE structure corresponding to input and output files.
+ * August 5th 2002: first version.
+- * April 19th 2003: now in options.c and support of the CandlOptions structure.
++ * April 19th 2003: now in options.c and support of the candl_options_t structure.
+ */
+ void candl_options_read(int argc, char** argv, FILE** input, FILE** output,
+- CandlOptions** options)
+-{
+- int i, infos = 0, input_is_set = 0;
++ FILE **input_test, candl_options_p* options) {
++ int i, infos = 0, input_is_set = 0, testscop_is_set = 0;
+
+- /* CandlOptions structure allocation and initialization. */
++ /* candl_options_t structure allocation and initialization. */
+ *options = candl_options_malloc();
+ /* The default output is the standard output. */
+ *output = stdout;
+-
+- for (i = 1; i < argc; i++)
+- if (argv[i][0] == '-')
+- {
+- if (!strcmp(argv[i], "-waw"))
+- candl_options_set(&(*options)->waw, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-raw"))
+- candl_options_set(&(*options)->raw, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-war"))
+- candl_options_set(&(*options)->war, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-rar"))
+- candl_options_set(&(*options)->rar, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-commute"))
+- candl_options_set(&(*options)->commute, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-fullcheck"))
+- candl_options_set(&(*options)->fullcheck, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-depgraph"))
+- candl_options_set(&(*options)->depgraph, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-violgraph"))
+- candl_options_set(&(*options)->violgraph, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-scalren"))
+- candl_options_set(&(*options)->scalar_renaming, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-scalpriv"))
+- candl_options_set(&(*options)->scalar_privatization, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-scalexp"))
+- candl_options_set(&(*options)->scalar_expansion, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-lastwriter"))
+- candl_options_set(&(*options)->lastwriter, argc, argv, &i);
+- else
+- if (!strcmp(argv[i], "-view"))
+- (*options)->view = 1;
+- else
+- if (!strcmp(argv[i], "-verbose"))
+- (*options)->verbose = 1;
+- else
+- if (!strcmp(argv[i], "-inscop"))
+- (*options)->readscop = 1;
+- else
+- if (!strcmp(argv[i], "-outscop"))
+- (*options)->writescop = 1;
+- else
+- if (!strcmp(argv[i], "-scoptocandl"))
+- (*options)->scoptocandl = 1;
+- else
+- if (!strcmp(argv[i], "-prune-dups"))
+- (*options)->prune_dups = 1;
+- else
+- if ((!strcmp(argv[i], "-struct")) ||
+- (!strcmp(argv[i], "-structure")))
+- (*options)->structure = 1;
+- else
+- if ((!strcmp(argv[i], "--help")) || (!strcmp(argv[i], "-h")))
+- {
+- candl_options_help();
+- infos = 1;
+- }
+- else
+- if ((!strcmp(argv[i], "--version")) || (!strcmp(argv[i], "-v")))
+- {
+- candl_options_version();
+- infos = 1;
+- }
+- else
+- if (!strcmp(argv[i], "-o"))
+- {
+- if (i+1 >= argc)
+- {
+- fprintf(stderr,
+- "[Candl]ERROR: no output name for -o option.\n");
+- exit(1);
+- }
+-
+- /* stdout is a special value, when used, we set output to standard
+- * output.
+- */
+- if (!strcmp(argv[i+1], "stdout"))
+- *output = stdout;
+- else
+- {
+- *output = fopen(argv[i+1], "w");
+- if (*output == NULL)
+- {
+- fprintf(stderr,
+- "[Candl]ERROR: can't create output file %s.\n",
+- argv[i+1]);
+- exit(1);
+- }
+- }
+- i++;
+- }
+- else
+- fprintf(stderr, "[Candl]ERROR: unknown %s option.\n", argv[i]);
++ *input_test = NULL;
++
++ for (i = 1; i < argc; i++) {
++ if (argv[i][0] == '-') {
++ if (!strcmp(argv[i], "-waw")) {
++ candl_options_set(&(*options)->waw, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-raw")) {
++ candl_options_set(&(*options)->raw, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-war")) {
++ candl_options_set(&(*options)->war, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-rar")) {
++ candl_options_set(&(*options)->rar, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-commute")) {
++ candl_options_set(&(*options)->commute, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-fullcheck")) {
++ candl_options_set(&(*options)->fullcheck, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-scalren")) {
++ candl_options_set(&(*options)->scalar_renaming, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-scalpriv")) {
++ candl_options_set(&(*options)->scalar_privatization, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-scalexp")) {
++ candl_options_set(&(*options)->scalar_expansion, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-lastwriter")) {
++ candl_options_set(&(*options)->lastwriter, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-autocorrect")) {
++ candl_options_set(&(*options)->autocorrect, argc, argv, &i);
++ } else
++ if (!strcmp(argv[i], "-view")) {
++ (*options)->view = 1;
++ } else
++ if (!strcmp(argv[i], "-verbose")) {
++ (*options)->verbose = 1;
++ } else
++ if (!strcmp(argv[i], "-outscop")) {
++ (*options)->outscop = 1;
++ } else
++ if (!strcmp(argv[i], "-prune-dups")) {
++ (*options)->prune_dups = 1;
++ } else
++ if ((!strcmp(argv[i], "-struct")) ||
++ (!strcmp(argv[i], "-structure"))) {
++ (*options)->structure = 1;
++ } else
++ if ((!strcmp(argv[i], "--help")) || (!strcmp(argv[i], "-h"))) {
++ candl_options_help();
++ infos = 1;
++ } else
++ if ((!strcmp(argv[i], "--version")) || (!strcmp(argv[i], "-v"))) {
++ candl_options_version();
++ infos = 1;
++ } else
++ if (!strcmp(argv[i], "-o")) {
++ i++;
++ if (i >= argc) {
++ fprintf(stderr,
++ "[Candl]ERROR: no output name for -o option.\n");
++ exit(1);
++ }
++
++ /* stdout is a special value, when used, we set output to standard
++ * output.
++ */
++ if (!strcmp(argv[i], "stdout")) {
++ *output = stdout;
++ } else {
++ *output = fopen(argv[i], "w");
++ if (*output == NULL) {
++ fprintf(stderr,
++ "[Candl]ERROR: can't create output file %s.\n",
++ argv[i]);
++ exit(1);
++ }
++ }
++ } else
++ if (!strcmp(argv[i], "-test")) {
++ i++;
++ if (!testscop_is_set) {
++ testscop_is_set = i;
++ /* stdin is a special value, when used, we set input to
++ standard input. */
++ if (!strcmp(argv[i], "stdin")) {
++ *input_test = stdin;
++ } else {
++ *input_test = fopen(argv[i], "r");
++ if (*input_test == NULL) {
++ fprintf(stderr,
++ "[Candl]ERROR: %s file does not exist.\n", argv[i]);
++ exit(1);
++ }
++ }
++ } else {
++ fprintf(stderr, "[Candl]ERROR: multiple input files.\n");
++ exit(1);
++ }
++ } else {
++ fprintf(stderr, "[Candl]ERROR: unknown %s option.\n", argv[i]);
+ }
+- else
+- {
+- if (!input_is_set)
+- {
+- input_is_set = 1;
+- /* stdin is a special value, when used, we set input to
+- standard input. */
+- if (!strcmp(argv[i], "stdin"))
+- *input = stdin;
+- else
+- {
+- *input = fopen(argv[i], "r");
+- if (*input == NULL)
+- {
+- fprintf(stderr,
+- "[Candl]ERROR: %s file does not exist.\n", argv[i]);
+- exit(1);
+- }
+- }
++ }
++ else { /* open a file */
++ if (!input_is_set) {
++ input_is_set = i;
++ /* stdin is a special value, when used, we set input to
++ standard input. */
++ if (!strcmp(argv[i], "stdin")) {
++ *input = stdin;
++ } else {
++ *input = fopen(argv[i], "r");
++ if (*input == NULL) {
++ fprintf(stderr,
++ "[Candl]ERROR: %s file does not exist.\n", argv[i]);
++ exit(1);
++ }
++ }
++ } else {
++ CANDL_error("multiple input files.\n");
+ }
+- else
+- {
+- fprintf(stderr, "[Candl]ERROR: multiple input files.\n");
+- exit(1);
+ }
+ }
+- if (!input_is_set)
+- {
+- if (!infos)
+- fprintf(stderr, "[Candl]ERROR: no input file (-h for help).\n");
+- exit(1);
+- }
++
++ if ((*options)->autocorrect) {
++ (*options)->fullcheck = 1;
++ if (!*input_test)
++ CANDL_error("no test file (-h for help).\n");
++ }
++
++ if (!input_is_set) {
++ if (!infos)
++ CANDL_error("no input file (-h for help).\n");
++ exit(1);
++ }
++
++ if (*input_test && !strcmp(argv[input_is_set], argv[testscop_is_set])) {
++ if (!infos)
++ CANDL_error("the input file and the test scop can't be the same file.\n");
++ exit(1);
++ }
++
++ if (infos)
++ exit(0);
+ }
+
+diff --git a/source/piplib-wrapper.c b/source/piplib-wrapper.c
+index 2ff4bb7..cdd44f3 100644
+--- a/source/piplib-wrapper.c
++++ b/source/piplib-wrapper.c
+@@ -1,13 +1,13 @@
+
+- /**------ ( ----------------------------------------------------------**
+- ** )\ CAnDL **
+- **----- / ) --------------------------------------------------------**
+- ** ( * ( piplib-wrapper.c **
+- **---- \#/ --------------------------------------------------------**
+- ** .-"#'-. First version: January 31st 2012 **
+- **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++/**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( piplib-wrapper.c **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: January 31st 2012 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -42,16 +42,99 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <candl/candl.h>
++#include <osl/macros.h> /* Need OSL_PRECISION for compatibility with piplib */
++#include <osl/relation.h>
++#include <candl/macros.h>
++#include <candl/piplib.h>
+
+
+-int
+-pip_has_rational_point(PipMatrix* system,
+- PipMatrix* context,
+- int conservative)
+-{
+-#ifdef CANDL_HAS_PIPLIB_HYBRID
+- return piplib_hybrid_has_rational_point(system, context, conservative);
+-#else
++/**
++ * pip_relation2matrix function :
++ * This function is used to keep the compatibility with Piplib
++ */
++PipMatrix* pip_relation2matrix(osl_relation_p in) {
++ int i, j, precision;
++ PipMatrix *out;
++
++ if (in == NULL)
++ return NULL;
++
++ #ifdef CANDL_LINEAR_VALUE_IS_INT
++ precision = OSL_PRECISION_SP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ precision = OSL_PRECISION_DP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ precision = OSL_PRECISION_MP;
++ #endif
++
++ if (precision != in->precision)
++ CANDL_error("Precision not compatible with piplib ! (pip_relation2matrix)");
++
++ out = pip_matrix_alloc(in->nb_rows, in->nb_columns);
++
++ for (i = 0 ; i < in->nb_rows ; i++) {
++ for (j = 0 ; j < in->nb_columns ; j++) {
++ #if defined(CANDL_LINEAR_VALUE_IS_INT)
++ CANDL_assign(out->p[i][j], in->m[i][j].sp);
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ CANDL_assign(out->p[i][j], in->m[i][j].dp);
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ CANDL_assign(out->p[i][j], *((mpz_t*)in->m[i][j].mp));
++ #endif
++ }
++ }
++
++ return out;
++}
++
++
++/**
++ * pip_matrix2relation function :
++ * This function is used to keep the compatibility with Piplib
++ */
++osl_relation_p pip_matrix2relation(PipMatrix* in) {
++ int i, j, precision;
++ osl_relation_p out;
++ osl_int_t temp;
++
++ if (in == NULL)
++ return NULL;
++
++ #if defined(CANDL_LINEAR_VALUE_IS_INT)
++ precision = OSL_PRECISION_SP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ precision = OSL_PRECISION_DP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ precision = OSL_PRECISION_MP;
++ #endif
++
++ out = osl_relation_pmalloc(precision, in->NbRows, in->NbColumns);
++ osl_int_init(precision, &temp);
++
++ for (i = 0 ; i < in->NbRows ; i++) {
++ for (j = 0 ; j < in->NbColumns ; j++) {
++ #ifdef CANDL_LINEAR_VALUE_IS_INT
++ temp.sp = in->p[i][j];
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ temp.dp = in->p[i][j];
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ mpz_set(*((mpz_t*)temp.mp), in->p[i][j]);
++ #endif
++ osl_int_assign(precision, &out->m[i][j], temp);
++ }
++ }
++
++ osl_int_clear(precision, &temp);
++ return out;
++}
++
++int pip_has_rational_point(osl_relation_p system,
++ osl_relation_p context,
++ int conservative) {
++// FIXME : compatibility with osl
++//#ifdef CANDL_HAS_PIPLIB_HYBRID
++// return piplib_hybrid_has_rational_point(system, context, conservative);
++//#else
+ PipOptions* options;
+ int ret = 0;
+ options = pip_options_init ();
+@@ -59,13 +142,256 @@ pip_has_rational_point(PipMatrix* system,
+ options->Urs_parms = -1;
+ options->Urs_unknowns = -1;
+ options->Nq = 0;
+- PipQuast* solution = pip_solve (system, context, -1, options);
++ PipQuast* solution = pip_solve_osl(system, context, -1, options);
+ if ((solution != NULL) &&
+ ((solution->list != NULL) || (solution->condition != NULL)))
+ ret = 1;
+- pip_options_free (options);
+- pip_quast_free (solution);
++ pip_options_free(options);
++ pip_quast_free(solution);
+ return ret;
+-#endif
++//#endif
+ }
+
++
++/**
++ * pip_solve_osl function :
++ * A pip_solve with osl_relation_p instead of PipMatrix
++ */
++PipQuast* pip_solve_osl(osl_relation_p inequnk, osl_relation_p ineqpar,
++ int Bg, PipOptions *options) {
++ PipMatrix *pip_unk = pip_relation2matrix(inequnk);
++ PipMatrix *pip_par = pip_relation2matrix(ineqpar);
++ PipQuast *solution = pip_solve(pip_unk, pip_par, Bg, options);
++ if (pip_unk) pip_matrix_free(pip_unk);
++ if (pip_par) pip_matrix_free(pip_par);
++ return solution;
++}
++
++
++/**
++ * Return true if the 'size' first elements of 'l1' and 'l2' are equal.
++ */
++int piplist_are_equal(PipList* l1, PipList* l2, int size) {
++ if (l1 == NULL && l2 == NULL)
++ return 1;
++ if (l1 == NULL || l2 == NULL)
++ return 0;
++ if (l1->vector == NULL && l2->vector == NULL)
++ return 1;
++ if (l1->vector == NULL || l2->vector == NULL)
++ return 0;
++
++ int count = 0;
++ for (; l1 && l2 && count < size; l1 = l1->next, l2 = l2->next, ++count) {
++ if (l1->vector == NULL && l2->vector == NULL)
++ return 1;
++ if (l1->vector == NULL || l2->vector == NULL)
++ return 0;
++ if (l1->vector->nb_elements != l2->vector->nb_elements)
++ return 0;
++ int j;
++ for (j = 0; j < l1->vector->nb_elements; ++j)
++ if (! CANDL_eq(l1->vector->the_vector[j],
++ l2->vector->the_vector[j]) ||
++ ! CANDL_eq(l1->vector->the_deno[j],
++ l2->vector->the_deno[j]))
++ return 0;
++ }
++
++ return 1;
++}
++
++
++/*
++ * Converts all conditions where the path does not lead to a solution
++ * The return is a upip_quast_to_polyhedranion of polyhedra
++ * extracted from pip_quast_to_polyhedra
++ */
++osl_relation_p pip_quast_no_solution_to_polyhedra(PipQuast *quast, int nvar,
++ int npar) {
++ osl_relation_p ep;
++ osl_relation_p tp;
++ osl_relation_p qp;
++ osl_relation_p iter;
++ int precision;
++ int j;
++ if (quast == NULL)
++ return NULL;
++
++ #if defined(CANDL_LINEAR_VALUE_IS_INT)
++ precision = OSL_PRECISION_SP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ precision = OSL_PRECISION_DP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ precision = OSL_PRECISION_MP;
++ #endif
++
++ if (quast->condition != NULL) {
++ tp = pip_quast_no_solution_to_polyhedra(quast->next_then, nvar, npar);
++ ep = pip_quast_no_solution_to_polyhedra(quast->next_else, nvar, npar);
++
++ /* Each of the matrices in the then tree needs to be augmented with
++ * the condition */
++ for (iter = tp ; iter != NULL ; iter = iter->next) {
++ int nrows = iter->nb_rows;
++ osl_int_set_si(precision, &iter->m[nrows][0], 1);
++ for (j = 1; j < 1 + nvar; j++)
++ osl_int_set_si(precision, &iter->m[nrows][j], 0);
++ for (j = 0; j < npar + 1; j++)
++ osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
++ CANDL_get_si(quast->condition->the_vector[j]));
++ (iter->nb_rows)++;
++ }
++
++ for (iter = ep; iter != NULL ; iter = iter->next) {
++ int nrows = iter->nb_rows;
++ /* Inequality */
++ osl_int_set_si(precision, &iter->m[nrows][0], 1);
++ for (j = 1; j < 1 + nvar; j++)
++ osl_int_set_si(precision, &iter->m[nrows][j], 0);
++ for (j = 0; j < npar + 1; j++)
++ osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
++ -CANDL_get_si(quast->condition->the_vector[j]));
++ osl_int_decrement(precision,
++ &iter->m[nrows][iter->nb_columns - 1],
++ iter->m[nrows][iter->nb_columns - 1]);
++ (iter->nb_rows)++;
++ }
++
++ /* union of tp and ep */
++ if (tp) {
++ qp = tp;
++ for (iter = tp ; iter->next != NULL ; iter = iter->next)
++ ;
++ iter->next = ep;
++ } else {
++ qp = ep;
++ }
++
++ return qp;
++
++ }
++
++ if (quast->list != NULL)
++ return NULL;
++
++ /* quast condition is NULL */
++ osl_relation_p lwmatrix = osl_relation_pmalloc(precision, nvar+npar+1,
++ nvar+npar+2);
++ lwmatrix->nb_rows = 0;
++ lwmatrix->nb_parameters = npar;
++
++ return lwmatrix;
++}
++
++
++/*
++ * Converts a PIP quast to a union of polyhedra
++ */
++osl_relation_p pip_quast_to_polyhedra(PipQuast *quast, int nvar, int npar) {
++ // originaly used for lastwriter
++ // july 5th 2012 : extracted from dependence.c
++
++ osl_relation_p ep;
++ osl_relation_p tp;
++ osl_relation_p qp;
++ osl_relation_p iter;
++ int precision;
++ int j;
++ if (quast == NULL)
++ return NULL;
++
++ #if defined(CANDL_LINEAR_VALUE_IS_INT)
++ precision = OSL_PRECISION_SP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_LONGLONG)
++ precision = OSL_PRECISION_DP;
++ #elif defined(CANDL_LINEAR_VALUE_IS_MP)
++ precision = OSL_PRECISION_MP;
++ #endif
++
++ if (quast->condition != NULL) {
++ tp = pip_quast_to_polyhedra(quast->next_then, nvar, npar);
++ ep = pip_quast_to_polyhedra(quast->next_else, nvar, npar);
++
++ /* Each of the matrices in the then tree needs to be augmented with
++ * the condition */
++ for (iter = tp ; iter != NULL ; iter = iter->next) {
++ int nrows = iter->nb_rows;
++ osl_int_set_si(precision, &iter->m[nrows][0], 1);
++ for (j = 1; j < 1 + nvar; j++)
++ osl_int_set_si(precision, &iter->m[nrows][j], 0);
++ for (j = 0; j < npar + 1; j++)
++ osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
++ CANDL_get_si(quast->condition->the_vector[j]));
++ (iter->nb_rows)++;
++ }
++
++ /* JP : july 5th 2012:
++ * Fix negation of a constraint in adding -1 to the constant
++ */
++
++ for (iter = ep; iter != NULL ; iter = iter->next) {
++ int nrows = iter->nb_rows;
++ /* Inequality */
++ osl_int_set_si(precision, &iter->m[nrows][0], 5);
++ for (j = 1; j < 1 + nvar; j++)
++ osl_int_set_si(precision, &iter->m[nrows][j], 0);
++ for (j = 0; j < npar + 1; j++)
++ osl_int_set_si(precision, &iter->m[nrows][1 + nvar + j],
++ -CANDL_get_si(quast->condition->the_vector[j]));
++ osl_int_decrement(precision,
++ &iter->m[nrows][iter->nb_columns - 1],
++ iter->m[nrows][iter->nb_columns - 1]);
++ (iter->nb_rows)++;
++ }
++
++ /* union of tp and ep */
++ if (tp) {
++ qp = tp;
++ for (iter = tp ; iter->next != NULL ; iter = iter->next)
++ ;
++ iter->next = ep;
++ } else {
++ qp = ep;
++ }
++
++ return qp;
++
++ } else {
++ /* quast condition is NULL */
++ osl_relation_p lwmatrix = osl_relation_pmalloc(precision, nvar+npar+1,
++ nvar+npar+2);
++ PipList *vecList = quast->list;
++
++ int count=0;
++ while (vecList != NULL) {
++ /* Equality */
++ osl_int_set_si(precision, &lwmatrix->m[count][0], 0);
++ for (j=0; j < nvar; j++)
++ if (j == count)
++ osl_int_set_si(precision, &lwmatrix->m[count][j + 1], 1);
++ else
++ osl_int_set_si(precision, &lwmatrix->m[count][j + 1], 0);
++
++ for (j=0; j < npar; j++)
++ osl_int_set_si(precision, &lwmatrix->m[count][j + 1 + nvar],
++ -CANDL_get_si(vecList->vector->the_vector[j]));
++ /* Constant portion */
++ if (quast->newparm != NULL)
++ /* Don't handle newparm for now */
++ osl_int_set_si(precision, &lwmatrix->m[count][npar + 1 + nvar],
++ -CANDL_get_si(vecList->vector->the_vector[npar+1]));
++ else
++ osl_int_set_si(precision, &lwmatrix->m[count][npar + 1 + nvar],
++ -CANDL_get_si(vecList->vector->the_vector[npar]));
++
++ count++;
++
++ vecList = vecList->next;
++ }
++ lwmatrix->nb_rows = count;
++ lwmatrix->nb_parameters = npar;
++
++ return lwmatrix;
++ }
++}
+diff --git a/source/program.c b/source/program.c
+deleted file mode 100644
+index 003e753..0000000
+--- a/source/program.c
++++ /dev/null
+@@ -1,574 +0,0 @@
+-
+- /**------ ( ----------------------------------------------------------**
+- ** )\ CAnDL **
+- **----- / ) --------------------------------------------------------**
+- ** ( * ( program.c **
+- **---- \#/ --------------------------------------------------------**
+- ** .-"#'-. First version: september 9th 2003 **
+- **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
+- ******** | | *************************************************************
+- * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+- ******************************************************************************
+- * *
+- * Copyright (C) 2003-2008 Cedric Bastoul *
+- * *
+- * This is free software; you can redistribute it and/or modify it under the *
+- * terms of the GNU Lesser General Public License as published by the Free *
+- * Software Foundation; either version 3 of the License, or (at your option) *
+- * any later version. *
+- * *
+- * This software is distributed in the hope that it will be useful, but *
+- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
+- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
+- * for more details. *
+- * *
+- * You should have received a copy of the GNU Lesser General Public License *
+- * along with software; if not, write to the Free Software Foundation, Inc., *
+- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+- * *
+- * CAnDL, the Chunky Dependence Analyzer *
+- * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+- * *
+- ******************************************************************************/
+-
+-
+-#include <sys/types.h>
+-#include <sys/time.h>
+-#include <sys/resource.h>
+-#include <stdlib.h>
+-#include <stdio.h>
+-#include <string.h>
+-#include <ctype.h>
+-
+-#include <candl/candl.h>
+-#include <candl/program.h>
+-
+-
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-
+-/**
+- * candl_program_print_structure function:
+- * Displays a candl_program_t structure (program) into a file (file,
+- * possibly stdout) in a way that trends to be understandable without falling
+- * in a deep depression or, for the lucky ones, getting a headache... It
+- * includes an indentation level (level) in order to work with others
+- * print_structure functions.
+- * - 09/09/2003: first version.
+- */
+-void candl_program_print_structure(FILE* file, candl_program_p program,
+- int level)
+-{
+- int i, j;
+-
+- if (program != NULL)
+- {
+- /* Go to the right level. */
+- for (j = 0; j < level; j++)
+- fprintf(file,"|\t");
+- fprintf(file,"+-- candl_program_t\n");
+-
+- /* A blank line. */
+- for (j = 0; j <= level + 1; j++)
+- fprintf(file,"|\t");
+- fprintf(file,"\n");
+-
+- /* Print the context. */
+- candl_matrix_print_structure(file, program->context, level+1);
+-
+- /* A blank line. */
+- for (j = 0; j <= level+1; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
+-
+- /* Go to the right level and print the statement number. */
+- for (j = 0; j <= level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "Statement number: %d\n", program->nb_statements);
+-
+- /* A blank line. */
+- for (j = 0; j <= level+1; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
+-
+- /* Print the statements. */
+- for (i = 0; i < program->nb_statements; ++i)
+- candl_statement_print_structure(file, program->statement[i], level+1);
+-
+- /* Print the transformation candidate. */
+- if (program->transformation != NULL)
+- for (i = 0; i < program->nb_statements; i++)
+- candl_matrix_print_structure(file, program->transformation[i], level+1);
+- else
+- {
+- /* Go to the right level. */
+- for (j = 0; j <= level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "+-- No transformation candidate\n");
+-
+- /* A blank line. */
+- for (j = 0; j <= level+1; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
+- }
+- }
+- else
+- {
+- /* Go to the right level. */
+- for (j = 0; j < level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "+-- NULL candl_program_t\n");
+- }
+-
+- /* The last line. */
+- for (j = 0; j <= level; j++)
+- fprintf(file, "|\t");
+- fprintf(file, "\n");
+-}
+-
+-
+-/**
+- * candl_program_print function:
+- * This function prints the content of a candl_program_t structure
+- * (program) into a file (file, possibly stdout).
+- */
+-void candl_program_print(FILE * file, candl_program_p program)
+-{
+- candl_program_print_structure(file, program,0);
+-}
+-
+-
+-
+-/**
+- * candl_program_print function:
+- * This function prints a candl_program_t structure (program) into a
+- * candl-formatted file (file, possibly stdout).
+- */
+-void candl_program_print_candl_file(FILE * file, candl_program_p program)
+-{
+- int i, j;
+-
+- fprintf (file, "# -------------------\n");
+- fprintf (file, "# Context\n");
+- candl_matrix_print_data(file, program->context);
+- fprintf (file, "\n");
+- fprintf (file, "# Number of statements\n");
+- fprintf (file, "%d\n", program->nb_statements);
+- for (i = 0; i < program->nb_statements; ++i)
+- {
+- fprintf (file, "# -------------------\n");
+- fprintf (file, "# Statement %d\n", i + 1);
+- fprintf (file, "# Statement type\n");
+- /* All types set to Assignment. */
+- fprintf (file, "A\n");
+- fprintf (file, "\n");
+- fprintf (file, "# Iteration domain\n");
+- candl_matrix_print_data(file, program->statement[i]->domain);
+- fprintf (file, "\n");
+- fprintf (file, "# Loop labels\n");
+- for (j = 0; j < program->statement[i]->depth; ++j)
+- fprintf (file, "%d ", program->statement[i]->index[j]);
+- fprintf (file, "\n");
+- fprintf (file, "# Written items\n");
+- candl_matrix_print_data(file, program->statement[i]->written);
+- fprintf (file, "\n");
+- fprintf (file, "# Read items\n");
+- candl_matrix_print_data(file, program->statement[i]->read);
+- fprintf (file, "\n");
+- }
+- fprintf (file, "# -------------------\n");
+- fprintf (file, "# Transformation candidate\n");
+- fprintf (file, "0\n");
+-}
+-
+-
+-/******************************************************************************
+- * Memory alloc/dealloc function *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_program_malloc function:
+- * This function allocates the memory space for a candl_program_t structure and
+- * sets its fields with default values. Then it returns a pointer to the
+- * allocated space.
+- * - 09/12/2005: first version.
+- */
+-candl_program_p candl_program_malloc()
+-{
+- candl_program_p program;
+-
+- /* Memory allocation for the candl_program_t structure. */
+- program = (candl_program_p)malloc(sizeof(candl_program_t));
+- if (program == NULL)
+- CANDL_FAIL("Error: memory overflow");
+-
+- /* We set the various fields with default values. */
+- program->context = NULL;
+- program->nb_statements = 0;
+- program->statement = NULL;
+- program->transformation = NULL;
+- program->scalars_privatizable = NULL;
+-
+- return program;
+-}
+-
+-
+-/**
+- * candl_program_free function:
+- * This function frees the allocated memory for a candl_program_t structure, it
+- * recursively frees everything inside.
+- */
+-void candl_program_free(candl_program_p program)
+-{
+- int i;
+-
+- candl_matrix_free(program->context);
+-
+- if (program->statement != NULL)
+- {
+- for (i = 0; i < program->nb_statements; i++)
+- candl_statement_free(program->statement[i]);
+- free(program->statement);
+- }
+-
+- if (program->transformation != NULL)
+- {
+- for (i = 0; i < program->nb_statements; i++)
+- candl_matrix_free(program->transformation[i]);
+- free(program->transformation);
+- }
+-
+- if (program->scalars_privatizable != NULL)
+- free(program->scalars_privatizable);
+-
+- free(program);
+-}
+-
+-
+-/******************************************************************************
+- * Reading function *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_program_read function:
+- * This function reads the informations to put in a candl_program_t
+- * structure from a file (file, possibly stdin). It returns a pointer
+- * to a candl_program_t structure containing the read informations.
+- * September 10th 2003: first version.
+- */
+-candl_program_p candl_program_read(FILE * file)
+-{
+- int i, nb_statements, nb_parameters, nb_functions;
+- char s[CANDL_MAX_STRING];
+- CandlStatement ** statement;
+- CandlMatrix ** transformation;
+- candl_program_p program;
+-
+- /* Memory allocation for the candl_program_t structure. */
+- program = candl_program_malloc();
+-
+- /* First of all, we read the context data. */
+- program->context = candl_matrix_read(file);
+- nb_parameters = program->context->NbColumns - 2;
+-
+- /* We read the number of statements. */
+- while (fgets(s, CANDL_MAX_STRING, file) == 0)
+- ;
+- while ((*s=='#'||*s=='\n') || (sscanf(s, " %d", &nb_statements) < 1))
+- fgets(s, CANDL_MAX_STRING, file);
+-
+- program->nb_statements = nb_statements;
+-
+- /* Reading of each statement. */
+- if (nb_statements > 0)
+- {
+- /* Memory allocation for the array of pointers to the statements. */
+- statement = (CandlStatement**) malloc(nb_statements *
+- sizeof(CandlStatement*));
+- if (statement == NULL)
+- CANDL_FAIL("Error: memory overflow");
+-
+- for (i = 0; i < nb_statements; i++)
+- statement[i] = candl_statement_read(file, i, nb_parameters);
+-
+- program->statement = statement;
+- }
+-
+- /* We read the number of transformation functions. */
+- while (fgets(s, CANDL_MAX_STRING, file) == 0)
+- ;
+- while ((*s=='#' || *s=='\n') || (sscanf(s, " %d", &nb_functions) < 1))
+- fgets(s, CANDL_MAX_STRING, file);
+-
+- /* Reading of each transformation function. */
+- if (nb_functions > 0)
+- {
+- /* The function number must be the same as statement number. */
+- if (nb_functions != nb_statements)
+- {
+- fprintf(stderr,
+- "[Candl]ERROR: the numbers of transformations (%d) and "
+- "statements (%d) differ.\n", nb_functions, nb_statements);
+- exit(1);
+- }
+-
+- /* Memory allocation for the array of pointers to the functions. */
+- transformation = (CandlMatrix **)malloc(nb_functions *
+- sizeof(CandlMatrix *));
+- if (transformation == NULL)
+- CANDL_FAIL("Error: memory overflow");
+-
+- for (i = 0; i < nb_functions; i++)
+- transformation[i] = candl_matrix_read(file);
+-
+- program->transformation = transformation;
+- }
+-
+- return(program);
+-}
+-
+-
+-/**
+- * This function reads the .scop formatted file 'file', check for the
+- * existence of the <candl> tag in the file, and retrieve the loop
+- * index information, if any.
+- * This function is built only if candl was configured with ScopLib support.
+- *
+- */
+-#ifdef CANDL_SUPPORTS_SCOPLIB
+-static
+-int** candl_program_scop_get_opt_indices(scoplib_scop_p scop)
+-{
+- /* Get the <candl></candl> tag content. */
+- char* candl_opts = scoplib_scop_tag_content(scop, "<candl>", "</candl>");
+- if (! candl_opts)
+- return NULL;
+- /* Get the <candl><indices></indices></candl> tag content. */
+- char* indices = scoplib_scop_tag_content_from_string(candl_opts, "<indices>",
+- "</indices>");
+- free (candl_opts);
+- if (! indices)
+- return NULL;
+-
+- /* Tag was found. Scan it. */
+- int buffer_size = 128;
+- /* Assume maximum loop nest depth of 128. */
+- int line[128];
+- char buff[32];
+- int** res = malloc(buffer_size * sizeof(int*));
+- int i, j;
+- int count, idx = 0;
+- int line_added = 0;
+- char* s = indices;
+-
+- while (s && *s != '\0')
+- {
+- for (i = 0; i < 128; ++i)
+- {
+- while (*s != '\0' && *s != '\n' && isspace(*s))
+- ++s;
+- if (*s != '\0' && *s != '#' && *s != '\n')
+- {
+- for (count = 0; *s >= '0' && *s <= '9'; ++count)
+- buff[count] = *(s++);
+- buff[count] = '\0';
+- line[i] = atoi(buff);
+- line_added = 1;
+- }
+- else
+- break;
+- }
+- if (line_added)
+- {
+- if (idx == buffer_size)
+- res = realloc(res, (buffer_size *= 2) * sizeof(int*));
+- res[idx] = (int*) malloc(i * sizeof(int));
+- for (j = 0; j < i; ++j)
+- res[idx][j] = line[j];
+- ++idx;
+- line_added = 0;
+- }
+- while (s && *s != '\0' && *s != '\n')
+- ++s;
+- if (s && *s != '\0' && *s == '\n')
+- ++s;
+- }
+- res = realloc(res, idx * sizeof(int*));
+- free (indices);
+-
+- return res;
+-}
+-#endif
+-
+-
+-/**
+- * candl_program_read_scop function:
+- * This function reads the informations to put in a candl_program_t
+- * structure from a file (file, possibly stdin) following the .scop
+- * format. It returns a pointer to a candl_program_t structure
+- * containing the read informations.
+- * This function is built only if candl was configured with ScopLib support.
+- *
+- */
+-#ifdef CANDL_SUPPORTS_SCOPLIB
+-candl_program_p candl_program_read_scop(FILE * file)
+-{
+- int i;
+-
+- /* Read the scop. */
+- scoplib_scop_p scop = scoplib_scop_read(file);
+- /* Check for the <candl> tag in the options of the .scop file. */
+- int** indices = candl_program_scop_get_opt_indices(scop);
+- /* Convert the scop. */
+- candl_program_p res = candl_program_convert_scop(scop, indices);
+-
+- /* Clean temporary data. */
+- if (indices)
+- {
+- for (i = 0; i < res->nb_statements; ++i)
+- free(indices[i]);
+- free(indices);
+- }
+- scoplib_scop_free(scop);
+-
+- return res;
+-}
+-#endif
+-
+-
+-/******************************************************************************
+- * Processing functions *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_program_convert_scop function:
+- * This function extracts the useful information of a scoplib_scop_t
+- * structure to a fresh, independent candl_program_t structure.
+- * This function is built only if candl was configured with ScopLib support.
+- *
+- */
+-#ifdef CANDL_SUPPORTS_SCOPLIB
+-candl_program_p candl_program_convert_scop(scoplib_scop_p scop, int** indices)
+-{
+- int i, j, k, l;
+- candl_program_p res = candl_program_malloc();
+- scoplib_statement_p s = scop->statement;
+-
+- /* Duplicate the context. */
+- res->context = (CandlMatrix*) scoplib_matrix_copy(scop->context);
+- if (res->context == NULL)
+- res->context = candl_matrix_malloc(0, 2);
+-
+- /* Count the number of statements. */
+- for (res->nb_statements = 0; s; s = s->next, res->nb_statements++)
+- ;
+-
+- /* Allocate the statements array. */
+- res->statement = (CandlStatement**) malloc(res->nb_statements *
+- sizeof(CandlStatement*));
+-
+- /* Initialize structures used in iterator indices computation. */
+- int max = 0;
+- int max_loop_depth = 128;
+- int cur_index[max_loop_depth];
+- int last[max_loop_depth];
+- for (i = 0; i < max_loop_depth; ++i)
+- {
+- cur_index[i] = i;
+- last[i] = 0;
+- }
+- /* Create the statements. */
+- for (i = 0, s = scop->statement; s; s = s->next, ++i)
+- {
+- CandlStatement* statement = candl_statement_malloc();
+- statement->label = i;
+- statement->ref = s;
+- if (s->domain->next != NULL)
+- CANDL_FAIL("Error: union of domains not supported");
+-
+- statement->domain = (CandlMatrix*) scoplib_matrix_copy(s->domain->elt);
+- /* For the moment, we do not parse the statement to extract its type. */
+- statement->type = CANDL_ASSIGNMENT;
+- statement->depth = statement->domain->NbColumns - 2 - scop->nb_parameters;
+- statement->written = (CandlMatrix*) scoplib_matrix_copy(s->write);
+- if (statement->written == NULL)
+- statement->written =
+- candl_matrix_malloc(0, statement->domain->NbColumns);
+- statement->read = (CandlMatrix*) scoplib_matrix_copy(s->read);
+- if (statement->read == NULL)
+- statement->read = candl_matrix_malloc(0, statement->domain->NbColumns);
+- statement->index = (int*) malloc(statement->depth * sizeof(int));
+- if (indices != NULL)
+- /* Iterator indices are provided. */
+- for (j = 0; j < statement->depth; ++j)
+- statement->index[j] = indices[i][j];
+- else
+- {
+- /* Iterator indices must be computed from the scattering matrix. */
+- scoplib_matrix_p m = s->schedule;
+- if (m == NULL)
+- CANDL_FAIL("Error: No scheduling matrix and no loop "
+- "indices specification");
+-
+- /* FIXME: Sort the statements in their execution order. */
+- /* It must be a 2d+1 identity scheduling matrix, and
+- statements must be sorted in their execution order. */
+- /* Check that it is a identity matrix. */
+- int error = 0;
+- if (m->NbRows != 2 * statement->depth + 1)
+- error = 1;
+- else
+- for (l = 0; l < m->NbRows; ++l)
+- {
+- for (k = 1; k < m->NbColumns - 1; ++k)
+- switch (CANDL_get_si(m->p[l][k]))
+- {
+- case 0:
+- if (l % 2 && k == (l / 2) + 1) error = 1;
+- break;
+- case 1:
+- if ((l % 2 && k != (l / 2) + 1) || (! l % 2)) error = 1;
+- break;
+- default:
+- error = 1;
+- break;
+- }
+- if (l % 2 && CANDL_get_si(m->p[l][k]))
+- error = 1;
+- }
+- if (error)
+- CANDL_FAIL("Error: schedule is not identity 2d+1 shaped.\n"
+- "Consider using the <indices> option tag to declare "
+- " iterator indices");
+-
+- /* Compute the value of the iterator indices. */
+- for (j = 0; j < statement->depth; ++j)
+- {
+- int val = CANDL_get_si(m->p[2 * j][m->NbColumns - 1]);
+- if (last[j] < val)
+- {
+- last[j] = val;
+- for (k = j + 1; k < max_loop_depth; ++k)
+- last[k] = 0;
+- for (k = j; k < max_loop_depth; ++k)
+- cur_index[k] = max + (k - j) + 1;
+- break;
+- }
+- }
+- for (j = 0; j < statement->depth; ++j)
+- statement->index[j] = cur_index[j];
+- max = max < cur_index[j - 1] ? cur_index[j - 1] : max;
+- }
+- /* Store the statement. */
+- res->statement[i] = statement;
+- }
+-
+- return res;
+-}
+-#endif
+diff --git a/source/pruning.c b/source/pruning.c
+index 2b0cf49..db4a90f 100644
+--- a/source/pruning.c
++++ b/source/pruning.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: July 17th 2011 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -40,35 +40,15 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+-#include <candl/candl.h>
+-
+ #include <assert.h>
++#include <osl/statement.h>
++#include <osl/relation.h>
++#include <candl/statement.h>
++#include <candl/dependence.h>
+
+
+-/**
+- * Return true if the 2 matrices are strictly identical.
+- */
+-static
+-int candl_matrix_equal(CandlMatrix* m1, CandlMatrix* m2)
+-{
+- int i, j;
++#if defined(CANDL_COMPILE_PRUNNING_C)
+
+- if (m1 == NULL)
+- {
+- if (m2 == NULL)
+- return 1;
+- return 0;
+- }
+-
+- if (m1->NbRows != m2->NbRows || m1->NbColumns != m2->NbColumns)
+- return 0;
+-
+- for (i = 0; i < m1->NbRows; ++i)
+- for (j = 0; j < m1->NbColumns; ++j)
+- if (! CANDL_eq(m1->p[i][j], m2->p[i][j]))
+- return 0;
+- return 1;
+-}
+
+ #define BUFF_SIZE 1024
+
+@@ -79,79 +59,69 @@ int candl_matrix_equal(CandlMatrix* m1, CandlMatrix* m2)
+ * Paths are stored as list of lists of dependences in 'paths_list'.
+ */
+ static
+-void find_paths_rec (int tgt_id, int cur_length, int max_length,
+- int final_id,
+- CandlDependence** alldeps,
+- CandlDependence** cur_path,
+- CandlDependence**** paths_list)
+-{
++void find_paths_rec(int tgt_id, int cur_length, int max_length,
++ int final_id,
++ osl_dependence_p* alldeps,
++ osl_dependence_p* cur_path,
++ osl_dependence_p*** paths_list) {
+ int i;
+
+- for (i = 0; alldeps[i]; ++i)
+- {
+- if (alldeps[i]->usr == NULL)
+- {
+- if (alldeps[i]->source->label == tgt_id)
+- {
+- // Ensure the path flow is consistent.
+- if (cur_length > 1)
+- {
+- if (cur_path[cur_length - 1]->type == CANDL_RAW ||
+- cur_path[cur_length - 1]->type == CANDL_RAW_SCALPRIV ||
+- cur_path[cur_length - 1]->type == CANDL_RAR)
+- {
+- // RAW or RAR.
+- if (alldeps[i]->type != CANDL_RAR &&
+- alldeps[i]->type != CANDL_WAR)
+- continue;
+- }
+- else
+- {
+- // WAW or WAR.
+- if (alldeps[i]->type != CANDL_WAW &&
+- alldeps[i]->type != CANDL_RAW)
+- continue;
+- }
+- }
+- if (cur_length + 1 == max_length)
+- {
+- if (alldeps[i]->target->label == final_id)
+- {
+- // Found a path.
+- int j, pos;
+- for (pos = 0; (*paths_list)[pos]; ++pos)
+- ;
+- if (pos + 1 % BUFF_SIZE == 0)
+- {
+- *paths_list = (CandlDependence***)
+- realloc(*paths_list, sizeof(CandlDependence**) *
+- (BUFF_SIZE + pos + 1));
+- *paths_list[pos + 1] = NULL;
+- }
+- (*paths_list)[pos] = (CandlDependence**)
+- malloc((max_length + 1) * sizeof(CandlDependence*));
+- for (j = 0; j < max_length - 1; ++j)
+- (*paths_list)[pos][j] = cur_path[j];
+- (*paths_list)[pos][j++] = alldeps[i];
+- (*paths_list)[pos][j] = NULL;
+- }
+- }
+- else
+- {
+- // Store the current node in the path.
+- cur_path[cur_length] = alldeps[i];
+- // Mark the dependence as processed.
+- alldeps[i]->usr = alldeps[i];
+- // Look for the next node.
+- find_paths_rec (alldeps[i]->target->label, cur_length + 1,
+- max_length, final_id, alldeps, cur_path,
+- paths_list);
+- // Reset the dependence.
+- alldeps[i]->usr = NULL;
+- }
+- }
+- }
++ for (i = 0; alldeps[i]; ++i) {
++ if (alldeps[i]->usr == NULL) {
++ ((candl_statement_usr_p)target->usr)->label
++ if (alldeps[i]->((candl_statement_usr_p)source->usr)->label == tgt_id) {
++ // Ensure the path flow is consistent.
++ if (cur_length > 1) {
++ if (cur_path[cur_length - 1]->type == CANDL_RAW ||
++ cur_path[cur_length - 1]->type == CANDL_RAW_SCALPRIV ||
++ cur_path[cur_length - 1]->type == CANDL_RAR) {
++ // RAW or RAR.
++ if (alldeps[i]->type != CANDL_RAR &&
++ alldeps[i]->type != CANDL_WAR)
++ continue;
++ }
++ else {
++ // WAW or WAR.
++ if (alldeps[i]->type != CANDL_WAW &&
++ alldeps[i]->type != CANDL_RAW)
++ continue;
++ }
++ }
++ if (cur_length + 1 == max_length) {
++ if (alldeps[i]->((candl_statement_usr_p)target->usr)->label == final_id) {
++ // Found a path.
++ int j, pos;
++ for (pos = 0; (*paths_list)[pos]; ++pos)
++ ;
++ if (pos + 1 % BUFF_SIZE == 0) {
++ *paths_list = (osl_dependence_p**)
++ realloc(*paths_list, sizeof(osl_dependence_p*) *
++ (BUFF_SIZE + pos + 1));
++ *paths_list[pos + 1] = NULL;
++ }
++ (*paths_list)[pos] = (osl_dependence_p*)
++ malloc((max_length + 1) * sizeof(osl_dependence_p));
++ for (j = 0; j < max_length - 1; ++j)
++ (*paths_list)[pos][j] = cur_path[j];
++ (*paths_list)[pos][j++] = alldeps[i];
++ (*paths_list)[pos][j] = NULL;
++ }
++ }
++ else {
++ // Store the current node in the path.
++ cur_path[cur_length] = alldeps[i];
++ // Mark the dependence as processed.
++ alldeps[i]->usr = alldeps[i];
++ // Look for the next node.
++ find_paths_rec(alldeps[i]->((candl_statement_usr_p)target->usr)->label,
++ cur_length + 1, max_length, final_id, alldeps,
++ cur_path, paths_list);
++ // Reset the dependence.
++ alldeps[i]->usr = NULL;
++ }
++ }
+ }
++ }
+ }
+
+
+@@ -162,91 +132,55 @@ void find_paths_rec (int tgt_id, int cur_length, int max_length,
+ * 'target->label'.
+ */
+ static
+-CandlDependence***
+-find_dep_paths (CandlDependence** ardeps,
+- CandlStatement* source,
+- CandlStatement*target)
+-{
++osl_dependence_p** find_dep_paths(osl_dependence_p* ardeps,
++ osl_statement_p source,
++ osl_statement_p target) {
+ int i, nb_dep;
+ for (nb_dep = 0; ardeps[nb_dep]; ++nb_dep)
+ ;
+ if (nb_dep < 2)
+ return NULL;
+- CandlDependence* cur_path[nb_dep + 1];
+- CandlDependence*** paths_list =
+- (CandlDependence***)malloc(BUFF_SIZE * sizeof(CandlDependence**));
++ osl_dependence_p *cur_path =
++ (osl_dependence_p*) malloc(sizeof(osl_dependence_p) *
++ (nb_dep + 1));
++ osl_dependence_p** paths_list =
++ (osl_dependence_p**)malloc(BUFF_SIZE * sizeof(osl_dependence_p*));
+ for (i = 0; i < BUFF_SIZE; ++i)
+ paths_list[i] = NULL;
+ // Iterate on all possible paths length, from Sx to Sy, of length y-x.
+- for (i = 2; i <= target->label - source->label; ++i)
+- find_paths_rec (source->label, 0, i, target->label, ardeps, cur_path,
+- &paths_list);
+-
++ for (i = 2; i <= ((candl_statement_usr_p)target->usr)->label -
++ ((candl_statement_usr_p)source->usr)->label; ++i)
++ find_paths_rec(((candl_statement_usr_p)source->usr)->label, 0, i,
++ ((candl_statement_usr_p)target->usr)->label, ardeps,
++ cur_path, &paths_list);
++ free(cur_path);
+ return paths_list;
+ }
+
+-/**
+- * Return true if the 'size' first elements of 'l1' and 'l2' are equal.
+- */
+-static
+-int piplist_are_equal (PipList* l1, PipList* l2, int size)
+-{
+- if (l1 == NULL && l2 == NULL)
+- return 1;
+- if (l1 == NULL || l2 == NULL)
+- return 0;
+- if (l1->vector == NULL && l2->vector == NULL)
+- return 1;
+- if (l1->vector == NULL || l2->vector == NULL)
+- return 0;
+-
+- int count = 0;
+- for (; l1 && l2 && count < size; l1 = l1->next, l2 = l2->next, ++count)
+- {
+- if (l1->vector == NULL && l2->vector == NULL)
+- return 1;
+- if (l1->vector == NULL || l2->vector == NULL)
+- return 0;
+- if (l1->vector->nb_elements != l2->vector->nb_elements)
+- return 0;
+- int j;
+- for (j = 0; j < l1->vector->nb_elements; ++j)
+- if (! CANDL_eq(l1->vector->the_vector[j],
+- l2->vector->the_vector[j]) ||
+- ! CANDL_eq(l1->vector->the_deno[j],
+- l2->vector->the_deno[j]))
+- return 0;
+- }
+-
+- return 1;
+-}
+
+ /**
+ * Return true if the 'size' first variables in a quast are strictly
+ * equal.
+ */
+ static
+-int
+-quast_are_equal (PipQuast* q1, PipQuast* q2, int size)
+-{
++int quast_are_equal (PipQuast* q1, PipQuast* q2, int size) {
+ if (q1 == NULL && q2 == NULL)
+ return 1;
+ if (q1 == NULL || q2 == NULL)
+ return 0;
+
+ // Inspect conditions.
+- if (q1->condition != NULL && q2->condition != NULL)
+- {
+- PipList c1; c1.next = NULL; c1.vector = q1->condition;
+- PipList c2; c2.next = NULL; c2.vector = q2->condition;
+- if (! piplist_are_equal(&c1, &c2, size))
+- return 0;
+- return quast_are_equal (q1->next_then, q2->next_then, size) &&
+- quast_are_equal (q1->next_else, q2->next_else, size);
+- }
++ if (q1->condition != NULL && q2->condition != NULL) {
++ PipList c1; c1.next = NULL; c1.vector = q1->condition;
++ PipList c2; c2.next = NULL; c2.vector = q2->condition;
++ if (! piplist_are_equal(&c1, &c2, size))
++ return 0;
++ return quast_are_equal(q1->next_then, q2->next_then, size) &&
++ quast_are_equal(q1->next_else, q2->next_else, size);
++ }
+ if (q1->condition != NULL || q2->condition != NULL)
+ return 0;
+- return piplist_are_equal (q1->list, q2->list, size);
++ return piplist_are_equal(q1->list, q2->list, size);
+ }
+
+ /**
+@@ -256,9 +190,7 @@ quast_are_equal (PipQuast* q1, PipQuast* q2, int size)
+ * corresponding to loop iterators).
+ */
+ static
+-int
+-is_covering (CandlDependence* dep, CandlDependence** path)
+-{
++int is_covering(osl_dependence_p dep, osl_dependence_p* path) {
+ int i, path_length;
+
+ for (path_length = 0; path[path_length]; ++path_length)
+@@ -267,170 +199,154 @@ is_covering (CandlDependence* dep, CandlDependence** path)
+ /// FIXME: This may be overly conservative.
+ // Check the path extremal points type.
+ if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV
+- || dep->type == CANDL_WAW)
+- {
+- // RAW or WAW.
+- if (path[0]->type != CANDL_RAW && path[0]->type != CANDL_RAW_SCALPRIV &&
+- path[0]->type != CANDL_WAW)
+- return 0;
+- if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV)
+- if (path[path_length - 1]->type != CANDL_RAW &&
+- path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
+- path[path_length - 1]->type != CANDL_RAR)
+- return 0;
+- if (dep->type == CANDL_WAW)
+- if (path[path_length - 1]->type != CANDL_WAR &&
+- path[path_length - 1]->type != CANDL_WAW)
+- return 0;
+- }
+- else
+- {
+- // WAR or RAR.
+- if (path[0]->type != CANDL_WAR && path[0]->type != CANDL_RAR)
+- return 0;
+- if (dep->type == CANDL_WAR)
+- if (path[path_length - 1]->type != CANDL_WAW &&
+- path[path_length - 1]->type != CANDL_WAR)
+- return 0;
+- if (dep->type == CANDL_RAR)
+- if (path[path_length - 1]->type != CANDL_RAR &&
+- path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
+- path[path_length - 1]->type != CANDL_RAW)
+- return 0;
+- }
++ || dep->type == CANDL_WAW) {
++ // RAW or WAW.
++ if (path[0]->type != CANDL_RAW && path[0]->type != CANDL_RAW_SCALPRIV &&
++ path[0]->type != CANDL_WAW)
++ return 0;
++ if (dep->type == CANDL_RAW || dep->type == CANDL_RAW_SCALPRIV)
++ if (path[path_length - 1]->type != CANDL_RAW &&
++ path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
++ path[path_length - 1]->type != CANDL_RAR)
++ return 0;
++ if (dep->type == CANDL_WAW)
++ if (path[path_length - 1]->type != CANDL_WAR &&
++ path[path_length - 1]->type != CANDL_WAW)
++ return 0;
++ }
++ else {
++ // WAR or RAR.
++ if (path[0]->type != CANDL_WAR && path[0]->type != CANDL_RAR)
++ return 0;
++ if (dep->type == CANDL_WAR)
++ if (path[path_length - 1]->type != CANDL_WAW &&
++ path[path_length - 1]->type != CANDL_WAR)
++ return 0;
++ if (dep->type == CANDL_RAR)
++ if (path[path_length - 1]->type != CANDL_RAR &&
++ path[path_length - 1]->type != CANDL_RAW_SCALPRIV &&
++ path[path_length - 1]->type != CANDL_RAW)
++ return 0;
++ }
+
+ // a- Fast check. Ensure the dependence depth is consistent across
+ // the path. We may correctly cover _more_ points and still have a
+ // perfect transitive cover.
+ /// FIXME: ambiguous test?
+-/* for (i = 0; i < path_length; ++i) */
+-/* if (path[i]->depth > dep->depth) */
+-/* return 0; */
++ /* for (i = 0; i < path_length; ++i) */
++ /* if (path[i]->depth > dep->depth) */
++ /* return 0; */
+
+ // b- Check the covering property. Works only if
+ // the iterator part of iteration domains and access functions are
+ // unimodular matrices.
+ // Build a large system with all dependences.
+- int nb_par = path[0]->source->domain->NbColumns - path[0]->source->depth - 2;
++ int nb_par = path[0]->domain->nb_parameters;
+ int nb_iters = 0;
+ int nb_rows = 0;
+- for (i = 0; i < path_length; ++i)
+- {
+- nb_iters += path[i]->domain->NbColumns - nb_par - 2;
+- nb_rows += path[i]->domain->NbRows;
+- if (i > 0)
+- nb_iters -= path[i]->source->depth;
+- }
+- CandlMatrix* syst = candl_matrix_malloc (nb_rows, nb_iters + nb_par + 2);
++ for (i = 0; i < path_length; ++i) {
++ nb_iters += path[i]->source_nb_output_dims_domain +
++ path[i]->target_nb_output_dims_domain;
++ nb_rows += path[i]->domain->nb_rows;
++ if (i > 0)
++ nb_iters -= ((candl_statement_usr_p) path[i]->source->usr)->depth;
++ }
++
++ CandlMatrix* syst = candl_matrix_malloc(nb_rows, nb_iters + nb_par + 2);
+ int pos = 0;
+ int j, k;
+ int iter_off = 0;
+- for (k = 0; k < path_length; ++k)
+- {
+- for (i = 0; i < path[k]->domain->NbRows; ++i)
+- {
+- CANDL_assign(syst->p[pos][0], path[k]->domain->p[i][0]);
+- for (j = 1; j < path[k]->domain->NbColumns - 1 - nb_par; ++j)
+- CANDL_assign(syst->p[pos][j + iter_off], path[k]->domain->p[i][j]);
+- for (; j < path[k]->domain->NbColumns; ++j)
+- {
+- int parpos = j - (path[k]->domain->NbColumns - 1 - nb_par) +
+- syst->NbColumns - nb_par - 1;
+- CANDL_assign(syst->p[pos][parpos], path[k]->domain->p[i][j]);
+- }
+- ++pos;
+- }
+- iter_off += path[k]->source->depth;
++ for (k = 0; k < path_length; ++k) {
++ for (i = 0; i < path[k]->domain->NbRows; ++i) {
++ CANDL_assign(syst->p[pos][0], path[k]->domain->p[i][0]);
++ for (j = 1; j < path[k]->domain->NbColumns - 1 - nb_par; ++j)
++ CANDL_assign(syst->p[pos][j + iter_off], path[k]->domain->p[i][j]);
++ for (; j < path[k]->domain->NbColumns; ++j) {
++ int parpos = j - (path[k]->domain->NbColumns - 1 - nb_par) +
++ syst->NbColumns - nb_par - 1;
++ CANDL_assign(syst->p[pos][parpos], path[k]->domain->p[i][j]);
++ }
++ ++pos;
+ }
++ iter_off += path[k]->source->depth;
++ }
+
+ // Algo:
+ // lexmin(dep, R) == lexmin(path, R) && lexmax(dep, R) == lexmax(path, R) &&
+ // lexmin(dep, S) == lexmin(path, S) && lexmax(dep, S) == lexmax(path, S)
+ PipOptions* options;
+- options = pip_options_init ();
++ options = pip_options_init();
+ options->Simplify = 1;
+ options->Urs_parms = -1;
+ options->Urs_unknowns = -1;
+- CandlMatrix* context = candl_matrix_malloc (0, nb_par + 2);
+- PipQuast* qpath = pip_solve (syst, context, -1, options);
+- PipQuast* qdep = pip_solve (dep->domain, context, -1, options);
+- int are_equal = quast_are_equal (qpath, qdep, dep->source->depth);
+- if (are_equal)
+- {
+- pip_quast_free (qpath);
+- pip_quast_free (qdep);
+- options->Maximize = 1;
+- qpath = pip_solve (syst, context, -1, options);
+- qdep = pip_solve (dep->domain, context, -1, options);
+- are_equal = quast_are_equal (qpath, qdep, dep->source->depth);
++ CandlMatrix* context = candl_matrix_malloc(0, nb_par + 2);
++ PipQuast* qpath = pip_solve(syst, context, -1, options);
++ PipQuast* qdep = pip_solve(dep->domain, context, -1, options);
++ int are_equal = quast_are_equal(qpath, qdep, dep->source->depth);
++ if (are_equal) {
++ pip_quast_free (qpath);
++ pip_quast_free (qdep);
++ options->Maximize = 1;
++ qpath = pip_solve(syst, context, -1, options);
++ qdep = pip_solve(dep->domain, context, -1, options);
++ are_equal = quast_are_equal(qpath, qdep, dep->source->depth);
++ }
++ if (are_equal) {
++ pip_quast_free(qpath);
++ pip_quast_free(qdep);
++ options->Maximize = 0;
++ // Permute columns for first and last iterators.
++ for (i = 0; i < dep->target->depth; ++i) {
++ for (j = 0; j < syst->NbRows; ++j) {
++ int tmp = CANDL_get_si(syst->p[j][1]);
++ int pos = syst->NbColumns - 1 - nb_par - dep->target->depth + i;
++ CANDL_assign(syst->p[j][1], syst->p[j][pos]);
++ CANDL_set_si(syst->p[j][pos], tmp);
++ }
+ }
+- if (are_equal)
+- {
+- pip_quast_free (qpath);
+- pip_quast_free (qdep);
+- options->Maximize = 0;
+- // Permute columns for first and last iterators.
+- for (i = 0; i < dep->target->depth; ++i)
+- {
+- for (j = 0; j < syst->NbRows; ++j)
+- {
+- int tmp = CANDL_get_si(syst->p[j][1]);
+- int pos = syst->NbColumns - 1 - nb_par - dep->target->depth + i;
+- CANDL_assign(syst->p[j][1], syst->p[j][pos]);
+- CANDL_set_si(syst->p[j][pos], tmp);
+- }
+- }
+- qpath = pip_solve (syst, context, -1, options);
+- qdep = pip_solve (dep->domain, context, -1, options);
+- are_equal = quast_are_equal (qpath, qdep, dep->target->depth);
+- }
+- if (are_equal)
+- {
+- pip_quast_free (qpath);
+- pip_quast_free (qdep);
+- options->Maximize = 1;
+- qpath = pip_solve (syst, context, -1, options);
+- qdep = pip_solve (dep->domain, context, -1, options);
+- are_equal = quast_are_equal (qpath, qdep, dep->target->depth);
+- }
+-
+- pip_options_free (options);
+- pip_quast_free (qpath);
+- pip_quast_free (qdep);
+- pip_matrix_free (syst);
++ qpath = pip_solve(syst, context, -1, options);
++ qdep = pip_solve(dep->domain, context, -1, options);
++ are_equal = quast_are_equal(qpath, qdep, dep->target->depth);
++ }
++ if (are_equal) {
++ pip_quast_free(qpath);
++ pip_quast_free(qdep);
++ options->Maximize = 1;
++ qpath = pip_solve(syst, context, -1, options);
++ qdep = pip_solve(dep->domain, context, -1, options);
++ are_equal = quast_are_equal(qpath, qdep, dep->target->depth);
++ }
++
++ pip_options_free(options);
++ pip_quast_free(qpath);
++ pip_quast_free(qdep);
++ pip_matrix_free(syst);
+
+ return are_equal;
+ }
+
+ static
+-int
+-is_iter_unimodular (CandlDependence* dep)
+-{
++int is_iter_unimodular(osl_dependence_p dep) {
+ // Check unimodular on the iterator part.
+ int i, j;
+- for (i = 0; i < dep->domain->NbRows; ++i)
+- {
+- if (i < dep->source->domain->NbRows ||
+- i > dep->source->domain->NbRows + dep->target->domain->NbRows)
+- {
+- for (j = 1; j <= dep->source->depth; ++j)
+- {
+- int val = CANDL_get_si(dep->domain->p[i][j]);
+- if (val < -1 || val > 1)
+- return 0;
+- }
+- }
+- else if (i < dep->source->domain->NbRows +
+- dep->target->domain->NbRows ||
+- i > dep->source->domain->NbRows + dep->target->domain->NbRows)
+- {
+- for (j = 1; j <= dep->source->depth; ++j)
+- {
+- int val = CANDL_get_si(dep->domain->p[i][j + dep->source->depth]);
+- if (val < -1 || val > 1)
+- return 0;
+- }
+- }
++ int n;
++ int precision = dep->domain->precision;
++ osl_relation_p matrix;
++
++ matrix = dep->source->domain;
++ for (i = 0 ; i < matrix->nb_rows ; i++)
++ for (j = 1 ; j <= matrix->nb_output_dims ; j++) {
++ n = osl_int_get_si(precision, matrix->m[i][j]);
++ if (n < -1 || n > 1)
++ return 0;
++ }
++
++ matrix = dep->target->domain;
++ for (i = 0 ; i < matrix->nb_rows ; i++)
++ for (j = 1 ; j <= matrix->nb_output_dims ; j++) {
++ n = osl_int_get_si(precision, matrix->m[i][j]);
++ if (n < -1 || n > 1)
++ return 0;
+ }
+
+ return 1;
+@@ -441,157 +357,169 @@ is_iter_unimodular (CandlDependence* dep)
+ * In-place modification of the list of dependence polyhedra.
+ *
+ */
+-CandlDependence*
+-candl_dependence_prune_transitively_covered (CandlDependence* deps)
+-{
+- CandlDependence* tmp;
++osl_dependence_p osl_dependence_prune_transitively_covered(
++ osl_dependence_p deps) {
++ if (deps == NULL)
++ return NULL;
++
++ osl_dependence_p tmp;
++ osl_dependence_p *ardeps;
++ osl_relation_p srcmat;
++ osl_relation_p *allarrays;
++ osl_dependence_p** path;
++ osl_dependence_p *curardeps;
++ candl_statement_usr_p s_usr, t_usr;
++ int precision = deps->domain->precision;
++ int nb_deps;
+
+ // 1- Collect all arrays that occur in dependences.
+ int cnt, i, j, k, l;
+ int nb_stmts = 0;
+- for (tmp = deps, cnt = 0; tmp; tmp = tmp->next)
+- {
+- nb_stmts = tmp->source->label > nb_stmts ? tmp->source->label : nb_stmts;
+- nb_stmts = tmp->target->label > nb_stmts ? tmp->target->label : nb_stmts;
+- ++cnt;
+- }
++ for (tmp = deps, cnt = 0; tmp; tmp = tmp->next) {
++ s_usr = tmp->source->usr;
++ t_usr = tmp->target->usr;
++ nb_stmts = s_usr->label > nb_stmts ? s_usr->label : nb_stmts;
++ nb_stmts = t_usr->label > nb_stmts ? t_usr->label : nb_stmts;
++ ++cnt;
++ }
+ ++nb_stmts;
+- int nb_deps = cnt;
+- int allarrays[cnt];
+- for (tmp = deps, cnt = 0; tmp; tmp = tmp->next)
+- {
+- CandlMatrix* srcmat;
+- if (tmp->type == CANDL_RAW || tmp->type == CANDL_RAW_SCALPRIV
+- || tmp->type == CANDL_WAW)
+- srcmat = tmp->source->written;
+- else
+- srcmat = tmp->source->read;
+- for (i = 0; i < cnt; ++i)
+- if (allarrays[i] == CANDL_get_si(srcmat->p[tmp->ref_source][0]))
+- break;
+- if (i == cnt)
+- allarrays[cnt++] = CANDL_get_si(srcmat->p[tmp->ref_source][0]);
+- }
+- allarrays[cnt] = -1;
++ nb_deps = cnt;
++ allarrays = (osl_relation_p*)malloc(sizeof(osl_relation_p)*cnt);
++
++ for (tmp = deps, cnt = 0; tmp; tmp = tmp->next) {
++ srcmat = candl_dependence_get_relation_ref_source_in_dep(tmp);
++ for (i = 0; i < cnt; ++i)
++ if (allarrays[i] == srcmat)
++ break;
++ if (i == cnt)
++ allarrays[cnt++] = srcmat;
++ }
++ allarrays[cnt] = NULL;
+
+ // 2- Iterate on all arrays.
+- for (i = 0; allarrays[i] != -1; ++i)
+- {
+- // a- Collect all dependences to this array.
+- CandlDependence* ardeps[nb_deps + 1];
+- for (tmp = deps, cnt = 0; tmp; tmp = tmp->next)
+- {
+- CandlMatrix* srcmat;
+- if (tmp->type == CANDL_RAW || tmp->type == CANDL_RAW_SCALPRIV
+- || tmp->type == CANDL_WAW)
+- srcmat = tmp->source->written;
+- else
+- srcmat = tmp->source->read;
+- if (allarrays[i] == CANDL_get_si(srcmat->p[tmp->ref_source][0]))
+- ardeps[cnt++] = tmp;
+- }
+- ardeps[cnt] = NULL;
+-
+- // b- First pruning. Remove all dependence polyhedra that are equal.
+- for (j = 0; ardeps[j]; ++j)
+- {
+- for (k = j + 1; ardeps[k]; ++k)
+- if (ardeps[j]->source == ardeps[k]->source &&
+- ardeps[j]->target == ardeps[k]->target &&
+- ardeps[j]->depth == ardeps[k]->depth &&
+- candl_matrix_equal (ardeps[j]->domain, ardeps[k]->domain))
+- {
+- ardeps[k - 1]->next = ardeps[k+1];
+- for (l = k; ardeps[l + 1]; ++l)
+- ardeps[l] = ardeps[l + 1];
+- ardeps[l] = NULL;
+- --k;
+- }
+- }
+-
+- // c- Local pruning. Remove all self-dependences (1-cycles)
+- // and all backward-dependences.
+- for (j = 0; ardeps[j]; ++j)
+- if (ardeps[j]->source >= ardeps[j]->target)
+- {
+- for (k = j; ardeps[k + 1]; ++k)
+- ardeps[k] = ardeps[k + 1];
+- ardeps[k] = NULL;
+- --j;
+- }
+-
+- // d- Local pruning. Remove all dependences where source/target
+- // are not unimodular in the iterator part of the access function and
+- // iteration domain.
+- for (j = 0; ardeps[j]; ++j)
+- if (! is_iter_unimodular (ardeps[j]))
+- {
+- for (k = j; ardeps[k + 1]; ++k)
+- ardeps[k] = ardeps[k + 1];
+- ardeps[k] = NULL;
+- --j;
+- }
+-
+- // d- Given a pair of statements, check if there is a dependence
+- // path from its source to its target, of same type of a found
+- // direct dependence.
+- int stmts, stmtt;
+- for (stmts = 0; stmts < nb_stmts - 2; ++stmts)
+- for (stmtt = stmts + 2; stmtt < nb_stmts; ++stmtt)
+- {
+- // Ensure there exists a direct dependence between stmts
+- // and stmtt.
+- //printf ("consider S%d -> S%d\n", stmts, stmtt);
+- for (j = 0; ardeps[j]; ++j)
+- if (ardeps[j]->source->label == stmts &&
+- ardeps[j]->target->label == stmtt)
+- break;
+- if (ardeps[j])
+- {
+- CandlStatement* source = ardeps[j]->source;
+- CandlStatement* target = ardeps[j]->target;
+-
+- // Subset of deps that can be on the path.
+- CandlDependence* curardeps[nb_deps + 1];
+- for (k = 0, l = 0; ardeps[k]; ++k)
+- if (ardeps[k]->source->label >= source->label &&
+- ardeps[k]->source->label <= target->label &&
+- ardeps[k]->target->label >= source->label &&
+- ardeps[k]->target->label <= target->label)
+- curardeps[l++] = ardeps[k];
+- curardeps[l] = NULL;
+- CandlDependence*** paths =
+- find_dep_paths(curardeps, source, target);
+-
+- if (paths)
+- {
+- for (j = 0; ardeps[j]; ++j)
+- if (ardeps[j]->source->label == stmts &&
+- ardeps[j]->target->label == stmtt)
+- {
+- // Inspect all paths. If there is a path
+- // that respect the transitive cover prop,
+- // then discard the dependence.
+- for (k = 0; paths[k] &&
+- ! is_covering (ardeps[j], paths[k]); ++k)
+- ;
+- if (paths[k])
+- {
+- candl_matrix_free (ardeps[j]->domain);
+- free (ardeps[j]);
+- if (j == 0)
+- deps = ardeps[j + 1];
+- else
+- ardeps[j - 1]->next = ardeps[j + 1];
+- }
+- }
+- for (k = 0; paths[k]; ++k)
+- free (paths[k]);
+- free (paths);
+- }
+- }
+- }
++ for (i = 0 ; allarrays[i] != NULL ; ++i) {
++ ardeps = (osl_dependence_p*) malloc(sizeof(osl_dependence_p) *
++ (nb_deps + 1));
++
++ // a- Collect all dependences to this array.
++ for (tmp = deps, cnt = 0; tmp; tmp = tmp->next) {
++ srcmat = candl_dependence_get_relation_ref_source_in_dep(tmp);
++ if (allarrays[i] == srcmat)
++ ardeps[cnt++] = tmp;
++ }
++ ardeps[cnt] = NULL;
++
++ // b- First pruning. Remove all dependence polyhedra that are equal.
++ for (j = 0; ardeps[j]; ++j)
++ for (k = j + 1; ardeps[k]; ++k)
++ if (ardeps[j]->source == ardeps[k]->source &&
++ ardeps[j]->target == ardeps[k]->target &&
++ ardeps[j]->depth == ardeps[k]->depth &&
++ osl_relation_equal(ardeps[j]->domain, ardeps[k]->domain)) {
++ ardeps[k - 1]->next = ardeps[k+1];
++ for (l = k; ardeps[l + 1]; ++l)
++ ardeps[l] = ardeps[l + 1];
++ ardeps[l] = NULL;
++ --k;
++ }
++
++ // c- Local pruning. Remove all self-dependences (1-cycles)
++ // and all backward-dependences.
++ for (j = 0; ardeps[j]; ++j) {
++ s_usr = ardeps[j]->source->usr;
++ t_usr = ardeps[j]->target->usr;
++ if (s_usr->label >= t_usr->label) {
++ for (k = j; ardeps[k + 1]; ++k)
++ ardeps[k] = ardeps[k + 1];
++ ardeps[k] = NULL;
++ --j;
++ }
+ }
+
++ // d- Local pruning. Remove all dependences where source/target
++ // are not unimodular in the iterator part of the access function and
++ // iteration domain.
++ for (j = 0; ardeps[j]; ++j)
++ if (! is_iter_unimodular(ardeps[j])) {
++ for (k = j; ardeps[k + 1]; ++k)
++ ardeps[k] = ardeps[k + 1];
++ ardeps[k] = NULL;
++ --j;
++ }
++
++ // d- Given a pair of statements, check if there is a dependence
++ // path from its source to its target, of same type of a found
++ // direct dependence.
++ int source_label, target_label;
++ for (source_label = 0; source_label < nb_stmts - 2; ++source_label)
++ for (target_label = source_label + 2; target_label < nb_stmts;
++ ++target_label) {
++ // Ensure there exists a direct dependence between source_label
++ // and target_label.
++ //printf ("consider S%d -> S%d\n", source_label, target_label);
++ for (j = 0; ardeps[j]; ++j) {
++ s_usr = ardeps[j]->source->usr;
++ t_usr = ardeps[j]->target->usr;
++ if (s_usr->label == source_label &&
++ t_usr->label == target_label)
++ break;
++ }
++ if (ardeps[j]) {
++ osl_statement_p source = ardeps[j]->source;
++ osl_statement_p target = ardeps[j]->target;
++
++ // Subset of deps that can be on the path.
++ curardeps = (osl_dependence_p*) malloc(sizeof(osl_dependence_p) *
++ (nb_deps + 1));
++
++ for (k = 0, l = 0; ardeps[k]; ++k) {
++ s_usr = ardeps[k]->source->usr;
++ t_usr = ardeps[k]->target->usr;
++ if (s_usr->label >= source->label &&
++ s_usr->label <= target->label &&
++ t_usr->label >= source->label &&
++ t_usr->label <= target->label)
++ curardeps[l++] = ardeps[k];
++ }
++ curardeps[l] = NULL;
++ paths = find_dep_paths(curardeps, source, target);
++
++ if (paths) {
++ for (j = 0; ardeps[j]; ++j) {
++ s_usr = ardeps[j]->source->usr;
++ t_usr = ardeps[j]->target->usr;
++ if (s_usr->label == source_label &&
++ t_usr->label == target_label) {
++ // Inspect all paths. If there is a path
++ // that respect the transitive cover prop,
++ // then discard the dependence.
++ for (k = 0; paths[k] && !is_covering(ardeps[j], paths[k]); ++k)
++ ;
++ if (paths[k]) {
++ osl_relation_free(ardeps[j]->domain);
++ free(ardeps[j]);
++ if (j == 0)
++ deps = ardeps[j + 1];
++ else
++ ardeps[j - 1]->next = ardeps[j + 1];
++ }
++ }
++ }
++ for (k = 0; paths[k]; ++k)
++ free(paths[k]);
++ free(paths);
++ }
++
++ free(curardeps);
++ }
++ }
++
++ free(ardeps);
++ }
++
++ free(allarrays);
++
+ return deps;
+ }
++
++#endif
+diff --git a/source/scop.c b/source/scop.c
+new file mode 100644
+index 0000000..f6ec0ae
+--- /dev/null
++++ b/source/scop.c
+@@ -0,0 +1,93 @@
++
++
++ /**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( scop.c **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: june 7th 2012 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
++ ******** | | *************************************************************
++ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
++ ******************************************************************************
++ * *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
++ * *
++ * This is free software; you can redistribute it and/or modify it under the *
++ * terms of the GNU General Public License as published by the Free Software *
++ * Foundation; either version 2 of the License, or (at your option) any later *
++ * version. *
++ * *
++ * This software is distributed in the hope that it will be useful, but *
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
++ * for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License along *
++ * with software; if not, write to the Free Software Foundation, Inc., *
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++ * *
++ * CAnDL, the Chunky Dependence Analyzer *
++ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++ * *
++ ******************************************************************************/
++
++/*
++ * author Joel Poudroux
++ */
++
++#include <stdlib.h>
++#include <osl/scop.h>
++#include <osl/statement.h>
++#include <candl/scop.h>
++#include <candl/statement.h>
++
++/**
++ * candl_scop_usr_init function:
++ * initialize a candl_scop_usr structure
++ *
++ * May, 2013 extended to each scop in the list,
++ */
++void candl_scop_usr_init(osl_scop_p scop) {
++
++ while (scop) {
++ candl_scop_usr_p scop_usr;
++
++ /* Init the scop_usr structure */
++ scop_usr = (candl_scop_usr_p) malloc(sizeof(candl_scop_usr_t));
++ scop_usr->scalars_privatizable = NULL;
++ scop_usr->usr_backup = scop->usr;
++ scop->usr = scop_usr;
++
++ candl_statement_usr_init_all(scop);
++
++ scop = scop->next;
++ }
++}
++
++
++/**
++ * candl_scop_usr_cleanup function:
++ */
++void candl_scop_usr_cleanup(osl_scop_p scop) {
++
++ while (scop) {
++ osl_statement_p statement = scop->statement;
++ candl_scop_usr_p scop_usr;
++ while (statement != NULL) {
++ candl_statement_usr_cleanup(statement);
++ statement = statement->next;
++ }
++ scop_usr = scop->usr;
++ if (scop_usr) {
++ if (scop_usr->scalars_privatizable)
++ free(scop_usr->scalars_privatizable);
++ scop->usr = scop_usr->usr_backup;
++ free(scop_usr);
++ }
++
++ scop = scop->next;
++ }
++}
+diff --git a/source/statement.c b/source/statement.c
+index 39ee0b8..d6845dd 100644
+--- a/source/statement.c
++++ b/source/statement.c
+@@ -1,18 +1,19 @@
+
++
+ /**------ ( ----------------------------------------------------------**
+ ** )\ CAnDL **
+ **----- / ) --------------------------------------------------------**
+- ** ( * ( statement.c **
++ ** ( * ( usr.c **
+ **---- \#/ --------------------------------------------------------**
+- ** .-"#'-. First version: september 9th 2003 **
++ ** .-"#'-. First version: june 7th 2012 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+ * *
+- * Copyright (C) 2003 Cedric Bastoul *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
+ * *
+ * This is free software; you can redistribute it and/or modify it under the *
+ * terms of the GNU General Public License as published by the Free Software *
+@@ -32,319 +33,103 @@
+ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
+ * *
+ ******************************************************************************/
+-/* CAUTION: the english used for comments is probably the worst you ever read,
+- * please feel free to correct and improve it !
+- */
+-
+-# include <stdlib.h>
+-# include <stdio.h>
+-# include <ctype.h>
+-# include <string.h>
+-# include "../include/candl/candl.h"
+
+-
+-/******************************************************************************
+- * Structure display function *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_statement_print_structure function:
+- * Displays a CandlStatement structure (statement) into a file (file,
+- * possibly stdout) in a way that trends to be understandable without falling
+- * in a deep depression or, for the lucky ones, getting a headache... It
+- * includes an indentation level (level) in order to work with others
+- * print_structure functions.
+- * - 18/09/2003: first version.
++/*
++ * author Joel Poudroux and Cedric Bastoul
+ */
+-void candl_statement_print_structure(file, statement, level)
+-FILE * file ;
+-CandlStatement * statement ;
+-int level ;
+-{ int i, j ;
+-
+- if (statement != NULL)
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- CandlStatement\n") ;
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-
+- /* Go to the right level and print the label. */
+- for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"Label: %d\n",statement->label) ;
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-
+- /* Go to the right level and print the type. */
+- for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"Type: ") ;
+- switch (statement->type)
+- { case CANDL_UNSET : fprintf(file,"UNSET\n") ; break ;
+- case CANDL_ASSIGNMENT : fprintf(file,"assignment\n") ; break ;
+- case CANDL_P_REDUCTION : fprintf(file,"plus-reduction\n") ; break ;
+- case CANDL_M_REDUCTION : fprintf(file,"minus-reduction\n") ; break ;
+- case CANDL_T_REDUCTION : fprintf(file,"times-reduction\n") ; break ;
+- default : fprintf(file,"unknown\n") ;
+- }
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-
+- /* Go to the right level and print the outer loops. */
+- for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"Depth: %d, outer loops(s):",statement->depth) ;
+- for (i=0;i<statement->depth;i++)
+- fprintf(file," %d",statement->index[i]) ;
+- fprintf(file,"\n") ;
+-
+- /* A blank line. */
+- for(j=0; j<=level+1; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-
+- /* Print the iteration domain. */
+- candl_matrix_print_structure(file,statement->domain,level+1) ;
+-
+- /* Print the written data. */
+- candl_matrix_print_structure(file,statement->written,level+1) ;
+-
+- /* Print the read data. */
+- candl_matrix_print_structure(file,statement->read,level+1) ;
+- }
+- else
+- { /* Go to the right level. */
+- for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- NULL statement\n") ;
+- }
+-
+- /* The last line. */
+- for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
+-}
+-
+-
+-/**
+- * candl_statement_print function:
+- * This function prints the content of a CandlStatement structure (statement)
+- * into a file (file, possibly stdout).
+- * - 09/09/2003: first version.
+- */
+-void candl_statement_print(FILE * file, CandlStatement * statement)
+-{ candl_statement_print_structure(file,statement,0) ;
+-}
+-
+-
+-/******************************************************************************
+- * Memory deallocation function *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_statement_free function:
+- * This function frees the allocated memory for a CandlStatement structure.
+- * - 09/09/2003: first version.
+- */
+-void candl_statement_free(CandlStatement * statement)
+-{ free(statement->index) ;
+- pip_matrix_free(statement->domain) ;
+- pip_matrix_free(statement->read) ;
+- pip_matrix_free(statement->written) ;
+- free(statement) ;
+-}
+
++#include <stdlib.h>
++#include <osl/scop.h>
++#include <osl/statement.h>
++#include <osl/extensions/dependence.h>
++#include <osl/relation.h>
++#include <candl/macros.h>
++#include <candl/statement.h>
++#include <candl/util.h>
+
+-/******************************************************************************
+- * Reading functions *
+- ******************************************************************************/
++#define CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH 128
+
+
+ /**
+- * candl_statement_read function:
+- * This function reads statement data from a file (file) and puts them into
+- * a CandlStatement structure. This function returns a pointer to this
+- * structure.
+- * - label is the statement number ;
+- * - nb_parameters is the number of parameters.
+- ***
+- * - 09/09/2003: first version.
++ * candl_statement_usr_init_all function:
++ * Init each candl_statement_usr structure of statements
+ */
+-CandlStatement * candl_statement_read(FILE * file, int label, int nb_parameters)
+-{ int i, n, * index ;
+- char s[CANDL_MAX_STRING], str[CANDL_MAX_STRING], * c, type ;
+- CandlStatement * statement ;
+-
+- /* Statement data. */
+- statement = candl_statement_malloc() ;
+-
+- /* We first read the statement type. */
+- while (fgets(s,CANDL_MAX_STRING,file) == 0) ;
+- while ((*s=='#' || *s=='\n') || (sscanf(s," %c",&type)<1))
+- fgets(s,CANDL_MAX_STRING,file) ;
++void candl_statement_usr_init_all(osl_scop_p scop) {
++
++ /* TODO
++ * that statements must be sorted to compute the statement label
++ * the problem is if the scop is reordered, the second transformed scop
++ * must be aligned with it
++ */
++
++ osl_statement_p iter;
++ osl_relation_p scattering;
++ candl_statement_usr_p stmt_usr;
++ int i, j, k;
++ int row;
++ int precision = scop->context->precision;
++ int count = 0; /* counter for statements */
+
+- switch (type)
+- { case 'A': statement->type = CANDL_ASSIGNMENT ; break ;
+- case 'P': statement->type = CANDL_P_REDUCTION ; break ;
+- case 'M': statement->type = CANDL_M_REDUCTION ; break ;
+- case 'T': statement->type = CANDL_T_REDUCTION ; break ;
+- default : fprintf(stderr, "[Candl]ERROR: unknown statement type %c\n",type);
+- fprintf(stderr, " possible types are:\n") ;
+- fprintf(stderr, " - A for assignment (=),\n") ;
+- fprintf(stderr, " - P for plus-reduction (+=),\n") ;
+- fprintf(stderr, " - M for minus-reduction (-=),\n") ;
+- fprintf(stderr, " - T for times-reduction (*=).\n") ;
+- exit(1) ;
++ /* Initialize structures used in iterator indices computation. */
++ int val;
++ int max = 0;
++ int cur_index[CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH];
++ int last[CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH];
++ for (i = 0; i < CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH; ++i) {
++ cur_index[i] = i;
++ last[i] = 0;
+ }
+-
+- statement->label = label ;
+- statement->domain = pip_matrix_read(file) ;
+- statement->depth = statement->domain->NbColumns - nb_parameters - 2 ;
+-
+- index = (int *)malloc(sizeof(int)*statement->depth) ;
+- if (index == NULL)
+- { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
+- exit(1) ;
+- }
+-
+- do /* Skip the comments, spaces and empty lines... */
+- { c = fgets(s,CANDL_MAX_STRING,file) ;
+- while ((c != NULL) && isspace(*c) && (*c != '\n'))
+- c++ ;
+- }
+- while (c != NULL && (*c == '#' || *c == '\n'));
++
++ /* Add useful information in the usr field of each statements */
++ for (iter = scop->statement ; iter != NULL ; iter = iter->next) {
++ scattering = iter->scattering;
+
+- if (c == NULL)
+- { fprintf(stderr, "[Candl]ERROR: no labels in input file.\n") ;
+- exit(1) ;
+- }
+- for (i=0;i<statement->depth;i++)
+- { /* All iterator labels must be on the same line. */
+- while (isspace(*c))
+- c++ ;
+- if (c == NULL || *c == '#' || *c == '\n')
+- { fprintf(stderr, "[Candl]ERROR: not enough labels in input file.\n") ;
+- exit(1) ;
+- }
+- /* n is strlen(str). */
+- if (sscanf(c,"%s%n",str,&n) == 0)
+- { fprintf(stderr, "[Candl]ERROR: no labels in input file.\n") ;
+- exit(1) ;
++ stmt_usr = (candl_statement_usr_p) malloc(sizeof(candl_statement_usr_t));
++ stmt_usr->depth = scattering->nb_output_dims/2;
++ stmt_usr->label = count;
++ stmt_usr->type = OSL_DEPENDENCE_ASSIGNMENT;
++ stmt_usr->usr_backup = iter->usr;
++ stmt_usr->index = (stmt_usr->depth ?
++ (int*) malloc(stmt_usr->depth * sizeof(int)) :
++ NULL);
++
++ /* Compute the value of the iterator indices.
++ * extracted from the last candl
++ */
++ for (j = 0; j < stmt_usr->depth; ++j) {
++ row = candl_util_relation_get_line(scattering, j*2);
++ val = osl_int_get_si(precision,
++ scattering->m[row][scattering->nb_columns - 1]);
++ if (last[j] < val) {
++ last[j] = val;
++ for (k = j + 1; k < CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH; ++k)
++ last[k] = 0;
++ for (k = j; k < CANDL_STATEMENT_USR_INDEX_MAX_LOOP_DEPTH; ++k)
++ cur_index[k] = max + (k - j) + 1;
++ break;
++ }
+ }
+- sscanf(str,"%d",&index[i]) ;
+- c += n ;
+- }
+- statement->index = index ;
+-
+- statement->written = pip_matrix_read(file) ;
+- statement->read = pip_matrix_read(file) ;
++ for (j = 0; j < stmt_usr->depth; ++j)
++ stmt_usr->index[j] = cur_index[j];
+
+- return statement ;
+-}
+-
+-
+-/******************************************************************************
+- * Processing functions *
+- ******************************************************************************/
+-
+-
+-/**
+- * candl_statement_malloc function:
+- * This function allocates the memory space for a CandlStatement structure and
+- * sets its fields with default values. Then it returns a pointer to the
+- * allocated space.
+- * - 09/12/2005: first version.
+- */
+-CandlStatement * candl_statement_malloc()
+-{ CandlStatement * statement ;
+-
+- /* Memory allocation for the CloogProgram structure. */
+- statement = (CandlStatement *)malloc(sizeof(CandlStatement)) ;
+- if (statement == NULL)
+- { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
+- exit(1) ;
++ max = max < cur_index[j - 1] ? cur_index[j - 1] : max;
++
++ iter->usr = stmt_usr;
++ count++;
+ }
+-
+- /* We set the various fields with default values. */
+- statement->label = CANDL_UNSET ;
+- statement->type = CANDL_UNSET ;
+- statement->depth = CANDL_UNSET ;
+- statement->index = NULL ;
+- statement->domain = NULL ;
+- statement->written = NULL ;
+- statement->read = NULL ;
+- statement->ref = NULL ;
+-
+- return statement ;
+ }
+
+
+ /**
+- * candl_statement_commute function:
+- * This function returns 1 if the two statements given as parameter commute,
+- * 0 otherwise. It uses the statement type information to answer the question.
+- * - 09/12/2005: first version.
++ * candl_usr_free function:
+ */
+-int candl_statement_commute(statement1, statement2)
+-CandlStatement * statement1, * statement2 ;
+-{ int type1, type2, nb_rows, i ;
+-
+- type1 = statement1->type ;
+- type2 = statement2->type ;
+-
+- /* In the case of self-dependence, a statement commutes with hitself if
+- * it is a reduction.
+- */
+- if ((statement1 == statement2) &&
+- ((type1 == CANDL_P_REDUCTION) ||
+- (type1 == CANDL_M_REDUCTION) ||
+- (type1 == CANDL_T_REDUCTION)))
+- return 1 ;
+-
+- /* Two statement commute when they are a reduction of the same type (or if
+- * their left and right members are the same, but it's not exploited here).
+- * The type may differ if it is either minus or plus-reduction. Furthermore,
+- * they have to write onto the same array (and only one array).
+- */
+- if (((type1 == CANDL_P_REDUCTION) && (type2 == CANDL_P_REDUCTION)) ||
+- ((type1 == CANDL_M_REDUCTION) && (type2 == CANDL_M_REDUCTION)) ||
+- ((type1 == CANDL_T_REDUCTION) && (type2 == CANDL_T_REDUCTION)) ||
+- ((type1 == CANDL_P_REDUCTION) && (type2 == CANDL_M_REDUCTION)) ||
+- ((type1 == CANDL_M_REDUCTION) && (type2 == CANDL_P_REDUCTION)))
+- { /* Here we check that there is one, only one and the same array. */
+- nb_rows = statement1->written->NbRows ;
+- if ((nb_rows == 0) || (nb_rows != statement2->written->NbRows))
+- return 0 ;
+-
+- if (statement1->written->p[0][0] != statement2->written->p[0][0])
+- return 0 ;
+-
+- for (i=1;i<nb_rows;i++)
+- if ((statement1->written->p[i][0] != 0) ||
+- (statement2->written->p[i][0] != 0))
+- return 0 ;
+-
+- return 1 ;
+- }
+-
+- return 0 ;
++void candl_statement_usr_cleanup(osl_statement_p statement) {
++ candl_statement_usr_p stmt_usr;
++ stmt_usr = statement->usr;
++ if (stmt_usr) {
++ if (stmt_usr->index)
++ free(stmt_usr->index);
++ statement->usr = stmt_usr->usr_backup;
++ free(stmt_usr);
++ }
+ }
+-
+-
+-
+-
+-
+-
+diff --git a/source/util.c b/source/util.c
+new file mode 100644
+index 0000000..df83aad
+--- /dev/null
++++ b/source/util.c
+@@ -0,0 +1,207 @@
++
++ /**------ ( ----------------------------------------------------------**
++ ** )\ CAnDL **
++ **----- / ) --------------------------------------------------------**
++ ** ( * ( util.c **
++ **---- \#/ --------------------------------------------------------**
++ ** .-"#'-. First version: june 7th 2012 **
++ **--- |"-.-"| -------------------------------------------------------**
++ | |
++ | |
++ ******** | | *************************************************************
++ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
++ ******************************************************************************
++ * *
++ * Copyright (C) 2003-2008 Cedric Bastoul *
++ * *
++ * This is free software; you can redistribute it and/or modify it under the *
++ * terms of the GNU General Public License as published by the Free Software *
++ * Foundation; either version 2 of the License, or (at your option) any later *
++ * version. *
++ * *
++ * This software is distributed in the hope that it will be useful, but *
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
++ * for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License along *
++ * with software; if not, write to the Free Software Foundation, Inc., *
++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
++ * *
++ * CAnDL, the Chunky Dependence Analyzer *
++ * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
++ * *
++ ******************************************************************************/
++
++/*
++ * author Joel Poudroux and Cedric Bastoul
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <osl/statement.h>
++#include <osl/relation.h>
++#include <osl/macros.h>
++#include <osl/extensions/dependence.h>
++#include <osl/relation_list.h>
++#include <osl/scop.h>
++#include <candl/macros.h>
++#include <candl/util.h>
++#include <candl/statement.h>
++
++
++/**
++ * candl_util_relation_get_line function:
++ * Because the lines in the scattering matrix may have not ordered, we have to
++ * search the corresponding line. It returns the first line where the value is
++ * different from zero in the `column'. `column' is between 0 and
++ * nb_output_dims-1
++ * \param[in] relation
++ * \param[in] column Line to search
++ * \return Return the real line
++ */
++int candl_util_relation_get_line(osl_relation_p relation, int column) {
++ if (column < 0 || column > relation->nb_output_dims)
++ return -1;
++ int i;
++ int precision = relation->precision;
++ for (i = 0 ; i < relation->nb_rows ; i++) {
++ if (!osl_int_zero(precision, relation->m[i][column + 1])) {
++ break;
++ }
++ }
++ return (i == relation->nb_rows ? -1 : i );
++}
++
++
++
++/* Check if two scop can be compared (same number of statements and
++ * same access array/domain in the same order)
++ *
++ * \param[in] s1 first scop to compare
++ * \param[in] s2 second scop to compare
++ * \return 1 if two scops equal, 0 otherwise
++ */
++int candl_util_check_scop(osl_scop_p s1, osl_scop_p s2) {
++
++ osl_statement_p it1 = s1->statement, it2 = s2->statement;
++ for (; it1 != NULL && it2 != NULL ; it1 = it1->next, it2 = it2->next) {
++ if (!osl_relation_list_equal(it1->access, it2->access))
++ return 0;
++ if (!osl_relation_equal(it1->domain, it2->domain))
++ return 0;
++ }
++
++ /* Different number of statements */
++ if ((it1 == NULL || it2 == NULL) && it1 != it2)
++ return 0;
++
++ return 1;
++}
++
++/* Extends the candl_util_check_scop() functionality to a list of scops
++ * Compares each scop in s1 to the corresponding element in list s2
++ * same access array/domain in the same order)
++ *
++ * \param[in] s1 first scop List to compare
++ * \param[in] s2 second scop List to compare
++ * \return 1 if two scops lists equal, 0 otherwise
++ */
++int candl_util_check_scop_list(osl_scop_p s1, osl_scop_p s2) {
++
++ while ((s1!=NULL) && (s2!=NULL)) {
++ if(!candl_util_check_scop(s1, s2))
++ return 0;
++
++ s1 = s1->next;
++ s2 = s2->next;
++ }
++
++ /* Different number of scops */
++ if ((s1 == NULL || s2 == NULL) && s1 != s2)
++ return 0;
++
++ /*scop lists can be compared*/
++ return 1;
++}
++
++/* Return the number access array which have the type `type'
++ */
++static int count_nb_access(osl_statement_p st, int type) {
++ osl_relation_list_p access = st->access;
++ int count = 0;
++ for (; access != NULL ; access = access->next)
++ if (access->elt->type == type)
++ count ++;
++ return count;
++}
++
++
++/**
++ * candl_util_statement_commute function:
++ * This function returns 1 if the two statements given as parameter commute,
++ * 0 otherwise. It uses the statement type information to answer the question.
++ * - 09/12/2005: first version.
++ */
++int candl_util_statement_commute(osl_statement_p statement1,
++ osl_statement_p statement2) {
++ candl_statement_usr_p usr1, usr2;
++ int type1, type2;
++ int id1, id2;
++
++ usr1 = statement1->usr;
++ usr2 = statement2->usr;
++ type1 = usr1->type;
++ type2 = usr2->type;
++
++ /* In the case of self-dependence, a statement commutes with hitself if
++ * it is a reduction.
++ */
++ if ((statement1 == statement2) &&
++ ((type1 == OSL_DEPENDENCE_P_REDUCTION) ||
++ (type1 == OSL_DEPENDENCE_M_REDUCTION) ||
++ (type1 == OSL_DEPENDENCE_T_REDUCTION)))
++ return 1;
++
++ /* Two statement commute when they are a reduction of the same type (or if
++ * their left and right members are the same, but it's not exploited here).
++ * The type may differ if it is either minus or plus-reduction. Furthermore,
++ * they have to write onto the same array (and only one array).
++ */
++ if ((type1 == OSL_DEPENDENCE_P_REDUCTION && type2 == OSL_DEPENDENCE_P_REDUCTION) ||
++ (type1 == OSL_DEPENDENCE_M_REDUCTION && type2 == OSL_DEPENDENCE_M_REDUCTION) ||
++ (type1 == OSL_DEPENDENCE_T_REDUCTION && type2 == OSL_DEPENDENCE_T_REDUCTION) ||
++ (type1 == OSL_DEPENDENCE_P_REDUCTION && type2 == OSL_DEPENDENCE_M_REDUCTION) ||
++ (type1 == OSL_DEPENDENCE_M_REDUCTION && type2 == OSL_DEPENDENCE_P_REDUCTION)) {
++ /* Here we check that there is one, only one and the same array. */
++ if (count_nb_access(statement1, OSL_TYPE_WRITE) > 1 ||
++ count_nb_access(statement2, OSL_TYPE_WRITE) > 1)
++ return 0;
++
++ /* search the first osl_write access */
++ osl_relation_list_p access1 = statement1->access;
++ osl_relation_list_p access2 = statement2->access;
++ for (; access1 != NULL && access2 != NULL ;
++ access1 = access1->next, access2 = access2->next)
++ if (access1->elt->type == OSL_TYPE_WRITE)
++ break;
++
++ if (access1 == NULL || access2 == NULL ||
++ access2->elt->type != OSL_TYPE_WRITE ||
++ access2->elt->nb_output_dims != access1->elt->nb_output_dims) {
++ osl_statement_dump(stderr, statement1);
++ osl_statement_dump(stderr, statement2);
++ CANDL_error("These statements haven't the same access array or access is NULL");
++ }
++
++ /* Check if the first dim (the Arr column) is the same */
++ id1 = osl_relation_get_array_id(access1->elt);
++ id2 = osl_relation_get_array_id(access2->elt);
++ if (id1 != id2)
++ return 0;
++
++ return 1;
++ }
++
++ return 0;
++}
+diff --git a/source/violation.c b/source/violation.c
+index 1f2d4bb..3f8e3fe 100644
+--- a/source/violation.c
++++ b/source/violation.c
+@@ -6,8 +6,8 @@
+ **---- \#/ --------------------------------------------------------**
+ ** .-"#'-. First version: december 12th 2005 **
+ **--- |"-.-"| -------------------------------------------------------**
+- | |
+- | |
++ | |
++ | |
+ ******** | | *************************************************************
+ * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
+ ******************************************************************************
+@@ -36,10 +36,20 @@
+ * please feel free to correct and improve it !
+ */
+
+-# include <stdlib.h>
+-# include <stdio.h>
+-# include <string.h>
+-# include "../include/candl/candl.h"
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <osl/macros.h>
++#include <osl/relation.h>
++#include <osl/statement.h>
++#include <osl/scop.h>
++#include <osl/extensions/dependence.h>
++#include <candl/macros.h>
++#include <candl/matrix.h>
++#include <candl/piplib.h>
++#include <candl/piplib-wrapper.h>
++#include <candl/statement.h>
++#include <candl/violation.h>
+
+
+ /******************************************************************************
+@@ -48,84 +58,79 @@
+
+
+ /**
+- * candl_violation_print_structure function:
++ * candl_violation_idump function:
+ * Displays a CandlViolation structure (violation) into a file (file,
+ * possibly stdout) in a way that trends to be understandable without falling
+ * in a deep depression or, for the lucky ones, getting a headache... It
+ * includes an indentation level (level) in order to work with others
+- * print_structure functions.
++ * idump functions.
+ * - 18/09/2003: first version.
+ */
+-void candl_violation_print_structure(file, violation, level)
+-FILE * file ;
+-CandlViolation * violation ;
+-int level ;
+-{ int j, first=1 ;
+- CandlDependence * next=NULL ;
+-
+- if (violation != NULL)
+- { /* Go to the right level. */
++void candl_violation_idump(FILE *file, candl_violation_p violation,
++ int level) {
++ int j, first=1;
++ osl_dependence_p next=NULL;
++
++ if (violation != NULL) { /* Go to the right level. */
+ for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- CandlViolation\n") ;
+- }
+- else
+- { for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"+-- NULL dependence violation\n") ;
++ fprintf(file,"|\t");
++ fprintf(file,"+-- CandlViolation\n");
++ } else {
++ for(j=0; j<level; j++)
++ fprintf(file,"|\t");
++ fprintf(file,"+-- NULL dependence violation\n");
+ }
+
+- while (violation != NULL)
+- { if (!first)
+- { /* Go to the right level. */
++ while (violation != NULL) {
++ if (!first) { /* Go to the right level. */
+ for(j=0; j<level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"| CandlViolation\n") ;
++ fprintf(file,"|\t");
++ fprintf(file,"| CandlViolation\n");
++ } else {
++ first = 0;
+ }
+- else
+- first = 0 ;
+
+ /* A blank line. */
+ for(j=0; j<=level+1; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
++ fprintf(file,"|\t");
++ fprintf(file,"\n");
+
+ /* Go to the right level and print the dimension. */
+ for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"Dimension: %d\n",violation->dimension) ;
++ fprintf(file,"|\t");
++ fprintf(file,"Dimension: %d\n",violation->dimension);
+
+ /* A blank line. */
+ for(j=0; j<=level+1; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
++ fprintf(file,"|\t");
++ fprintf(file,"\n");
+
+ /* Print the dependence. */
+- if (violation->dependence != NULL)
+- { next = violation->dependence->next ; /* To not print the whole list... */
+- violation->dependence->next = NULL ; /* I know it's not beautiful :-/ ! */
++ if (violation->dependence != NULL) {
++ next = violation->dependence->next; /* To not print the whole list... */
++ violation->dependence->next = NULL; /* I know it's not beautiful :-/ ! */
+ }
+- candl_dependence_print_structure(file,violation->dependence,level+1) ;
++ osl_dependence_idump(file,violation->dependence,level+1);
+ if (violation->dependence != NULL)
+- violation->dependence->next = next ;
++ violation->dependence->next = next;
+
+ /* Print the dependence polyhedron. */
+- candl_matrix_print_structure(file,violation->domain,level+1) ;
++ osl_relation_idump(file, violation->domain, level+1);
+
+- violation = violation->next ;
++ violation = violation->next;
+
+ /* Next line. */
+- if (violation != NULL)
+- { for (j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"V\n") ;
++ if (violation != NULL) {
++ for (j=0; j<=level; j++)
++ fprintf(file,"|\t");
++ fprintf(file,"V\n");
+ }
+ }
+
+ /* The last line. */
+ for(j=0; j<=level; j++)
+- fprintf(file,"|\t") ;
+- fprintf(file,"\n") ;
++ fprintf(file,"|\t");
++ fprintf(file,"\n");
+ }
+
+
+@@ -133,8 +138,8 @@ int level ;
+ * This function prints the content of a CandlViolation structure
+ * (violation) into a file (file, possibly stdout).
+ */
+-void candl_violation_print(FILE * file, CandlViolation * violation)
+-{ candl_violation_print_structure(file,violation,0) ;
++void candl_violation_dump(FILE * file, candl_violation_p violation) {
++ candl_violation_idump(file,violation,0);
+ }
+
+
+@@ -144,43 +149,47 @@ void candl_violation_print(FILE * file, CandlViolation * violation)
+ * See http://www.graphviz.org
+ * - 12/12/2005: first version.
+ */
+-void candl_violation_pprint(FILE * file, CandlViolation * violation)
+-{ int i=0 ;
+- CandlDependence * dependence ;
++void candl_violation_pprint(FILE * file, candl_violation_p violation) {
++ int i=0;
++ osl_dependence_p dependence;
++ candl_statement_usr_p s_usr;
++ candl_statement_usr_p t_usr;
+
+- fprintf(file,"digraph G {\n") ;
++ fprintf(file,"digraph G {\n");
+
+- fprintf(file,"# Legality Violation Graph\n") ;
++ fprintf(file,"# Legality Violation Graph\n");
+ fprintf(file,"# Generated by Candl "CANDL_RELEASE" "CANDL_VERSION" bits\n");
+ if (violation == NULL)
+- fprintf(file,"# Congratulations: the transformation is legal !\n");
+-
+- while (violation != NULL)
+- { dependence = violation->dependence ;
+-
+- fprintf(file," S%d -> S%d [label=\" ",dependence->source->label,
+- dependence->target->label) ;
+- switch (dependence->type)
+- { case CANDL_UNSET : fprintf(file,"UNSET") ; break ;
+- case CANDL_RAW : fprintf(file,"RAW") ; break ;
+- case CANDL_WAR : fprintf(file,"WAR") ; break ;
+- case CANDL_WAW : fprintf(file,"WAW") ; break ;
+- case CANDL_RAR : fprintf(file,"RAR") ; break ;
+- default : fprintf(file,"unknown") ;
++ fprintf(file,"# Congratulations: the transformation is legal !\n");
++
++ while (violation != NULL) {
++ dependence = violation->dependence;
++ s_usr = dependence->stmt_source_ptr->usr;
++ t_usr = dependence->stmt_target_ptr->usr;
++
++ fprintf(file," S%d -> S%d [label=\" ", s_usr->label,
++ t_usr->label);
++ switch (dependence->type) {
++ case OSL_UNDEFINED : fprintf(file,"UNSET"); break;
++ case OSL_DEPENDENCE_RAW : fprintf(file,"RAW") ; break;
++ case OSL_DEPENDENCE_WAR : fprintf(file,"WAR") ; break;
++ case OSL_DEPENDENCE_WAW : fprintf(file,"WAW") ; break;
++ case OSL_DEPENDENCE_RAR : fprintf(file,"RAR") ; break;
++ default : fprintf(file,"unknown");
+ }
+ fprintf(file," depth %d, ref %d->%d, viol %d \"];\n",
+ dependence->depth,
+ dependence->ref_source,
+ dependence->ref_target,
+- violation->dimension) ;
+- violation = violation->next ;
+- i++ ;
++ violation->dimension);
++ violation = violation->next;
++ i++;
+ }
+
+ if (i>4)
+- fprintf(file,"# Number of edges = %i\n}\n",i) ;
++ fprintf(file,"# Number of edges = %i\n}\n",i);
+ else
+- fprintf(file,"}\n") ;
++ fprintf(file,"}\n");
+ }
+
+
+@@ -190,13 +199,14 @@ void candl_violation_pprint(FILE * file, CandlViolation * violation)
+ * violation graph.
+ * - 20/03/2006: first version.
+ */
+-void candl_violation_view(CandlViolation * violation)
+-{ FILE * temp_output ;
+-
+- temp_output = fopen(CANDL_TEMP_OUTPUT,"w") ;
+- candl_violation_pprint(temp_output,violation) ;
+- fclose(temp_output) ;
+- system("(dot -Tps "CANDL_TEMP_OUTPUT" | gv - &) && rm -f "CANDL_TEMP_OUTPUT) ;
++void candl_violation_view(candl_violation_p violation) {
++ FILE * temp_output;
++ temp_output = fopen(CANDL_TEMP_OUTPUT,"w+");
++ candl_violation_pprint(temp_output,violation);
++ fclose(temp_output);
++ /* check the return to remove the warning compilation */
++ if(system("dot -Tps "CANDL_TEMP_OUTPUT" | gv - && rm -f "CANDL_TEMP_OUTPUT" &"))
++ ;
+ }
+
+
+@@ -208,14 +218,13 @@ void candl_violation_view(CandlViolation * violation)
+ * This function frees the allocated memory for a CandlViolation structure.
+ * - 18/09/2003: first version.
+ */
+-void candl_violation_free(CandlViolation * violation)
+-{ CandlViolation * next ;
+-
+- while (violation != NULL)
+- { next = violation->next ;
+- candl_matrix_free(violation->domain) ;
+- free(violation) ;
+- violation = next ;
++void candl_violation_free(candl_violation_p violation) {
++ candl_violation_p next;
++ while (violation != NULL) {
++ next = violation->next;
++ osl_relation_free(violation->domain);
++ free(violation);
++ violation = next;
+ }
+ }
+
+@@ -232,23 +241,27 @@ void candl_violation_free(CandlViolation * violation)
+ * allocated space.
+ * - 07/12/2005: first version.
+ */
+-CandlViolation * candl_violation_malloc()
+-{ CandlViolation * violation ;
++candl_violation_p candl_violation_malloc() {
++ candl_violation_p violation;
+
+ /* Memory allocation for the CandlViolation structure. */
+- violation = (CandlViolation *)malloc(sizeof(CandlViolation)) ;
+- if (violation == NULL)
+- { fprintf(stderr, "[Candl]ERROR: memory overflow.\n") ;
+- exit(1) ;
++ violation = (candl_violation_p) malloc(sizeof(candl_violation_t));
++ if (violation == NULL) {
++ fprintf(stderr, "[Candl]ERROR: memory overflow.\n");
++ exit(1);
+ }
+
+ /* We set the various fields with default values. */
+- violation->dependence = NULL ;
+- violation->domain = NULL ;
+- violation->next = NULL ;
+- violation->dimension = CANDL_UNSET ;
+-
+- return violation ;
++ violation->dependence = NULL;
++ violation->domain = NULL;
++ violation->next = NULL;
++ violation->dimension = OSL_UNDEFINED;
++ violation->source_nb_output_dims_scattering = -1;
++ violation->target_nb_output_dims_scattering = -1;
++ violation->source_nb_local_dims_scattering = -1;
++ violation->target_nb_local_dims_scattering = -1;
++
++ return violation;
+ }
+
+
+@@ -258,22 +271,23 @@ CandlViolation * candl_violation_malloc()
+ * of this list is (start). This function updates (now) to the end of the loop
+ * list (loop), and updates (start) if the added element is the first one -that
+ * is when (start) is NULL-.
+- * - 12/12/2005: first version (from candl_dependence_add).
++ * - 12/12/2005: first version (from candl_dependence_add,
++ * currently osl_dependence_add).
+ */
+-void candl_violation_add(start, now, violation)
+-CandlViolation ** start, ** now, * violation ;
+-{ if (violation != NULL)
+- { if (*start == NULL)
+- { *start = violation ;
+- *now = *start ;
+- }
+- else
+- { (*now)->next = violation ;
+- *now = (*now)->next ;
++void candl_violation_add(candl_violation_p* start,
++ candl_violation_p* now,
++ candl_violation_p violation) {
++ if (violation != NULL) {
++ if (*start == NULL) {
++ *start = violation;
++ *now = *start;
++ } else {
++ (*now)->next = violation;
++ *now = (*now)->next;
+ }
+
+ while ((*now)->next != NULL)
+- *now = (*now)->next ;
++ *now = (*now)->next;
+ }
+ }
+
+@@ -289,86 +303,97 @@ CandlViolation ** start, ** now, * violation ;
+ **
+ * - 12/12/2005: first version.
+ */
+-CandlViolation * candl_violation(program, dependence, options)
+-CandlProgram * program ;
+-CandlDependence * dependence ;
+-CandlOptions * options ;
+-{ int dimension, max_dimension, violated ;
+- CandlMatrix * system, * domain, * t_source, * t_target ;
+- CandlStatement * source, * target ;
+- CandlViolation * violation=NULL, * now=NULL, * new ;
+- PipOptions * pip_options ;
+- PipQuast * solution ;
+-
+- /* If there is no program or transformation, we consider this legal. */
+- if ((program == NULL) || (program->transformation == NULL))
+- return NULL ;
+-
+- /* If the dependence graph is not already built, do it. */
+- if (dependence == NULL)
+- dependence = candl_dependence(program,options) ;
+-
+- pip_options = pip_options_init() ;
+- pip_options->Simplify = 1 ;
++candl_violation_p candl_violation(osl_scop_p orig_scop,
++ osl_dependence_p orig_dependence,
++ osl_scop_p test_scop,
++ candl_options_p options) {
++ osl_statement_p source, target, iter;
++ osl_statement_p *stmts;
++ osl_relation_p t_source, t_target;
++ candl_statement_usr_p s_usr, t_usr;
++ candl_violation_p violation = NULL, now, new;
++ PipOptions *pip_options;
++ PipQuast *solution;
++ int i;
++ int nb_par = orig_scop->context->nb_parameters;
++ int nb_stmts = 0;
++ int dimension, max_dimension, violated;
++
++ /* If there is no scop or transformation, we consider this legal. */
++ if (test_scop == NULL)
++ return NULL;
++
++ /* Temporary array to access faster at the `label'th statement */
++ for (iter = test_scop->statement ; iter != NULL ;
++ iter = iter->next, nb_stmts++)
++ ;
++ stmts = (osl_statement_p*) malloc(sizeof(osl_statement_p) * nb_stmts);
++ for (i = 0, iter = test_scop->statement ; iter != NULL ;
++ iter = iter->next, i++) {
++ stmts[i] = iter;
++ }
+
++ pip_options = pip_options_init();
++ pip_options->Simplify = 1;
++
+ /* We check every edge of the dependence graph. */
+- while (dependence != NULL)
+- { source = dependence->source ;
+- target = dependence->target ;
+- domain = dependence->domain ;
++ while (orig_dependence != NULL) {
++ source = orig_dependence->stmt_source_ptr;
++ target = orig_dependence->stmt_target_ptr;
++ s_usr = source->usr;
++ t_usr = target->usr;
+
+ /* We find the source transformation matrix. */
+- t_source = program->transformation[source->label] ;
++ t_source = stmts[s_usr->label]->scattering;
+
+ /* We find the target transformation matrix. */
+- t_target = program->transformation[target->label] ;
+-
++ t_target = stmts[t_usr->label]->scattering;
++
+ /* The maximal dimension we have to check for legality. */
+- max_dimension = CANDL_min(t_source->NbRows,t_target->NbRows) ;
+-
++ max_dimension = CANDL_min(t_source->nb_output_dims,t_target->nb_output_dims);
++
+ /* We check each dimension for legality. */
+- for (dimension = 0; dimension<max_dimension; dimension++)
+- { violated = 0 ;
+- system = NULL ;
++ for (dimension = 1; dimension <= max_dimension; dimension++) {
++ violated = 0;
+
+ /* We build the constraint system corresponding to that
+ * violation then check if there is an integral point inside,
+ * if yes there is actually a dependence violation and we
+ * will add this one to the list.
+ */
+- system = candl_matrix_violation(dependence->domain,t_source,t_target,
+- dimension,program->context->NbColumns-2) ;
+-
+- solution = pip_solve(system,program->context,-1,pip_options) ;
++ new = candl_matrix_violation(orig_dependence, t_source,
++ t_target, dimension,
++ nb_par);
++ solution = pip_solve_osl(new->domain, orig_scop->context, -1, pip_options);
+
+ if ((solution != NULL) &&
+ ((solution->list != NULL) || (solution->condition != NULL)))
+- violated = 1 ;
+-
+- pip_quast_free(solution) ;
++ violated = 1;
+
+- if (violated)
+- { new = candl_violation_malloc() ;
++ pip_quast_free(solution);
+
+- /* We set the various fields with corresponding values. */
+- new->dependence = dependence ;
+- new->dimension = dimension ;
+- new->domain = system ;
++ if (violated) {
+
+- candl_violation_add(&violation,&now,new) ;
++ /* We set the various fields with corresponding values. */
++ new->dependence = orig_dependence;
++ new->dimension = dimension;
++ candl_violation_add(&violation,&now,new);
+
+- if (!options->fullcheck)
+- { pip_options_free(pip_options) ;
+- return violation ;
+- }
++ if (!options->fullcheck) {
++ pip_options_free(pip_options);
++ return violation;
++ }
++ } else if (new) {
++ candl_violation_free(new);
+ }
+- else
+- candl_matrix_free(system) ;
+ }
+- dependence = dependence->next ;
++ orig_dependence = orig_dependence->next;
+ }
+
+- pip_options_free(pip_options) ;
+- return violation ;
++ free(stmts);
++
++ pip_options_free(pip_options);
++
++ return violation;
+ }
+