--- /dev/null
+# Check if this is a in tree build.
+if (NOT DEFINED LLVM_MAIN_SRC_DIR)
+ project(Polly)
+ cmake_minimum_required(VERSION 2.8)
+
+ # Where is LLVM installed?
+ set(LLVM_INSTALL_ROOT "" CACHE PATH "Root of LLVM install.")
+ # Check if the LLVM_INSTALL_ROOT valid.
+ if( NOT EXISTS ${LLVM_INSTALL_ROOT}/include/llvm )
+ message(FATAL_ERROR "LLVM_INSTALL_ROOT (${LLVM_INSTALL_ROOT}) is not a valid LLVM installation.")
+ endif(NOT EXISTS ${LLVM_INSTALL_ROOT}/include/llvm)
+ # Add the llvm header path.
+ include_directories(${LLVM_INSTALL_ROOT}/include/)
+
+ # Get the system librarys that will link into LLVM.
+ function(get_system_libs return_var)
+ # Returns in `return_var' a list of system libraries used by LLVM.
+ if( NOT MSVC )
+ if( MINGW )
+ set(system_libs ${system_libs} imagehlp psapi)
+ elseif( CMAKE_HOST_UNIX )
+ if( HAVE_LIBDL )
+ set(system_libs ${system_libs} ${CMAKE_DL_LIBS})
+ endif()
+ if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
+ set(system_libs ${system_libs} pthread)
+ endif()
+ endif( MINGW )
+ endif( NOT MSVC )
+ set(${return_var} ${system_libs} PARENT_SCOPE)
+ endfunction(get_system_libs)
+
+ # Now set the header paths.
+ execute_process(COMMAND "${LLVM_INSTALL_ROOT}/bin/llvm-config" --includedir
+ OUTPUT_VARIABLE LLVM_INCLUDE_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ include_directories( ${LLVM_INCLUDE_DIR} )
+
+ # And then set the cxx flags.
+ execute_process(COMMAND "${LLVM_INSTALL_ROOT}/bin/llvm-config" --cxxflags
+ OUTPUT_VARIABLE LLVM_CXX_FLAGS
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${LLVM_CXX_FLAGS})
+endif(NOT DEFINED LLVM_MAIN_SRC_DIR)
+
+set(POLLY_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(POLLY_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+# Add appropriate flags for GCC
+if (CMAKE_COMPILER_IS_GNUCXX)
+ # FIXME: Turn off exceptions, RTTI:
+ # -fno-exceptions -fno-rtti
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -fno-exceptions -fno-rtti")
+endif ()
+
+# Add path for custom modules
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${POLLY_SOURCE_DIR}/cmake")
+
+FIND_PACKAGE(Cloog REQUIRED)
+FIND_PACKAGE(Isl REQUIRED)
+FIND_PACKAGE(Gmp REQUIRED)
+
+option(POLLY_ENABLE_OPENSCOP "Enable Openscop library for scop import/export" ON)
+if (POLLY_ENABLE_OPENSCOP)
+ FIND_PACKAGE(OpenScop)
+endif(POLLY_ENABLE_OPENSCOP)
+
+option(POLLY_ENABLE_SCOPLIB "Enable SCoPLib library for scop import/export" ON)
+if (POLLY_ENABLE_SCOPLIB)
+ FIND_PACKAGE(SCoPLib)
+endif(POLLY_ENABLE_SCOPLIB)
+
+INCLUDE_DIRECTORIES( ${CLOOG_INCLUDE_DIR} )
+INCLUDE_DIRECTORIES( ${ISL_INCLUDE_DIR} )
+INCLUDE_DIRECTORIES( ${GMP_INCLUDE_DIR} )
+
+# Support OpenScop export/import if the library is available.
+if (OPENSCOP_FOUND)
+ INCLUDE_DIRECTORIES( ${OPENSCOP_INCLUDE_DIR} )
+endif(OPENSCOP_FOUND)
+if (SCOPLIB_FOUND)
+ INCLUDE_DIRECTORIES( ${SCOPLIB_INCLUDE_DIR} )
+endif(SCOPLIB_FOUND)
+
+macro(add_polly_library name)
+ set(srcs ${ARGN})
+ if(MSVC_IDE OR XCODE)
+ file( GLOB_RECURSE headers *.h *.td *.def)
+ set(srcs ${srcs} ${headers})
+ string( REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR})
+ list( GET split_path -1 dir)
+ file( GLOB_RECURSE headers
+ ../../include/polly${dir}/*.h)
+ set(srcs ${srcs} ${headers})
+ endif(MSVC_IDE OR XCODE)
+ if (MODULE)
+ set(libkind MODULE)
+ elseif (SHARED_LIBRARY)
+ set(libkind SHARED)
+ else()
+ set(libkind)
+ endif()
+ add_library( ${name} ${libkind} ${srcs} )
+ if( LLVM_COMMON_DEPENDS )
+ add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
+ endif( LLVM_COMMON_DEPENDS )
+ if( LLVM_USED_LIBS )
+ foreach(lib ${LLVM_USED_LIBS})
+ target_link_libraries( ${name} ${lib} )
+ endforeach(lib)
+ endif( LLVM_USED_LIBS )
+
+ target_link_libraries( ${name} ${CLOOG_LIBRARY} ${ISL_LIBRARY} ${GMP_LIBRARY})
+ if (OPENSCOP_FOUND)
+ target_link_libraries( ${name} ${OPENSCOP_LIBRARY})
+ endif(OPENSCOP_FOUND)
+ if (SCOPLIB_FOUND)
+ target_link_libraries( ${name} ${SCOPLIB_LIBRARY})
+ endif(SCOPLIB_FOUND)
+
+ if( LLVM_LINK_COMPONENTS )
+ llvm_config(${name} ${LLVM_LINK_COMPONENTS})
+ endif( LLVM_LINK_COMPONENTS )
+ get_system_libs(llvm_system_libs)
+ if( llvm_system_libs )
+ target_link_libraries(${name} ${llvm_system_libs})
+ endif( llvm_system_libs )
+
+ if(MSVC)
+ get_target_property(cflag ${name} COMPILE_FLAGS)
+ if(NOT cflag)
+ set(cflag "")
+ endif(NOT cflag)
+ set(cflag "${cflag} /Za")
+ set_target_properties(${name} PROPERTIES COMPILE_FLAGS ${cflag})
+ endif(MSVC)
+ install(TARGETS ${name}
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+endmacro(add_polly_library)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib/JSON/include
+ ${CMAKE_CURRENT_BINARY_DIR}/include
+ )
+
+install(DIRECTORY include
+ DESTINATION .
+ PATTERN ".svn" EXCLUDE
+ )
+
+add_definitions( -D_GNU_SOURCE )
+
+add_subdirectory(include)
+add_subdirectory(lib)
+add_subdirectory(test)
+add_subdirectory(tools)
+# TODO: docs.
+
+
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/include/polly/Config/config.h.cmake
+ ${POLLY_BINARY_DIR}/include/polly/Config/config.h )
+
--- /dev/null
+This file is a partial list of people who have contributed to Polly.
+If you have contributed a patch or made some other contribution to
+LLVM, please submit a patch to this file to add yourself, and it will be
+done!
+
+The list is sorted by surname and formatted to allow easy grepping and
+beautification by scripts. The fields are: name (N), email (E), web-address
+(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
+(S).
+
+N: Raghesh Aloor
+E: raghesh.a@gmail.com
+D: OpenMP code generation
+D: Google Summer of Code student 2011
+
+N: Tobias Grosser
+E: tobias@grosser.es
+W: http://www.grosser.es
+D: Co-founder, design of the overall architecture
+
+N: Andreas Simbuerger
+E: simbuerg@fim.uni-passau.de
+D: Profiling infrastructure
+
+N: Hongbin Zheng
+E: etherzhhb@gmail.com
+D: Co-founder
+D: scop detection, automake/cmake infrastructure, scopinfo, scoppasses, ...
+D: Google Summer of Code student 2010
+
+
--- /dev/null
+==============================================================================
+Polly Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2011 Polly Team
+All rights reserved.
+
+Developed by:
+
+ Polly Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the Polly Team, copyright holders, nor the names of
+ its contributors may be used to endorse or promote products derived from
+ this Software without specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The Polly software contains code written by third parties. Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the Polly Distribution, and nothing in any of the other
+licenses gives permission to use the names of the Polly Team or promote products
+derived from this Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program Directory
+------- ---------
+jsoncpp lib/JSON
+
+
+
--- /dev/null
+##===- projects/polly/Makefile -----------------------------*- Makefile -*-===##
+#
+# This is a polly Makefile for a project that uses LLVM.
+#
+##===----------------------------------------------------------------------===##
+
+#
+# Indicates our relative path to the top of the project's root directory.
+#
+LEVEL = .
+DIRS = lib test tools
+EXTRA_DIST = include
+
+#
+# Include the Master Makefile that knows how to build all.
+#
+include $(LEVEL)/Makefile.common
--- /dev/null
+#===-- Makefile.common - Common make rules for Polly -------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+#
+# Configuration file to set paths specific to local installation of LLVM
+#
+PROJECT_NAME := polly
+PROJ_VERSION := 0.9
+# Set this variable to the top of the LLVM source tree.
+LLVM_SRC_ROOT = @LLVM_SRC@
+
+# Set the name of the project here
+
+# (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config).
+LLVM_OBJ_ROOT = @LLVM_OBJ@
+
+PROJ_SRC_ROOT := $(subst //,/,@abs_top_srcdir@)
+
+# Set the root directory of this project's object files
+PROJ_OBJ_ROOT := $(subst //,/,@abs_top_builddir@)
+
+ifndef LLVM_OBJ_ROOT
+include $(LEVEL)/Makefile.config
+else
+include $(PROJ_OBJ_ROOT)/Makefile.config
+endif
+
+# Include LLVM's Master Makefile.
+include $(LLVM_SRC_ROOT)/Makefile.common
--- /dev/null
+#===-- Makefile.config - Local configuration for LLVM ------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+#
+# This file is included by Makefile.common. It defines paths and other
+# values specific to a particular installation of LLVM.
+#
+#===------------------------------------------------------------------------===#
+
+# Set the root directory of this polly's object files
+POLLY_SRC_ROOT := $(subst //,/,@abs_top_srcdir@)
+
+# Set this variable to the top level directory where LLVM was built
+POLLY_OBJ_ROOT := $(subst //,/,@abs_top_builddir@)
+
+# Set the root directory of this project's install prefix
+PROJ_INSTALL_ROOT := @prefix@
+
+# Set the C++ flags
+ifeq (@GXX@,yes)
+POLLY_CXXFLAGS := "-fno-common -Woverloaded-virtual -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings"
+endif
+
+# Do us work with scoplib?
+OPENSCOP_FOUND := @openscop_found@
+SCOPLIB_FOUND := @scoplib_found@
+
+# Set include directroys
+POLLY_INC := @gmp_inc@ @isl_inc@ \
+ @cloog_inc@ @openscop_inc@ @scoplib_inc@ \
+ -I$(POLLY_SRC_ROOT)/lib/JSON/include
+
+POLLY_LD := @gmp_ld@ @isl_ld@ @cloog_ld@ @openscop_ld@ @scoplib_ld@ @scoplib_rpath@
+
+POLLY_LIB := @gmp_lib@ @isl_lib@ @cloog_lib@ @openscop_lib@ @scoplib_lib@
--- /dev/null
+Polly - Polyhedral optimizations for LLVM
+
+Polly uses a mathematical representation, the polyhedral model, to represent and
+transform loops and other control flow structures. Using an abstract
+representation it is possible to reason about transformations in a more general
+way and to use highly optimized linear programming libraries to figure out the
+optimal loop structure. These transformations can be used to do constant
+propagation through arrays, remove dead loop iterations, optimize loops for
+cache locality, optimize arrays, apply advanced automatic parallelization, drive
+vectorization, or they can be used to do software pipelining.
+
+
--- /dev/null
+#!/bin/sh
+die () {
+ echo "$@" 1>&2
+ exit 1
+}
+
+test -d autoconf && test -f autoconf/configure.ac && cd autoconf
+test -f configure.ac || die "Can't find 'autoconf' dir; please cd into it first"
+autoconf --version | egrep '2\.[5-6][0-9]' > /dev/null
+if test $? -ne 0 ; then
+ die "Your autoconf was not detected as being 2.5x"
+fi
+cwd=`pwd`
+if test -d ../../../autoconf/m4 ; then
+ cd ../../../autoconf/m4
+ llvm_m4=`pwd`
+ cd $cwd
+elif test -d ../../llvm/autoconf/m4 ; then
+ cd ../../llvm/autoconf/m4
+ llvm_m4=`pwd`
+ cd $cwd
+else
+ die "Can't find the LLVM autoconf/m4 directory. polly should be checked out to projects directory"
+fi
+echo "Regenerating aclocal.m4 with aclocal"
+rm -f aclocal.m4
+aclocal -I $llvm_m4 -I "$llvm_m4/.." -I $(pwd)/m4 || die "aclocal failed"
+echo "Regenerating configure with autoconf 2.5x"
+autoconf --force --warnings=all -o ../configure configure.ac || die "autoconf failed"
+cd ..
+echo "Regenerating config.h.in with autoheader"
+autoheader --warnings=all -I autoconf -I autoconf/m4 -I $llvm_m4 -I "$llvm_m4/.." autoconf/configure.ac || die "autoheader failed"
+exit 0
--- /dev/null
+------------------------------------------------------------------------------
+Autoconf Files
+------------------------------------------------------------------------------
+All autoconf files are licensed under the LLVM license with the following
+additions:
+
+llvm/autoconf/install-sh:
+ This script is licensed under the LLVM license, with the following
+ additional copyrights and restrictions:
+
+ Copyright 1991 by the Massachusetts Institute of Technology
+
+ Permission to use, copy, modify, distribute, and sell this software and its
+ documentation for any purpose is hereby granted without fee, provided that
+ the above copyright notice appear in all copies and that both that
+ copyright notice and this permission notice appear in supporting
+ documentation, and that the name of M.I.T. not be used in advertising or
+ publicity pertaining to distribution of the software without specific,
+ written prior permission. M.I.T. makes no representations about the
+ suitability of this software for any purpose. It is provided "as is"
+ without express or implied warranty.
+
+Please see the source files for additional copyrights.
+
--- /dev/null
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+dnl find_lib_and_headers(name, verify-header, library-name, requirded?)
+dnl Export
+dnl name_inc in -I"include-path" form
+dnl name_lib in -l"library-name" form
+dnl name_ld in -L"library-path" form
+dnl name_found set to "yes" if found
+
+AC_DEFUN([find_lib_and_headers],
+[
+ AC_LANG_PUSH(C++)
+ OLD_CXXFLAGS=$CXXFLAGS;
+ OLD_LDFLAGS=$LDFLAGS;
+ OLD_LIBS=$LIBS;
+
+ LIBS="$LIBS -l$3";
+
+ # Get include path and lib path
+ AC_ARG_WITH([$1],
+ [AS_HELP_STRING([--with-$1], [prefix of $1 ])],
+ [given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+ given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"],
+ [given_inc_path=inc_not_give_$1;
+ given_lib_path=lib_not_give_$1]
+ )
+ # Check for library and headers works
+ AC_MSG_CHECKING([for $1 in $given_inc_path, $given_lib_path])
+ # try to compile a file that includes a header of the library
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <$2>]], [[;]])],
+ [AC_MSG_RESULT([ok])
+ AC_SUBST([$1_found],["yes"])
+ AS_IF([test "x$given_inc_path" != "xinc_not_give_$1"],
+ [AC_SUBST([$1_inc],["-I$given_inc_path"])])
+ AC_SUBST([$1_lib],["-l$3"])
+ AS_IF([test "x$given_lib_path" != "xlib_not_give_$1"],
+ [AC_SUBST([$1_ld],["-L$given_lib_path"])])],
+ [AS_IF([test "x$4" = "xrequired"],
+ [AC_MSG_ERROR([$1 required but not found])],
+ [AC_MSG_RESULT([not found])])]
+ )
+
+ # reset original CXXFLAGS
+ CXXFLAGS=$OLD_CXXFLAGS
+ LDFLAGS=$OLD_LDFLAGS;
+ LIBS=$OLD_LIBS
+ AC_LANG_POP(C++)
+])
+
+#
+# Provide the arguments and other processing needed for an LLVM project
+#
+AC_DEFUN([LLVM_CONFIG_PROJECT],
+ [AC_ARG_WITH([llvmsrc],
+ AS_HELP_STRING([--with-llvmsrc],[Location of LLVM Source Code]),
+ [llvm_src="$withval"],[llvm_src="]$1["])
+ AC_SUBST(LLVM_SRC,$llvm_src)
+ AC_ARG_WITH([llvmobj],
+ AS_HELP_STRING([--with-llvmobj],[Location of LLVM Object Code]),
+ [llvm_obj="$withval"],[llvm_obj="]$2["])
+ AC_SUBST(LLVM_OBJ,$llvm_obj)
+ AC_CONFIG_COMMANDS([setup],,[llvm_src="${LLVM_SRC}"])
+])
+
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-02-22'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvmeppc:OpenBSD:*:*)
+ echo powerpc-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mipseb-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ DRS?6000:UNIX_SV:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7 && exit 0 ;;
+ esac ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c \
+ && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && exit 0
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ # avoid double evaluation of $set_cc_for_build
+ test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ *:UNICOS/mp:*:*)
+ echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ # Determine whether the default compiler uses glibc.
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #if __GLIBC__ >= 2
+ LIBC=gnu
+ #else
+ LIBC=
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ x86:Interix*:3*)
+ echo i586-pc-interix3
+ exit 0 ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit 0 ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ case `uname -p` in
+ *86) UNAME_PROCESSOR=i686 ;;
+ powerpc) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-02-22'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k \
+ | m32r | m68000 | m68k | m88k | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | msp430 \
+ | ns16k | ns32k \
+ | openrisc | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+ | strongarm \
+ | tahoe | thumb | tic80 | tron \
+ | v850 | v850e \
+ | we32k \
+ | x86 | xscale | xstormy16 | xtensa \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* \
+ | m32r-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | mcore-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | msp430-* \
+ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
+ | v850-* | v850e-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+ | xtensa-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nv1)
+ basic_machine=nv1-cray
+ os=-unicosmp
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i686-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tic4x | c4x*)
+ basic_machine=tic4x-unknown
+ os=-coff
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+dnl **************************************************************************
+dnl * Initialize
+dnl **************************************************************************
+AC_INIT([Polly],[0.01],[polly-dev@googlegroups.com])
+
+dnl Identify where LLVM source tree is
+LLVM_SRC_ROOT="`(cd $srcdir/../..; pwd)`"
+LLVM_OBJ_ROOT="`(cd ../..; pwd)`"
+
+dnl Tell autoconf that this is an LLVM project being configured
+dnl This provides the --with-llvmsrc and --with-llvmobj options
+LLVM_CONFIG_PROJECT($LLVM_SRC_ROOT,$LLVM_OBJ_ROOT)
+
+dnl Tell autoconf that the auxilliary files are actually located in
+dnl the LLVM autoconf directory, not here.
+AC_CONFIG_AUX_DIR($LLVM_SRC/autoconf)
+
+dnl Indicate that we require autoconf 2.59 or later. Ths is needed because we
+dnl use some autoconf macros only available in 2.59.
+AC_PREREQ(2.59)
+
+dnl Verify that the source directory is valid
+AC_CONFIG_SRCDIR(["lib/Analysis/ScopInfo.cpp"])
+
+dnl Configure a common Makefile
+AC_CONFIG_FILES(Makefile.config)
+AC_CONFIG_FILES(Makefile.common)
+
+dnl Configure project makefiles
+dnl List every Makefile that exists within your source tree
+
+dnl Quit if the source directory has already been configured.
+dnl NOTE: This relies upon undocumented autoconf behavior.
+if test ${srcdir} != "." ; then
+ if test -f ${srcdir}/include/polly/Config/config.h ; then
+ AC_MSG_ERROR([Already configured in ${srcdir}])
+ fi
+fi
+
+AC_DEFINE([CLOOG_INT_GMP], [1], [Use gmp for isl])
+
+dnl **************************************************************************
+dnl * Determine which system we are building on
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Check for programs.
+dnl **************************************************************************
+
+dnl AC_PROG_CPP
+dnl AC_PROG_CC(gcc)
+dnl AC_PROG_CXX(g++)
+
+dnl **************************************************************************
+dnl * Check for libraries.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for header files.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for typedefs, structures, and compiler characteristics.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for library functions.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Enable various compile-time options
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Set the location of various third-party software packages
+dnl **************************************************************************
+dnl Find Gmp
+find_lib_and_headers([gmp], [gmp.h], [gmp], [required])
+
+dnl Find Isl
+find_lib_and_headers([isl], [isl/config.h], [isl], [required])
+
+dnl Find cloog
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $isl_inc"
+find_lib_and_headers([cloog], [cloog/isl/cloog.h], [cloog-isl], [required])
+CXXFLAGS=$saved_CXXFLAGS
+
+
+dnl Check if Scoplib there
+find_lib_and_headers([openscop], [openscop/scop.h], [openscop])
+AS_IF([test "x$openscop_found" = "xyes"],
+ [AC_DEFINE([OPENSCOP_FOUND],[1],[Define if openscop found])])
+
+dnl Check if Scoplib there
+find_lib_and_headers([scoplib], [scoplib/scop.h], [scoplib])
+AS_IF([test "x$scoplib_found" = "xyes"],
+ [AC_DEFINE([SCOPLIB_FOUND],[1],[Define if scoplib found])])
+
+if test "x$scoplib_found" = "xyes"; then :
+ scoplib_rpath="-Wl,-rpath=$given_lib_path"
+else
+ scoplib_rpath=""
+fi
+
+AC_SUBST(scoplib_rpath)
+
+dnl **************************************************************************
+dnl * Create the output files
+dnl **************************************************************************
+
+dnl This must be last
+AC_CONFIG_HEADERS(include/polly/Config/config.h)
+AC_OUTPUT
--- /dev/null
+dnl **************************************************************************
+dnl * Initialize
+dnl **************************************************************************
+AC_INIT([Polly],[0.01],[etherzhhb@gmail.com grosser@fim.uni-passau.de ojomojo@gmail.com])
+
+dnl Identify where LLVM source tree is
+LLVM_SRC_ROOT="../.."
+LLVM_OBJ_ROOT="../.."
+dnl Tell autoconf that the auxilliary files are actually located in
+dnl the LLVM autoconf directory, not here.
+AC_CONFIG_AUX_DIR($LLVM_SRC_ROOT/autoconf)
+
+dnl Tell autoconf that this is an LLVM project being configured
+dnl This provides the --with-llvmsrc and --with-llvmobj options
+LLVM_CONFIG_PROJECT($LLVM_SRC_ROOT,$LLVM_OBJ_ROOT)
+
+dnl Verify that the source directory is valid
+AC_CONFIG_SRCDIR(["Makefile.common.in"])
+
+dnl Configure a common Makefile
+AC_CONFIG_FILES(Makefile.common)
+
+dnl Configure project makefiles
+dnl List every Makefile that exists within your source tree
+AC_CONFIG_MAKEFILE(Makefile)
+AC_CONFIG_MAKEFILE(lib/Makefile)
+
+dnl **************************************************************************
+dnl * Determine which system we are building on
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Check for programs.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Check for libraries.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for header files.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for typedefs, structures, and compiler characteristics.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for library functions.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Enable various compile-time options
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Set the location of various third-party software packages
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Create the output files
+dnl **************************************************************************
+
+dnl This must be last
+AC_OUTPUT
--- /dev/null
+dnl find_lib_and_headers(name, verify-header, library-name, requirded?)
+dnl Export
+dnl name_inc in -I"include-path" form
+dnl name_lib in -l"library-name" form
+dnl name_ld in -L"library-path" form
+dnl name_found set to "yes" if found
+
+AC_DEFUN([find_lib_and_headers],
+[
+ AC_LANG_PUSH(C++)
+ OLD_CXXFLAGS=$CXXFLAGS;
+ OLD_LDFLAGS=$LDFLAGS;
+ OLD_LIBS=$LIBS;
+
+ LIBS="$LIBS -l$3";
+
+ # Get include path and lib path
+ AC_ARG_WITH([$1],
+ [AS_HELP_STRING([--with-$1], [prefix of $1 ])],
+ [given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+ given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"],
+ [given_inc_path=inc_not_give_$1;
+ given_lib_path=lib_not_give_$1]
+ )
+ # Check for library and headers works
+ AC_MSG_CHECKING([for $1 in $given_inc_path, $given_lib_path])
+ # try to compile a file that includes a header of the library
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <$2>]], [[;]])],
+ [AC_MSG_RESULT([ok])
+ AC_SUBST([$1_found],["yes"])
+ AS_IF([test "x$given_inc_path" != "xinc_not_give_$1"],
+ [AC_SUBST([$1_inc],["-I$given_inc_path"])])
+ AC_SUBST([$1_lib],["-l$3"])
+ AS_IF([test "x$given_lib_path" != "xlib_not_give_$1"],
+ [AC_SUBST([$1_ld],["-L$given_lib_path"])])],
+ [AS_IF([test "x$4" = "xrequired"],
+ [AC_MSG_ERROR([$1 required but not found])],
+ [AC_MSG_RESULT([not found])])]
+ )
+
+ # reset original CXXFLAGS
+ CXXFLAGS=$OLD_CXXFLAGS
+ LDFLAGS=$OLD_LDFLAGS;
+ LIBS=$OLD_LIBS
+ AC_LANG_POP(C++)
+])
--- /dev/null
+FIND_PATH(CLOOG_INCLUDE_DIR cloog/isl/cloog.h)
+
+FIND_LIBRARY(CLOOG_LIBRARY NAMES cloog-isl)
+
+IF (CLOOG_INCLUDE_DIR AND CLOOG_LIBRARY)
+ SET(CLOOG_FOUND TRUE)
+ENDIF (CLOOG_INCLUDE_DIR AND CLOOG_LIBRARY)
+
+
+IF (CLOOG_FOUND)
+ IF (NOT CLOOG_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Cloog: ${CLOOG_LIBRARY}")
+ ENDIF (NOT CLOOG_FIND_QUIETLY)
+ELSE (CLOOG_FOUND)
+ IF (CLOOG_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find Cloog")
+ ENDIF (CLOOG_FIND_REQUIRED)
+ENDIF (CLOOG_FOUND)
+
--- /dev/null
+FIND_PATH(GMP_INCLUDE_DIR gmp.h)
+
+FIND_LIBRARY(GMP_LIBRARY NAMES gmp)
+
+IF (GMP_INCLUDE_DIR AND GMP_LIBRARY)
+ SET(GMP_FOUND TRUE)
+ENDIF (GMP_INCLUDE_DIR AND GMP_LIBRARY)
+
+
+IF (GMP_FOUND)
+ IF (NOT GMP_FIND_QUIETLY)
+ MESSAGE(STATUS "Found GMP: ${GMP_LIBRARY}")
+ ENDIF (NOT GMP_FIND_QUIETLY)
+ELSE (GMP_FOUND)
+ IF (GMP_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find GMP")
+ ENDIF (GMP_FIND_REQUIRED)
+ENDIF (GMP_FOUND)
+
--- /dev/null
+FIND_PATH(ISL_INCLUDE_DIR isl/set.h)
+
+FIND_LIBRARY(ISL_LIBRARY NAMES isl)
+
+IF (ISL_INCLUDE_DIR AND ISL_LIBRARY)
+ SET(ISL_FOUND TRUE)
+ENDIF (ISL_INCLUDE_DIR AND ISL_LIBRARY)
+
+
+IF (ISL_FOUND)
+ IF (NOT Isl_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Isl: ${ISL_LIBRARY}")
+ ENDIF (NOT Isl_FIND_QUIETLY)
+ELSE (ISL_FOUND)
+ IF (Isl_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find Isl")
+ ENDIF (Isl_FIND_REQUIRED)
+ENDIF (ISL_FOUND)
+
--- /dev/null
+FIND_PATH(OPENSCOP_INCLUDE_DIR openscop/scop.h)
+
+FIND_LIBRARY(OPENSCOP_LIBRARY NAMES openscop)
+
+IF (OPENSCOP_INCLUDE_DIR AND OPENSCOP_LIBRARY)
+ SET(OPENSCOP_FOUND TRUE)
+ENDIF (OPENSCOP_INCLUDE_DIR AND OPENSCOP_LIBRARY)
+
+
+IF (OPENSCOP_FOUND)
+ IF (NOT Isl_FIND_QUIETLY)
+ MESSAGE(STATUS "Found OpenScop: ${OPENSCOP_LIBRARY}")
+ ENDIF (NOT Isl_FIND_QUIETLY)
+ELSE (OPENSCOP_FOUND)
+ IF (Isl_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find OpenScop")
+ ENDIF (Isl_FIND_REQUIRED)
+ENDIF (OPENSCOP_FOUND)
+
--- /dev/null
+FIND_PATH(SCOPLIB_INCLUDE_DIR scoplib/scop.h)
+
+FIND_LIBRARY(SCOPLIB_LIBRARY NAMES scoplib)
+
+IF (SCOPLIB_INCLUDE_DIR AND SCOPLIB_LIBRARY)
+ SET(SCOPLIB_FOUND TRUE)
+ENDIF (SCOPLIB_INCLUDE_DIR AND SCOPLIB_LIBRARY)
+
+
+IF (SCOPLIB_FOUND)
+ IF (NOT Isl_FIND_QUIETLY)
+ MESSAGE(STATUS "Found SCoPLib: ${SCOPLIB_LIBRARY}")
+ ENDIF (NOT Isl_FIND_QUIETLY)
+ELSE (SCOPLIB_FOUND)
+ IF (Isl_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find SCoPLib")
+ ENDIF (Isl_FIND_REQUIRED)
+ENDIF (SCOPLIB_FOUND)
+
--- /dev/null
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.67 for Polly 0.01.
+#
+# Report bugs to <polly-dev@googlegroups.com>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: polly-dev@googlegroups.com about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Polly'
+PACKAGE_TARNAME='polly'
+PACKAGE_VERSION='0.01'
+PACKAGE_STRING='Polly 0.01'
+PACKAGE_BUGREPORT='polly-dev@googlegroups.com'
+PACKAGE_URL=''
+
+ac_unique_file=""lib/Analysis/ScopInfo.cpp""
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+scoplib_rpath
+scoplib_ld
+scoplib_lib
+scoplib_inc
+scoplib_found
+openscop_ld
+openscop_lib
+openscop_inc
+openscop_found
+cloog_ld
+cloog_lib
+cloog_inc
+cloog_found
+isl_ld
+isl_lib
+isl_inc
+isl_found
+gmp_ld
+gmp_lib
+gmp_inc
+gmp_found
+OBJEXT
+EXEEXT
+ac_ct_CXX
+CPPFLAGS
+LDFLAGS
+CXXFLAGS
+CXX
+LLVM_OBJ
+LLVM_SRC
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_llvmsrc
+with_llvmobj
+with_gmp
+with_isl
+with_cloog
+with_openscop
+with_scoplib
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CCC'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used" >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures Polly 0.01 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/polly]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of Polly 0.01:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-llvmsrc Location of LLVM Source Code
+ --with-llvmobj Location of LLVM Object Code
+ --with-gmp prefix of gmp
+ --with-isl prefix of isl
+ --with-cloog prefix of cloog
+ --with-openscop prefix of openscop
+ --with-scoplib prefix of scoplib
+
+Some influential environment variables:
+ CXX C++ compiler command
+ CXXFLAGS C++ compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <polly-dev@googlegroups.com>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+Polly configure 0.01
+generated by GNU Autoconf 2.67
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Polly $as_me 0.01, which was
+generated by GNU Autoconf 2.67. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5 ; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+LLVM_SRC_ROOT="`(cd $srcdir/../..; pwd)`"
+LLVM_OBJ_ROOT="`(cd ../..; pwd)`"
+
+
+# Check whether --with-llvmsrc was given.
+if test "${with_llvmsrc+set}" = set; then :
+ withval=$with_llvmsrc; llvm_src="$withval"
+else
+ llvm_src="$LLVM_SRC_ROOT"
+fi
+
+ LLVM_SRC=$llvm_src
+
+
+# Check whether --with-llvmobj was given.
+if test "${with_llvmobj+set}" = set; then :
+ withval=$with_llvmobj; llvm_obj="$withval"
+else
+ llvm_obj="$LLVM_OBJ_ROOT"
+fi
+
+ LLVM_OBJ=$llvm_obj
+
+ ac_config_commands="$ac_config_commands setup"
+
+
+
+ac_aux_dir=
+for ac_dir in $LLVM_SRC/autoconf "$srcdir"/$LLVM_SRC/autoconf; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in $LLVM_SRC/autoconf \"$srcdir\"/$LLVM_SRC/autoconf" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+
+
+
+
+ac_config_files="$ac_config_files Makefile.config"
+
+ac_config_files="$ac_config_files Makefile.common"
+
+
+
+if test ${srcdir} != "." ; then
+ if test -f ${srcdir}/include/polly/Config/config.h ; then
+ as_fn_error $? "Already configured in ${srcdir}" "$LINENO" 5
+ fi
+fi
+
+
+$as_echo "#define CLOOG_INT_GMP 1" >>confdefs.h
+
+
+
+
+
+
+
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5
+$as_echo_n "checking whether the C++ compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C++ compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5 ; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5
+$as_echo_n "checking for C++ compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5 ; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5 ; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ OLD_CXXFLAGS=$CXXFLAGS;
+ OLD_LDFLAGS=$LDFLAGS;
+ OLD_LIBS=$LIBS;
+
+ LIBS="$LIBS -lgmp";
+
+ # Get include path and lib path
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+ withval=$with_gmp; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+ given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"
+else
+ given_inc_path=inc_not_give_gmp;
+ given_lib_path=lib_not_give_gmp
+
+fi
+
+ # Check for library and headers works
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gmp in $given_inc_path, $given_lib_path" >&5
+$as_echo_n "checking for gmp in $given_inc_path, $given_lib_path... " >&6; }
+ # try to compile a file that includes a header of the library
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <gmp.h>
+int
+main ()
+{
+;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+ gmp_found="yes"
+
+ if test "x$given_inc_path" != "xinc_not_give_gmp"; then :
+ gmp_inc="-I$given_inc_path"
+
+fi
+ gmp_lib="-lgmp"
+
+ if test "x$given_lib_path" != "xlib_not_give_gmp"; then :
+ gmp_ld="-L$given_lib_path"
+
+fi
+else
+ if test "xrequired" = "xrequired"; then :
+ as_fn_error $? "gmp required but not found" "$LINENO" 5
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ # reset original CXXFLAGS
+ CXXFLAGS=$OLD_CXXFLAGS
+ LDFLAGS=$OLD_LDFLAGS;
+ LIBS=$OLD_LIBS
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ OLD_CXXFLAGS=$CXXFLAGS;
+ OLD_LDFLAGS=$LDFLAGS;
+ OLD_LIBS=$LIBS;
+
+ LIBS="$LIBS -lisl";
+
+ # Get include path and lib path
+
+# Check whether --with-isl was given.
+if test "${with_isl+set}" = set; then :
+ withval=$with_isl; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+ given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"
+else
+ given_inc_path=inc_not_give_isl;
+ given_lib_path=lib_not_give_isl
+
+fi
+
+ # Check for library and headers works
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isl in $given_inc_path, $given_lib_path" >&5
+$as_echo_n "checking for isl in $given_inc_path, $given_lib_path... " >&6; }
+ # try to compile a file that includes a header of the library
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <isl/config.h>
+int
+main ()
+{
+;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+ isl_found="yes"
+
+ if test "x$given_inc_path" != "xinc_not_give_isl"; then :
+ isl_inc="-I$given_inc_path"
+
+fi
+ isl_lib="-lisl"
+
+ if test "x$given_lib_path" != "xlib_not_give_isl"; then :
+ isl_ld="-L$given_lib_path"
+
+fi
+else
+ if test "xrequired" = "xrequired"; then :
+ as_fn_error $? "isl required but not found" "$LINENO" 5
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ # reset original CXXFLAGS
+ CXXFLAGS=$OLD_CXXFLAGS
+ LDFLAGS=$OLD_LDFLAGS;
+ LIBS=$OLD_LIBS
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $isl_inc"
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ OLD_CXXFLAGS=$CXXFLAGS;
+ OLD_LDFLAGS=$LDFLAGS;
+ OLD_LIBS=$LIBS;
+
+ LIBS="$LIBS -lcloog-isl";
+
+ # Get include path and lib path
+
+# Check whether --with-cloog was given.
+if test "${with_cloog+set}" = set; then :
+ withval=$with_cloog; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+ given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"
+else
+ given_inc_path=inc_not_give_cloog;
+ given_lib_path=lib_not_give_cloog
+
+fi
+
+ # Check for library and headers works
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cloog in $given_inc_path, $given_lib_path" >&5
+$as_echo_n "checking for cloog in $given_inc_path, $given_lib_path... " >&6; }
+ # try to compile a file that includes a header of the library
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <cloog/isl/cloog.h>
+int
+main ()
+{
+;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+ cloog_found="yes"
+
+ if test "x$given_inc_path" != "xinc_not_give_cloog"; then :
+ cloog_inc="-I$given_inc_path"
+
+fi
+ cloog_lib="-lcloog-isl"
+
+ if test "x$given_lib_path" != "xlib_not_give_cloog"; then :
+ cloog_ld="-L$given_lib_path"
+
+fi
+else
+ if test "xrequired" = "xrequired"; then :
+ as_fn_error $? "cloog required but not found" "$LINENO" 5
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ # reset original CXXFLAGS
+ CXXFLAGS=$OLD_CXXFLAGS
+ LDFLAGS=$OLD_LDFLAGS;
+ LIBS=$OLD_LIBS
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+CXXFLAGS=$saved_CXXFLAGS
+
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ OLD_CXXFLAGS=$CXXFLAGS;
+ OLD_LDFLAGS=$LDFLAGS;
+ OLD_LIBS=$LIBS;
+
+ LIBS="$LIBS -lopenscop";
+
+ # Get include path and lib path
+
+# Check whether --with-openscop was given.
+if test "${with_openscop+set}" = set; then :
+ withval=$with_openscop; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+ given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"
+else
+ given_inc_path=inc_not_give_openscop;
+ given_lib_path=lib_not_give_openscop
+
+fi
+
+ # Check for library and headers works
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openscop in $given_inc_path, $given_lib_path" >&5
+$as_echo_n "checking for openscop in $given_inc_path, $given_lib_path... " >&6; }
+ # try to compile a file that includes a header of the library
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <openscop/scop.h>
+int
+main ()
+{
+;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+ openscop_found="yes"
+
+ if test "x$given_inc_path" != "xinc_not_give_openscop"; then :
+ openscop_inc="-I$given_inc_path"
+
+fi
+ openscop_lib="-lopenscop"
+
+ if test "x$given_lib_path" != "xlib_not_give_openscop"; then :
+ openscop_ld="-L$given_lib_path"
+
+fi
+else
+ if test "x" = "xrequired"; then :
+ as_fn_error $? "openscop required but not found" "$LINENO" 5
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ # reset original CXXFLAGS
+ CXXFLAGS=$OLD_CXXFLAGS
+ LDFLAGS=$OLD_LDFLAGS;
+ LIBS=$OLD_LIBS
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+if test "x$openscop_found" = "xyes"; then :
+
+$as_echo "#define OPENSCOP_FOUND 1" >>confdefs.h
+
+fi
+
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ OLD_CXXFLAGS=$CXXFLAGS;
+ OLD_LDFLAGS=$LDFLAGS;
+ OLD_LIBS=$LIBS;
+
+ LIBS="$LIBS -lscoplib";
+
+ # Get include path and lib path
+
+# Check whether --with-scoplib was given.
+if test "${with_scoplib+set}" = set; then :
+ withval=$with_scoplib; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+ given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"
+else
+ given_inc_path=inc_not_give_scoplib;
+ given_lib_path=lib_not_give_scoplib
+
+fi
+
+ # Check for library and headers works
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for scoplib in $given_inc_path, $given_lib_path" >&5
+$as_echo_n "checking for scoplib in $given_inc_path, $given_lib_path... " >&6; }
+ # try to compile a file that includes a header of the library
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <scoplib/scop.h>
+int
+main ()
+{
+;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+ scoplib_found="yes"
+
+ if test "x$given_inc_path" != "xinc_not_give_scoplib"; then :
+ scoplib_inc="-I$given_inc_path"
+
+fi
+ scoplib_lib="-lscoplib"
+
+ if test "x$given_lib_path" != "xlib_not_give_scoplib"; then :
+ scoplib_ld="-L$given_lib_path"
+
+fi
+else
+ if test "x" = "xrequired"; then :
+ as_fn_error $? "scoplib required but not found" "$LINENO" 5
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ # reset original CXXFLAGS
+ CXXFLAGS=$OLD_CXXFLAGS
+ LDFLAGS=$OLD_LDFLAGS;
+ LIBS=$OLD_LIBS
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+if test "x$scoplib_found" = "xyes"; then :
+
+$as_echo "#define SCOPLIB_FOUND 1" >>confdefs.h
+
+fi
+
+if test "x$scoplib_found" = "xyes"; then :
+ scoplib_rpath="-Wl,-rpath=$given_lib_path"
+else
+ scoplib_rpath=""
+fi
+
+
+
+
+ac_config_headers="$ac_config_headers include/polly/Config/config.h"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Polly $as_me 0.01, which was
+generated by GNU Autoconf 2.67. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <polly-dev@googlegroups.com>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+Polly config.status 0.01
+configured by $0, generated by GNU Autoconf 2.67,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+llvm_src="${LLVM_SRC}"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "setup") CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;;
+ "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
+ "Makefile.common") CONFIG_FILES="$CONFIG_FILES Makefile.common" ;;
+ "include/polly/Config/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/polly/Config/config.h" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = "\a"
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = "\a"
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
--- /dev/null
+<html>
+ <body>
+ <h1>SAMPLE PROJECT DOCUMENTATION</h1>
+ <p>This is just a placeholder</p>
+ </body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="401.6861"
+ height="238.80142"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.0 r9654"
+ sodipodi:docname="polly.png">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.32759489"
+ inkscape:cx="105.19472"
+ inkscape:cy="-140.99869"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="862"
+ inkscape:window-height="879"
+ inkscape:window-x="0"
+ inkscape:window-y="19"
+ inkscape:window-maximized="0"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-180.51353,-120.73426)">
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot3053"
+ style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion
+ id="flowRegion3055"><rect
+ id="rect3057"
+ width="234.05714"
+ height="123.29796"
+ x="115.98367"
+ y="215.39891" /></flowRegion><flowPara
+ id="flowPara3059"></flowPara></flowRoot> <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:OpenSymbol;-inkscape-font-specification:OpenSymbol"
+ x="173.45306"
+ y="355.41525"
+ id="text3061"
+ sodipodi:linespacing="125%"><tspan
+ sodipodi:role="line"
+ id="tspan3063"
+ x="173.45306"
+ y="355.41525"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:URW Bookman L;-inkscape-font-specification:URW Bookman L" /></text>
+ <g
+ id="g3981">
+ <g
+ id="g3971">
+ <text
+ xml:space="preserve"
+ style="font-size:188.40333557px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#253ba3;fill-opacity:1;stroke:none;font-family:Sans"
+ x="166.2375"
+ y="263.02325"
+ id="text3069"
+ sodipodi:linespacing="125%"
+ transform="scale(0.97718415,1.0233486)"><tspan
+ sodipodi:role="line"
+ id="tspan3071"
+ x="166.2375"
+ y="263.02325">Po</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:188.40333557px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#25a34d;fill-opacity:1;stroke:none;font-family:Sans"
+ x="401.41913"
+ y="255.32637"
+ id="text3073"
+ sodipodi:linespacing="125%"
+ transform="scale(0.97718415,1.0233486)"><tspan
+ sodipodi:role="line"
+ id="tspan3075"
+ x="401.41913"
+ y="255.32637">L </tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:188.40333557px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#a38c25;fill-opacity:1;stroke:none;font-family:Sans"
+ x="489.90826"
+ y="262.77887"
+ id="text3077"
+ sodipodi:linespacing="125%"
+ transform="scale(0.97718415,1.0233486)"><tspan
+ sodipodi:role="line"
+ id="tspan3079"
+ x="489.90826"
+ y="262.77887">y</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:188.40333557px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#a3257a;fill-opacity:1;stroke:none;font-family:Sans"
+ x="369.58545"
+ y="282.15436"
+ id="text3081"
+ sodipodi:linespacing="125%"
+ transform="scale(0.97718415,1.0233486)"><tspan
+ sodipodi:role="line"
+ id="tspan3083"
+ x="369.58545"
+ y="282.15436">L</tspan></text>
+ </g>
+ <text
+ transform="scale(0.97718415,1.0233486)"
+ sodipodi:linespacing="125%"
+ id="text3085"
+ y="343.51309"
+ x="214.77977"
+ style="font-size:188.40333557px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ xml:space="preserve"><tspan
+ style="font-size:37.68066788px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Liberation Mono;-inkscape-font-specification:Liberation Mono"
+ y="343.51309"
+ x="214.77977"
+ id="tspan3087"
+ sodipodi:role="line">Polyhedral LLVM</tspan></text>
+ </g>
+ </g>
+</svg>
--- /dev/null
+add_subdirectory(polly)
--- /dev/null
+if( MSVC_IDE OR XCODE )
+ # Creates a dummy target containing all headers for the benefit of
+ # Visual Studio users.
+ file(GLOB_RECURSE headers *.h)
+ add_library(polly_headers_do_not_build EXCLUDE_FROM_ALL
+ # We need at least one source file:
+ ${POLLY_SOURCE_DIR}/lib/Support/GICHelper.cpp
+ ${headers})
+endif()
--- /dev/null
+//===- CLooG.h - CLooG interface --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// CLooG[1] interface.
+//
+// The CLooG interface takes a Scop and generates a CLooG AST (clast). This
+// clast can either be returned directly or it can be pretty printed to stdout.
+//
+// A typical clast output looks like this:
+//
+// for (c2 = max(0, ceild(n + m, 2); c2 <= min(511, floord(5 * n, 3)); c2++) {
+// bb2(c2);
+// }
+//
+// [1] http://www.cloog.org/ - The Chunky Loop Generator
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_CLOOG_H
+#define POLLY_CLOOG_H
+#include "polly/ScopPass.h"
+
+#define CLOOG_INT_GMP 1
+#include "cloog/cloog.h"
+
+struct clast_name;
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace polly {
+ class Scop;
+ class Cloog;
+
+ class CloogInfo : public ScopPass {
+ Cloog *C;
+ Scop *scop;
+
+ public:
+ static char ID;
+ CloogInfo() : ScopPass(ID), C(0) {}
+
+ /// Write a .cloog input file
+ void dump(FILE *F);
+
+ /// Print a source code representation of the program.
+ void pprint(llvm::raw_ostream &OS);
+
+ /// Create the CLooG AST from this program.
+ const struct clast_stmt *getClast();
+
+ bool runOnScop(Scop &S);
+ void printScop(llvm::raw_ostream &OS) const;
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ };
+}
+#endif /* POLLY_CLOOG_H */
--- /dev/null
+//===- polly/Config.h ------------ Configuration of Polly -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Configuration of Polly.
+//
+//===----------------------------------------------------------------------===//
+#ifndef POLLY_CONFIG_H
+#define POLLY_CONFIG_H
+
+#cmakedefine OPENSCOP_FOUND
+#cmakedefine SCOPLIB_FOUND
+
+#endif
--- /dev/null
+/* include/polly/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */
+
+/* Use gmp for isl */
+#undef CLOOG_INT_GMP
+
+/* Define if openscop found */
+#undef OPENSCOP_FOUND
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define if scoplib found */
+#undef SCOPLIB_FOUND
--- /dev/null
+//===------ polly/Dependences.h - Polyhedral dependency analysis *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Calculate the data dependency relations for a Scop using ISL.
+//
+// The integer set library (ISL) from Sven, has a integrated dependency analysis
+// to calculate data dependences. This pass takes advantage of this and
+// calculate those dependences a Scop.
+//
+// The dependences in this pass are exact in terms that for a specific read
+// statement instance only the last write statement instance is returned. In
+// case of may writes a set of possible write instances is returned. This
+// analysis will never produce redundant dependences.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_DEPENDENCES_H
+#define POLLY_DEPENDENCES_H
+
+#include "polly/ScopPass.h"
+
+#include <map>
+
+struct isl_union_map;
+struct isl_union_set;
+struct isl_map;
+struct isl_set;
+
+using namespace llvm;
+
+namespace polly {
+
+ class Scop;
+ class ScopStmt;
+
+ class Dependences : public ScopPass {
+
+ isl_union_map *must_dep, *may_dep;
+ isl_union_map *must_no_source, *may_no_source;
+
+ isl_union_map *war_dep;
+ isl_union_map *waw_dep;
+
+ isl_union_map *sink;
+ isl_union_map *must_source;
+ isl_union_map *may_source;
+
+ public:
+ static char ID;
+ typedef std::map<ScopStmt*, isl_map*> StatementToIslMapTy;
+
+ Dependences();
+ bool isValidScattering(StatementToIslMapTy *NewScatterings);
+
+ /// @brief Check if a dimension of the Scop can be executed in parallel.
+ ///
+ /// @param loopDomain The subset of the scattering space that is executed in
+ /// parallel.
+ /// @param parallelDimension The scattering dimension that is being executed
+ /// in parallel.
+ ///
+ /// @return bool Returns true, if executing parallelDimension in parallel is
+ /// valid for the scattering domain subset given.
+ bool isParallelDimension(isl_set *loopDomain, unsigned parallelDimension);
+
+ bool runOnScop(Scop &S);
+ void printScop(raw_ostream &OS) const;
+ virtual void releaseMemory();
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ };
+} // End polly namespace.
+
+#endif
--- /dev/null
+//===- polly/LinkAllPasses.h ------------ Reference All Passes ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all transformation and analysis passes for tools
+// like opt and bugpoint that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_LINKALLPASSES_H
+#define POLLY_LINKALLPASSES_H
+
+#include "polly/Config/config.h"
+#include <cstdlib>
+
+namespace llvm {
+ class Pass;
+ class PassInfo;
+ class RegionPass;
+}
+
+using namespace llvm;
+
+namespace polly {
+ Pass *createAffSCEVItTesterPass();
+ Pass *createCloogExporterPass();
+ Pass *createCloogInfoPass();
+ Pass *createCodeGenerationPass();
+ Pass *createCodePreperationPass();
+ Pass *createDependencesPass();
+ Pass *createDOTOnlyPrinterPass();
+ Pass *createDOTOnlyViewerPass();
+ Pass *createDOTPrinterPass();
+ Pass *createDOTViewerPass();
+ Pass *createIndependentBlocksPass();
+ Pass *createInterchangePass();
+ Pass *createJSONExporterPass();
+ Pass *createJSONImporterPass();
+ Pass *createRegionSimplifyPass();
+ Pass *createScopInfoPass();
+
+#ifdef OPENSCOP_FOUND
+ Pass *createScopExporterPass();
+ Pass *createScopImporterPass();
+#endif
+
+#ifdef SCOPLIB_FOUND
+ Pass *createPoccPass();
+ Pass *createScopLibExporterPass();
+ Pass *createScopLibImporterPass();
+#endif
+
+ extern char &IndependentBlocksID;
+ extern char &CodePreperationID;
+}
+
+using namespace polly;
+
+namespace {
+ struct PollyForcePassLinking {
+ PollyForcePassLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ createAffSCEVItTesterPass();
+ createCloogExporterPass();
+ createCloogInfoPass();
+ createCodeGenerationPass();
+ createCodePreperationPass();
+ createDependencesPass();
+ createDOTOnlyPrinterPass();
+ createDOTOnlyViewerPass();
+ createDOTPrinterPass();
+ createDOTViewerPass();
+ createIndependentBlocksPass();
+ createInterchangePass();
+ createJSONExporterPass();
+ createJSONImporterPass();
+ createRegionSimplifyPass();
+ createScopInfoPass();
+
+#ifdef OPENSCOP_FOUND
+ createScopExporterPass();
+ createScopImporterPass();
+#endif
+#ifdef SCOPLIB_FOUND
+ createPoccPass();
+ createScopLibExporterPass();
+ createScopLibImporterPass();
+#endif
+
+ }
+ } PollyForcePassLinking; // Force link by creating a global definition.
+}
+
+#endif
--- /dev/null
+//===- MayAliasSet.h - May-alias Set for Base Pointers ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines two classes: MayAliasSet and MayAliasSetInfo.
+// MayAliasSet contains the base pointers of access functions in SCoP that
+// may/must alias each others. And MayAliasSetInfo will compute and hold these
+// MayAliasSets in every SCoP in a function.
+//
+// The difference between MayAliasSet and the original LLVM AliasSet is that
+// the LLVM AliasSets are disjoint, but MayAliasSets are not.
+//
+// Suppose we have the following LLVM IR:
+// define void @f(i32* noalias nocapture %a, i32* noalias nocapture %b)nounwind{
+// bb.nph:
+// %0 = tail call i32 (...)* @rnd() nounwind
+// %1 = icmp eq i32 %0, 0
+// %ptr0 = select i1 %1, i32* %b, i32* %a
+// %2 = load i32* %ptr0, align 4
+// %3 = load i32* %a, align 4
+// %4 = load i32* %b, align 4
+// ret void
+// }
+//
+// The LLVM AliasSetTracker constructs only one LLVM AliasSet that contains
+// ptr0, a and b, but MayAliasSetInfo is supposed to build two MayAliasSets:
+// {a, ptr0} and {b, ptr0}.
+//
+// Take the above LLVM IR for example, the MayAliasSetInfo builds two set:
+// A: {a, ptr0} and B: {b, ptr0} and constructs base pointer to MayAliasSet
+// mapping like:
+// a -> A
+// b -> B
+// ptr0 -> A, B
+//
+// After that, SCoPInfo pass will build a access function for each MayAliasSet,
+// so "%2 = load i32* %ptr0, align 4" will be translated to "read A" and
+// "read B", while "%3 = load i32* %a, align 4" will be translated to "read A",
+// and "%4 = load i32* %b, align 4" will be translated to "read B". This means
+// we can treat the MayAliasSet as the identifier of the virtual array of memory
+// access in SCoPs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_MAY_ALIAS_SET_H
+#define POLLY_MAY_ALIAS_SET_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Allocator.h"
+#include <map>
+
+namespace llvm {
+ class Value;
+ class AliasAnalysis;
+ class raw_ostream;
+}
+
+using namespace llvm;
+
+namespace polly {
+class MayAliasSetInfo;
+class TempScop;
+
+//===----------------------------------------------------------------------===//
+/// @brief MayAliasSet of pointers in SCoPs.
+///
+/// Note: Pointers in MayAliasSet only must-alias with each other now.
+class MayAliasSet {
+ // DO NOT IMPLEMENT
+ MayAliasSet(const MayAliasSet &);
+ // DO NOT IMPLEMENT
+ const MayAliasSet &operator=(const MayAliasSet &);
+
+ // TODO: Use CallbackVH to update the set when some base pointers are deleted
+ // by some pass.
+ SmallPtrSet<const Value*, 8> MustAliasPtrs;
+
+ MayAliasSet() {}
+
+ friend class MayAliasSetInfo;
+public:
+
+ /// @name Must Alias Pointer Iterators
+ ///
+ /// These iterators iterate over all must alias pointers in the set.
+ //@{
+ typedef SmallPtrSetIterator<const Value*> const_iterator;
+ const_iterator mustalias_begin() const { return MustAliasPtrs.begin(); }
+ const_iterator mustalias_end() const { return MustAliasPtrs.end(); }
+ //@}
+
+ /// @brief Add a must alias pointer to this set.
+ ///
+ /// @param V The pointer to add.
+ void addMustAliasPtr(const Value* V) { MustAliasPtrs.insert(V); }
+
+ void print(raw_ostream &OS) const;
+ void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Compute and manage the may-alias sets in a TempSCoP or SCoP.
+class MayAliasSetInfo {
+ // DO NOT IMPLEMENT
+ MayAliasSetInfo(const MayAliasSetInfo &);
+ // DO NOT IMPLEMENT
+ const MayAliasSetInfo &operator=(const MayAliasSetInfo &);
+
+ SpecificBumpPtrAllocator<MayAliasSet> MayASAllocator;
+
+ // Mapping the pointers to their may-alias sets.
+ typedef std::multimap<const Value*, MayAliasSet*> MayAliasSetMapType;
+ MayAliasSetMapType BasePtrMap;
+
+public:
+ MayAliasSetInfo() {}
+
+ /// @name MayAliasSet Iterators
+ ///
+ /// These iterators iterate over all may-alias sets referring to a base
+ /// pointer.
+ //@{
+ typedef MayAliasSetMapType::iterator alias_iterator;
+ typedef MayAliasSetMapType::const_iterator const_alias_iterator;
+
+ alias_iterator alias_begin(const Value *BasePtr) {
+ return BasePtrMap.lower_bound(BasePtr);
+ }
+
+ alias_iterator alias_end(const Value *BasePtr) {
+ return BasePtrMap.upper_bound(BasePtr);
+ }
+
+ const_alias_iterator alias_begin(const Value *BasePtr) const {
+ return BasePtrMap.lower_bound(BasePtr);
+ }
+
+ const_alias_iterator alias_end(const Value *BasePtr) const {
+ return BasePtrMap.upper_bound(BasePtr);
+ }
+ //@}
+
+
+ /// @brief Build MayAliasSets in a SCoP.
+ ///
+ /// @param Scop The SCoP to build MayAliasSets in.
+ /// @param AA The AliasAnalaysis provides the alias information.
+ void buildMayAliasSets(TempScop &Scop, AliasAnalysis &AA);
+};
+}
+
+#endif
--- /dev/null
+//===--- ScopDetection.h - Detect Scops -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Detect the maximal Scops of a function.
+//
+// A static control part (Scop) is a subgraph of the control flow graph (CFG)
+// that only has statically known control flow and can therefore be described
+// within the polyhedral model.
+//
+// Every Scop fullfills these restrictions:
+//
+// * It is a single entry single exit region
+//
+// * Only affine linear bounds in the loops
+//
+// Every natural loop in a Scop must have a number of loop iterations that can
+// be described as an affine linear function in surrounding loop iterators or
+// parameters. (A parameter is a scalar that does not change its value during
+// execution of the Scop).
+//
+// * Only comparisons of affine linear expressions in conditions
+//
+// * All loops and conditions perfectly nested
+//
+// The control flow needs to be structured such that it could be written using
+// just 'for' and 'if' statements, without the need for any 'goto', 'break' or
+// 'continue'.
+//
+// * Side effect free functions call
+//
+// Only function calls and intrinsics that do not have side effects are allowed
+// (readnone).
+//
+// The Scop detection finds the largest Scops by checking if the largest
+// region is a Scop. If this is not the case, its canonical subregions are
+// checked until a region is a Scop. It is now tried to extend this Scop by
+// creating a larger non canonical region.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCOP_DETECTION_H
+#define POLLY_SCOP_DETECTION_H
+
+#include "llvm/Pass.h"
+#include "llvm/Analysis/AliasSetTracker.h"
+
+#include <set>
+
+using namespace llvm;
+
+namespace llvm {
+ class RegionInfo;
+ class Region;
+ class LoopInfo;
+ class Loop;
+ class ScalarEvolution;
+ class SCEV;
+ class SCEVAddRecExpr;
+ class CallInst;
+ class Instruction;
+ class AliasAnalysis;
+ class Value;
+}
+
+namespace polly {
+typedef std::set<const SCEV*> ParamSetType;
+
+//===----------------------------------------------------------------------===//
+/// @brief Pass to detect the maximal static control parts (Scops) of a
+/// function.
+class ScopDetection : public FunctionPass {
+ //===--------------------------------------------------------------------===//
+ // DO NOT IMPLEMENT
+ ScopDetection(const ScopDetection &);
+ // DO NOT IMPLEMENT
+ const ScopDetection &operator=(const ScopDetection &);
+
+ /// @brief Analysis passes used.
+ //@{
+ ScalarEvolution* SE;
+ LoopInfo *LI;
+ RegionInfo *RI;
+ AliasAnalysis *AA;
+ //@}
+
+ /// @brief Context variables for SCoP detection.
+ struct DetectionContext {
+ Region &CurRegion; // The region to check.
+ AliasSetTracker AST; // The AliasSetTracker to hold the alias information.
+ bool Verifying; // If we are in the verification phase?
+ DetectionContext(Region &R, AliasAnalysis &AA, bool Verify)
+ : CurRegion(R), AST(AA), Verifying(Verify) {}
+ };
+
+ // Remember the valid regions
+ typedef std::set<const Region*> RegionSet;
+ RegionSet ValidRegions;
+
+ // Try to expand the region R. If R can be expanded return the expanded
+ // region, NULL otherwise.
+ Region *expandRegion(Region &R);
+
+ // Find the Scops in this region tree.
+ void findScops(Region &R);
+
+ /// @brief Check if all basic block in the region are valid.
+ ///
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if all blocks in R are valid, false otherwise.
+ bool allBlocksValid(DetectionContext &Context) const;
+
+ /// @brief Check the exit block of a region is valid.
+ ///
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if the exit of R is valid, false otherwise.
+ bool isValidExit(DetectionContext &Context) const;
+
+ /// @brief Check if a region is a Scop.
+ ///
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if R is a Scop, false otherwise.
+ bool isValidRegion(DetectionContext &Context) const;
+
+ /// @brief Check if a call instruction can be part of a Scop.
+ ///
+ /// @param CI The call instruction to check.
+ /// @return True if the call instruction is valid, false otherwise.
+ static bool isValidCallInst(CallInst &CI);
+
+ /// @brief Check if a memory access can be part of a Scop.
+ ///
+ /// @param Inst The instruction accessing the memory.
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if the memory access is valid, false otherwise.
+ bool isValidMemoryAccess(Instruction &Inst, DetectionContext &Context) const;
+
+ /// @brief Check if an instruction has any non trivial scalar dependencies
+ /// as part of a Scop.
+ ///
+ /// @param Inst The instruction to check.
+ /// @param RefRegion The region in respect to which we check the access
+ /// function.
+ ///
+ /// @return True if the instruction has scalar dependences, false otherwise.
+ bool hasScalarDependency(Instruction &Inst, Region &RefRegion) const;
+
+ /// @brief Check if an instruction can be part of a Scop.
+ ///
+ /// @param Inst The instruction to check.
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if the instruction is valid, false otherwise.
+ bool isValidInstruction(Instruction &I, DetectionContext &Context) const;
+
+ /// @brief Check if the BB can be part of a Scop.
+ ///
+ /// @param BB The basic block to check.
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if the basic block is valid, false otherwise.
+ bool isValidBasicBlock(BasicBlock &BB, DetectionContext &Context) const;
+
+ /// @brief Check if the control flow in a basic block is valid.
+ ///
+ /// @param BB The BB to check the control flow.
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if the BB contains only valid control flow.
+ bool isValidCFG(BasicBlock &BB, DetectionContext &Context) const;
+
+ /// @brief Check if the SCEV expression is a valid affine function
+ ///
+ /// @param S The SCEV expression to be checked
+ /// @param RefRegion The reference scope to check SCEV, it help to find out
+ /// induction variables and parameters
+ /// @param BasePtr If S represents a memory access, BasePtr should contain
+ /// a valid memory location to which the base address of the
+ /// memory access will be stored.
+ ///
+ /// @return True if the SCEV expression is affine, false otherwise
+ ///
+ bool isValidAffineFunction(const SCEV *S, Region &RefRegion,
+ Value **BasePtr = 0) const;
+
+ /// @brief Is a loop valid with respect to a given region.
+ ///
+ /// @param L The loop to check.
+ /// @param Context The context of scop detection.
+ ///
+ /// @return True if the loop is valid in the region.
+ bool isValidLoop(Loop *L, DetectionContext &Context) const;
+
+ /// @brief Check if a function is an OpenMP subfunction.
+ ///
+ /// An OpenMP subfunction is not valid for Scop detection.
+ ///
+ /// @param F The function to check.
+ ///
+ /// @return True if the function is not an OpenMP subfunction.
+ bool isValidFunction(llvm::Function &F);
+
+public:
+ static char ID;
+ explicit ScopDetection() : FunctionPass(ID) {}
+
+ /// @brief Get the RegionInfo stored in this pass.
+ ///
+ /// This was added to give the DOT printer easy access to this information.
+ RegionInfo *getRI() const { return RI; }
+
+ /// @brief Is the region is the maximum region of a Scop?
+ ///
+ /// @param R The Region to test if it is maximum.
+ ///
+ /// @return Return true if R is the maximum Region in a Scop, false otherwise.
+ bool isMaxRegionInScop(const Region &R) const;
+
+ /// @name Maximum Region In Scops Iterators
+ ///
+ /// These iterators iterator over all maximum region in Scops of this
+ /// function.
+ //@{
+ typedef RegionSet::iterator iterator;
+ typedef RegionSet::const_iterator const_iterator;
+
+ iterator begin() { return ValidRegions.begin(); }
+ iterator end() { return ValidRegions.end(); }
+
+ const_iterator begin() const { return ValidRegions.begin(); }
+ const_iterator end() const { return ValidRegions.end(); }
+ //@}
+
+ /// @brief Remove a region and its children from valid region set.
+ ///
+ /// @param R The region to remove.
+ void forgetScop(const Region &R) {
+ assert(isMaxRegionInScop(R) && "R is not a Scop!");
+ ValidRegions.erase(&R);
+ }
+
+ /// @brief Verify if all valid Regions in this Function are still valid
+ /// after some transformations.
+ void verifyAnalysis() const;
+
+ /// @brief Verify if R is still a valid part of Scop after some
+ /// transformations.
+ ///
+ /// @param R The Region to verify.
+ void verifyRegion(const Region &R) const;
+
+ /// @name FunctionPass interface
+ //@{
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+ virtual bool runOnFunction(Function &F);
+ virtual void print(raw_ostream &OS, const Module *) const;
+ //@}
+};
+
+} //end namespace polly
+
+#endif
--- /dev/null
+//===------ polly/ScopInfo.h - Create Scops from LLVM IR --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Create a polyhedral description for a static control flow region.
+//
+// The pass creates a polyhedral description of the Scops detected by the Scop
+// detection derived from their LLVM-IR code.
+//
+// This represantation is shared among several tools in the polyhedral
+// community, which are e.g. CLooG, Pluto, Loopo, Graphite.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCOP_INFO_H
+#define POLLY_SCOP_INFO_H
+
+#include "llvm/Analysis/RegionPass.h"
+
+using namespace llvm;
+
+namespace llvm {
+ class SCEV;
+ class ScalarEvolution;
+ class SCEVAddRecExpr;
+ class Loop;
+ class LoopInfo;
+ class Type;
+ class PHINode;
+}
+
+struct isl_map;
+struct isl_basic_map;
+struct isl_set;
+struct isl_ctx;
+struct isl_dim;
+struct isl_constraint;
+
+namespace polly {
+
+class Scop;
+class ScopStmt;
+class ScopInfo;
+class TempScop;
+class SCEVAffFunc;
+class Comparison;
+
+//===----------------------------------------------------------------------===//
+/// @brief Represent memory accesses in statements.
+class MemoryAccess {
+ // DO NOT IMPLEMENT
+ MemoryAccess(const MemoryAccess &);
+ // DO NOT IMPLEMENT
+ const MemoryAccess &operator=(const MemoryAccess &);
+
+public:
+ /// @brief The access type of a memory access
+ ///
+ /// There are three kind of access types:
+ ///
+ /// * A read access
+ ///
+ /// A certain set of memory locations are read and may be used for internal
+ /// calculations.
+ ///
+ /// * A write access
+ ///
+ /// A certain set of memory locactions is definitely written. The old value is
+ /// replaced by a newly calculated value. The old value is not read or used at
+ /// all.
+ ///
+ /// * A may write access
+ ///
+ /// A certain set of memory locactions may be written. The memory location may
+ /// contain a new value if there is actually a write or the old value may
+ /// remain, if no write happens.
+ enum AccessType {
+ Read,
+ Write,
+ MayWrite
+ };
+
+private:
+ isl_map *AccessRelation;
+ enum AccessType Type;
+
+ const Value* BaseAddr;
+ std::string BaseName;
+ isl_basic_map *createBasicAccessMap(ScopStmt *Statement);
+ void setBaseName();
+ ScopStmt *statement;
+
+public:
+ // @brief Create an affine memory access.
+ //
+ // @param AffFunc The access function.
+ // @param Statement The Statement that contains this access.
+ // @param SE The ScalarEvolution analysis.
+ MemoryAccess(const SCEVAffFunc &AffFunc, ScopStmt *Statement);
+
+ // @brief Create a read all access.
+ //
+ // @param BaseAddress The base address of the memory accessed.
+ // @param Statement The Statement that contains this access.
+ MemoryAccess(const Value *BaseAddress, ScopStmt *Statement);
+
+ ~MemoryAccess();
+
+ /// @brief Is this a read memory access?
+ bool isRead() const { return Type == MemoryAccess::Read; }
+
+ isl_map *getAccessFunction() { return AccessRelation; }
+ isl_map *getAccessFunction() const { return AccessRelation; }
+
+ /// @brief Get an isl string representing this access function.
+ std::string getAccessFunctionStr() const;
+
+ const Value *getBaseAddr() const {
+ return BaseAddr;
+ }
+
+ const std::string &getBaseName() const {
+ return BaseName;
+ }
+
+ /// @brief Get the stride of this memory access in the specified domain
+ /// subset.
+ isl_set *getStride(const isl_set *domainSubset) const;
+
+ /// @brief Is consecutive memory accessed for a given
+ /// statement instance set?
+ bool isStrideOne(const isl_set *domainSubset) const;
+
+ /// @brief Is always the same memory accessed for a given
+ /// statement instance set?
+ bool isStrideZero(const isl_set *domainSubset) const;
+
+ /// @brief Get the statement that contains this memory access.
+ ScopStmt *getStatement() const { return statement; }
+
+ /// @brief Print the MemoryAccess.
+ ///
+ /// @param OS The output stream the MemoryAccess is printed to.
+ void print(raw_ostream &OS) const;
+
+ /// @brief Print the MemoryAccess to stderr.
+ void dump() const;
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Statement of the Scop
+///
+/// A Scop statement represents an instruction in the Scop.
+///
+/// It is further described by its iteration domain, its schedule and its data
+/// accesses.
+/// At the moment every statement represents a single basic block of LLVM-IR.
+class ScopStmt {
+ //===-------------------------------------------------------------------===//
+ // DO NOT IMPLEMENT
+ ScopStmt(const ScopStmt &);
+ // DO NOT IMPLEMENT
+ const ScopStmt &operator=(const ScopStmt &);
+
+
+ /// Polyhedral description
+ //@{
+
+ /// The Scop containing this ScopStmt
+ Scop &Parent;
+
+ /// The iteration domain describes the set of iterations for which this
+ /// statement is executed.
+ ///
+ /// Example:
+ /// for (i = 0; i < 100 + b; ++i)
+ /// for (j = 0; j < i; ++j)
+ /// S(i,j);
+ ///
+ /// 'S' is executed for different values of i and j. A vector of all
+ /// induction variables around S (i, j) is called iteration vector.
+ /// The domain describes the set of possible iteration vectors.
+ ///
+ /// In this case it is:
+ ///
+ /// Domain: 0 <= i <= 100 + b
+ /// 0 <= j <= i
+ ///
+ /// A pair of statment and iteration vector (S, (5,3)) is called statment
+ /// instance.
+ isl_set *Domain;
+
+ /// The scattering map describes the execution order of the statement
+ /// instances.
+ ///
+ /// A statement and its iteration domain do not give any information about the
+ /// order in time in which the different statement instances are executed.
+ /// This information is provided by the scattering.
+ ///
+ /// The scattering maps every instance of each statement into a multi
+ /// dimensional scattering space. This space can be seen as a multi
+ /// dimensional clock.
+ ///
+ /// Example:
+ ///
+ /// <S,(5,4)> may be mapped to (5,4) by this scattering:
+ ///
+ /// s0 = i (Year of execution)
+ /// s1 = j (Day of execution)
+ ///
+ /// or to (9, 20) by this scattering:
+ ///
+ /// s0 = i + j (Year of execution)
+ /// s1 = 20 (Day of execution)
+ ///
+ /// The order statement instances are executed is defined by the
+ /// scattering vectors they are mapped to. A statement instance
+ /// <A, (i, j, ..)> is executed before a statement instance <B, (i', ..)>, if
+ /// the scattering vector of A is lexicographic smaller than the scattering
+ /// vector of B.
+ isl_map *Scattering;
+
+ /// The memory accesses of this statement.
+ ///
+ /// The only side effects of a statement are its memory accesses.
+ typedef SmallVector<MemoryAccess*, 8> MemoryAccessVec;
+ MemoryAccessVec MemAccs;
+ std::map<const Instruction*, MemoryAccess*> InstructionToAccess;
+
+ //@}
+
+ /// The BasicBlock represented by this statement.
+ BasicBlock *BB;
+
+ /// @brief Whether this statement is a reduction.
+ bool IsReduction;
+
+ /// @brief The loop induction variables surrounding the statement.
+ ///
+ /// This information is only needed for final code generation.
+ std::vector<PHINode*> IVS;
+
+ std::string BaseName;
+
+ /// Build the statment.
+ //@{
+ isl_set *toUpperLoopBound(const SCEVAffFunc &UpperBound, isl_dim *dim,
+ unsigned BoundedDimension) const;
+ isl_set *toConditionSet(const Comparison &Cmp, isl_dim *dim) const;
+ void addConditionsToDomain(TempScop &tempScop, const Region &CurRegion);
+ void buildIterationDomainFromLoops(TempScop &tempScop);
+ void buildIterationDomain(TempScop &tempScop, const Region &CurRegion);
+ void buildScattering(SmallVectorImpl<unsigned> &Scatter);
+ void buildAccesses(TempScop &tempScop, const Region &CurRegion);
+ //@}
+
+ /// Create the ScopStmt from a BasicBlock.
+ ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
+ BasicBlock &bb, SmallVectorImpl<Loop*> &NestLoops,
+ SmallVectorImpl<unsigned> &Scatter);
+
+ /// Create the finalization statement.
+ ScopStmt(Scop &parent, SmallVectorImpl<unsigned> &Scatter);
+
+ friend class Scop;
+public:
+
+ ~ScopStmt();
+
+ /// @brief Get an isl_ctx pointer.
+ isl_ctx *getIslContext();
+
+ /// @brief Get the iteration domain of this ScopStmt.
+ ///
+ /// @return The iteration domain of this ScopStmt.
+ isl_set *getDomain() const { return Domain; }
+
+ /// @brief Get an isl string representing this domain.
+ std::string getDomainStr() const;
+
+ /// @brief Get the scattering function of this ScopStmt.
+ ///
+ /// @return The scattering function of this ScopStmt.
+ isl_map *getScattering() const { return Scattering; }
+ void setScattering(isl_map *scattering) { Scattering = scattering; }
+
+ /// @brief Get an isl string representing this scattering.
+ std::string getScatteringStr() const;
+
+ /// @brief Get the BasicBlock represented by this ScopStmt.
+ ///
+ /// @return The BasicBlock represented by this ScopStmt.
+ BasicBlock *getBasicBlock() const { return BB; }
+
+ MemoryAccess &getAccessFor(const Instruction *Inst) {
+ return *InstructionToAccess[Inst];
+ }
+
+ void setBasicBlock(BasicBlock *Block) { BB = Block; }
+
+ typedef MemoryAccessVec::iterator memacc_iterator;
+ memacc_iterator memacc_begin() { return MemAccs.begin(); }
+ memacc_iterator memacc_end() { return MemAccs.end(); }
+
+ unsigned getNumParams() const;
+ unsigned getNumIterators() const;
+ unsigned getNumScattering() const;
+
+ Scop *getParent() { return &Parent; }
+ const Scop *getParent() const { return &Parent; }
+
+ const char *getBaseName() const;
+ /// @brief Get the induction variable for a dimension.
+ ///
+ /// @param Dimension The dimension of the induction variable
+ /// @return The induction variable at a certain dimension.
+ const PHINode *getInductionVariableForDimension(unsigned Dimension) const;
+
+ /// @brief Return the SCEV for a loop dimension.
+ const SCEVAddRecExpr *getSCEVForDimension(unsigned Dimension) const;
+
+ /// @brief Is this statement the final read statement?
+ ///
+ /// A final read statement is scheduled after all statements to model
+ /// that all data used in the Scop is read after the Scop.
+ bool isFinalRead() { return getBasicBlock() == NULL; }
+
+ bool isReduction() { return IsReduction; }
+
+ /// @brief Print the ScopStmt.
+ ///
+ /// @param OS The output stream the ScopStmt is printed to.
+ void print(raw_ostream &OS) const;
+
+ /// @brief Print the ScopStmt to stderr.
+ void dump() const;
+};
+
+/// @brief Print ScopStmt S to raw_ostream O.
+static inline raw_ostream& operator<<(raw_ostream &O, const ScopStmt &S) {
+ S.print(O);
+ return O;
+}
+
+//===----------------------------------------------------------------------===//
+/// @brief Static Control Part
+///
+/// A Scop is the polyhedral representation of a control flow region detected
+/// by the Scop detection. It is generated by translating the LLVM-IR and
+/// abstracting its effects.
+///
+/// A Scop consists of a set of:
+///
+/// * A set of statements executed in the Scop.
+///
+/// * A set of global parameters
+/// Those parameters are scalar integer values, which are constant during
+/// execution.
+///
+/// * A context
+/// This context contains information about the values the parameters
+/// can take and relations between different parameters.
+class Scop {
+ //===-------------------------------------------------------------------===//
+ // DO NOT IMPLEMENT
+ Scop(const Scop &);
+ // DO NOT IMPLEMENT
+ const Scop &operator=(const Scop &);
+
+ ScalarEvolution *SE;
+
+ /// The underlying Region.
+ Region &R;
+
+ /// Max loop depth.
+ unsigned MaxLoopDepth;
+
+ typedef std::vector<ScopStmt*> StmtSet;
+ /// The Statments in this Scop.
+ StmtSet Stmts;
+
+ /// Parameters of this Scop
+ typedef SmallVector<const SCEV*, 8> ParamVecType;
+ ParamVecType Parameters;
+
+ /// Constraints on parameters.
+ isl_set *Context;
+
+ /// Create the static control part with a region, max loop depth of this
+ /// region and parameters used in this region.
+ Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE);
+
+ /// @brief Check if a basic block is trivial.
+ ///
+ /// A trivial basic block does not contain any useful calculation. Therefore,
+ /// it does not need to be represented as a polyhedral statement.
+ ///
+ /// @param BB The basic block to check
+ /// @param tempScop TempScop returning further information regarding the Scop.
+ ///
+ /// @return True if the basic block is trivial, otherwise false.
+ static bool isTrivialBB(BasicBlock *BB, TempScop &tempScop);
+
+ /// Build the Scop and Statement with precalculate scop information.
+ void buildScop(TempScop &TempScop, const Region &CurRegion,
+ // Loops in Scop containing CurRegion
+ SmallVectorImpl<Loop*> &NestLoops,
+ // The scattering numbers
+ SmallVectorImpl<unsigned> &Scatter,
+ LoopInfo &LI);
+
+ /// Helper function for printing the Scop.
+ void printContext(raw_ostream &OS) const;
+ void printStatements(raw_ostream &OS) const;
+
+ friend class ScopInfo;
+public:
+
+ ~Scop();
+
+ ScalarEvolution *getSE() const;
+
+ /// @brief Get the count of parameters used in this Scop.
+ ///
+ /// @return The count of parameters used in this Scop.
+ inline ParamVecType::size_type getNumParams() const {
+ return Parameters.size();
+ }
+
+ /// @brief Get a set containing the parameters used in this Scop
+ ///
+ /// @return The set containing the parameters used in this Scop.
+ inline const ParamVecType &getParams() const { return Parameters; }
+
+ /// @name Parameter Iterators
+ ///
+ /// These iterators iterate over all parameters of this Scop.
+ //@{
+ typedef ParamVecType::iterator param_iterator;
+ typedef ParamVecType::const_iterator const_param_iterator;
+
+ param_iterator param_begin() { return Parameters.begin(); }
+ param_iterator param_end() { return Parameters.end(); }
+ const_param_iterator param_begin() const { return Parameters.begin(); }
+ const_param_iterator param_end() const { return Parameters.end(); }
+ //@}
+
+ /// @brief Get the maximum region of this static control part.
+ ///
+ /// @return The maximum region of this static control part.
+ inline const Region &getRegion() const { return R; }
+ inline Region &getRegion() { return R; }
+
+ /// @brief Get the maximum depth of the loop.
+ ///
+ /// @return The maximum depth of the loop.
+ inline unsigned getMaxLoopDepth() const { return MaxLoopDepth; }
+
+ /// @brief Get the scattering dimension number of this Scop.
+ ///
+ /// @return The scattering dimension number of this Scop.
+ inline unsigned getScatterDim() const {
+ unsigned maxScatterDim = 0;
+
+ for (const_iterator SI = begin(), SE = end(); SI != SE; ++SI)
+ maxScatterDim = std::max(maxScatterDim, (*SI)->getNumScattering());
+
+ return maxScatterDim;
+ }
+
+ /// @brief Get the name of this Scop.
+ std::string getNameStr() const;
+
+ /// @brief Get the constraint on parameter of this Scop.
+ ///
+ /// @return The constraint on parameter of this Scop.
+ inline isl_set *getContext() const { return Context; }
+
+ /// @brief Get an isl string representing the context.
+ std::string getContextStr() const;
+
+ /// @name Statements Iterators
+ ///
+ /// These iterators iterate over all statements of this Scop.
+ //@{
+ typedef StmtSet::iterator iterator;
+ typedef StmtSet::const_iterator const_iterator;
+
+ iterator begin() { return Stmts.begin(); }
+ iterator end() { return Stmts.end(); }
+ const_iterator begin() const { return Stmts.begin(); }
+ const_iterator end() const { return Stmts.end(); }
+
+ typedef StmtSet::reverse_iterator reverse_iterator;
+ typedef StmtSet::const_reverse_iterator const_reverse_iterator;
+
+ reverse_iterator rbegin() { return Stmts.rbegin(); }
+ reverse_iterator rend() { return Stmts.rend(); }
+ const_reverse_iterator rbegin() const { return Stmts.rbegin(); }
+ const_reverse_iterator rend() const { return Stmts.rend(); }
+ //@}
+
+ /// @brief Print the static control part.
+ ///
+ /// @param OS The output stream the static control part is printed to.
+ void print(raw_ostream &OS) const;
+
+ /// @brief Print the ScopStmt to stderr.
+ void dump() const;
+
+ /// @brief Get the isl context of this static control part.
+ ///
+ /// @return The isl context of this static control part.
+ isl_ctx *getCtx() const;
+};
+
+/// @brief Print Scop scop to raw_ostream O.
+static inline raw_ostream& operator<<(raw_ostream &O, const Scop &scop) {
+ scop.print(O);
+ return O;
+}
+
+//===---------------------------------------------------------------------===//
+/// @brief Build the Polly IR (Scop and ScopStmt) on a Region.
+///
+class ScopInfo : public RegionPass {
+ //===-------------------------------------------------------------------===//
+ // DO NOT IMPLEMENT
+ ScopInfo(const ScopInfo &);
+ // DO NOT IMPLEMENT
+ const ScopInfo &operator=(const ScopInfo &);
+
+ // The Scop
+ Scop *scop;
+
+ void clear() {
+ if (scop) {
+ delete scop;
+ scop = 0;
+ }
+ }
+
+public:
+ static char ID;
+ explicit ScopInfo() : RegionPass(ID), scop(0) {}
+ ~ScopInfo() { clear(); }
+
+ /// @brief Try to build the Polly IR of static control part on the current
+ /// SESE-Region.
+ ///
+ /// @return If the current region is a valid for a static control part,
+ /// return the Polly IR representing this static control part,
+ /// return null otherwise.
+ Scop *getScop() { return scop; }
+ const Scop *getScop() const { return scop; }
+
+ /// @name RegionPass interface
+ //@{
+ virtual bool runOnRegion(Region *R, RGPassManager &RGM);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory() { clear(); }
+ virtual void print(raw_ostream &OS, const Module *) const {
+ if (scop)
+ scop->print(OS);
+ else
+ OS << "Invalid Scop!\n";
+ }
+ //@}
+};
+
+} //end namespace polly
+
+#endif
--- /dev/null
+//===- ScopLib.h - ScopLib interface ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Scoplib interface.
+//
+// The scoplib interface allows to import/export a scop using scoplib.
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCOPLIB_H
+#define POLLY_SCOPLIB_H
+
+#define SCOPLIB_INT_T_IS_MP
+#include "scoplib/scop.h"
+
+#include <map>
+
+namespace llvm {
+ class Value;
+}
+
+struct isl_constraint;
+struct isl_basic_map;
+struct isl_basic_set;
+struct isl_map;
+struct isl_set;
+
+namespace polly {
+ class Dependences;
+ class ScopStmt;
+ class Scop;
+ class ScopLib {
+ Scop *PollyScop;
+ scoplib_scop_p scoplib;
+ Dependences *D;
+
+ std::map<const llvm::Value*, int> ArrayMap;
+
+ void initializeArrays();
+ void initializeParameters();
+ void initializeScattering();
+ void initializeStatements();
+ scoplib_statement_p initializeStatement(ScopStmt *stmt);
+ void freeStatement(scoplib_statement_p stmt);
+ static int accessToMatrix_constraint(isl_constraint *c, void *user);
+ static int accessToMatrix_basic_map(isl_basic_map *bmap, void *user);
+ scoplib_matrix_p createAccessMatrix(ScopStmt *S, bool isRead);
+ static int domainToMatrix_constraint(isl_constraint *c, void *user);
+ static int domainToMatrix_basic_set(isl_basic_set *bset, void *user);
+ scoplib_matrix_p domainToMatrix(isl_set *PS);
+ static int scatteringToMatrix_constraint(isl_constraint *c, void *user);
+ static int scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user);
+ scoplib_matrix_p scatteringToMatrix(isl_map *pmap);
+
+ public:
+ ScopLib(Scop *S);
+ ScopLib(Scop *S, FILE *F, Dependences *D);
+ ~ScopLib();
+ void print(FILE *F);
+ bool updateScattering();
+
+ };
+}
+
+#endif /* POLLY_SCOPLIB_H */
--- /dev/null
+//===--------- ScopPass.h - Pass for Static Control Parts --------*-C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ScopPass class. ScopPasses are just RegionPasses,
+// except they operate on Polly IR (Scop and ScopStmt) built by ScopInfo Pass.
+// Because they operate on Polly IR, not the LLVM IR, ScopPasses are not allowed
+// to modify the LLVM IR. Due to this limitation, the ScopPass class takes
+// care of declaring that no LLVM passes are invalidated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCOP_PASS_H
+#define POLLY_SCOP_PASS_H
+
+#include "llvm/Analysis/RegionPass.h"
+
+using namespace llvm;
+
+struct isl_ctx;
+
+namespace polly {
+class Scop;
+
+/// ScopPass - This class adapts the RegionPass interface to allow convenient
+/// creation of passes that operate on the Polly IR. Instead of overriding
+/// runOnRegion, subclasses override runOnScop.
+class ScopPass : public RegionPass {
+ Scop *S;
+protected:
+ explicit ScopPass(char &ID) : RegionPass(ID), S(0) {}
+
+ /// runOnScop - This method must be overloaded to perform the
+ /// desired Polyhedral transformation or analysis.
+ ///
+ virtual bool runOnScop(Scop &S) = 0;
+
+ /// getAnalysisUsage - Subclasses that override getAnalysisUsage
+ /// must call this.
+ ///
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+public:
+ /// getIslContext - Get the isl_ctx of current SCoP.
+ isl_ctx *getIslContext();
+
+ Scop &getCurScop() const {
+ assert(S && "Not on a Scop!");
+ return *S;
+ }
+private:
+ virtual bool runOnRegion(Region *R, RGPassManager &RGM);
+ void print(raw_ostream &OS, const Module *) const;
+ virtual void printScop(raw_ostream &OS) const {}
+};
+
+} // End llvm namespace
+
+#endif
--- /dev/null
+//===-- AffineSCEVIterator.h - Iterate the SCEV in an affine way -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The iterator can be used to iterate over the affine component of the SCEV
+// expression.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef AFFINE_SCEV_ITERATOR_H
+#define AFFINE_SCEV_ITERATOR_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+
+#include <map>
+
+#include "llvm/ADT/SmallVector.h"
+
+using namespace llvm;
+
+namespace polly {
+
+/// @brief The itertor transform the scalar expressions to the form of sum of
+/// (constant * varialbe)s, and return the variable/constant pairs one by one
+/// on the fly.
+///
+/// For example, we can write SCEV:
+/// {{%x,+,sizeof(i32)}<%bb2.preheader>,+,(4 * sizeof(i32))}<%bb1>
+/// in affine form:
+/// (4 * sizeof(i32)) * %indvar + sizeof(i32) * %0 + 1 * %x + 0 * 1
+/// so we can get the follow pair from the iterator:
+/// {%indvar, (4 * sizeof(i32))}, {%0, sizeof(i32)}, {%x, 1} and {1, 0}
+/// where %indvar is the induction variable of loop %bb1 and %0 is the induction
+/// variable of loop %bb2.preheader.
+///
+/// In the returned pair,
+/// The "first" field is the variable part, the "second" field constant part.
+/// And the translation part of the expression will always return last.
+///
+class AffineSCEVIterator : public std::iterator<std::forward_iterator_tag,
+ std::pair<const SCEV*, const SCEV*>, ptrdiff_t>,
+ SCEVVisitor<AffineSCEVIterator,
+ std::pair<const SCEV*, const SCEV*> >
+ {
+ typedef std::iterator<std::forward_iterator_tag,
+ std::pair<const SCEV*, const SCEV*>, ptrdiff_t> super;
+
+ friend struct llvm::SCEVVisitor<AffineSCEVIterator,
+ std::pair<const SCEV*, const SCEV*> >;
+
+ ScalarEvolution *SE;
+public:
+ typedef super::value_type value_type;
+ typedef super::pointer ptr_type;
+ typedef AffineSCEVIterator Self;
+private:
+ typedef SCEVNAryExpr::op_iterator scev_op_it;
+
+ // The stack help us remember the SCEVs that not visit yet.
+ SmallVector<const SCEV*, 8> visitStack;
+
+ // The current value of this iterator.
+ value_type val;
+
+ const SCEVConstant* getSCEVOne(const SCEV* S) const {
+ return cast<SCEVConstant>(SE->getConstant(S->getType(), 1));
+ }
+
+ //===-------------------------------------------------------------------===//
+ /// Functions for SCEVVisitor.
+ ///
+ /// These function compute the constant part and variable part of the SCEV,
+ /// and return them in a std::pair, where the first field is the variable,
+ /// and the second field is the constant.
+ ///
+ value_type visitConstant(const SCEVConstant *S) {
+ return std::make_pair(getSCEVOne(S), S);
+ }
+
+ value_type visitUnknown(const SCEVUnknown* S) {
+ const Type *AllocTy;
+ Constant *FieldNo;
+ // We treat these as constant.
+ if (S->isSizeOf (AllocTy) ||
+ S->isAlignOf (AllocTy) ||
+ S->isOffsetOf(AllocTy, FieldNo))
+ return std::make_pair(getSCEVOne(S), S);
+
+ return std::make_pair(S, getSCEVOne(S));
+ }
+
+ value_type visitMulExpr(const SCEVMulExpr* S) {
+ SmallVector<const SCEV*, 4> Coeffs, Variables;
+
+ // Do not worry about the Constant * Variable * (Variable + Variable)
+ // MulExpr, we will never get a affine expression from it, so we just
+ // leave it there.
+ for (scev_op_it I = S->op_begin(), E = S->op_end(); I != E; ++I) {
+ // Get the constant part and the variable part of each operand.
+ value_type res = visit(*I);
+
+ Coeffs.push_back(res.second);
+ Variables.push_back(res.first);
+ }
+
+ // Get the constant part and variable part of this MulExpr by
+ // multiply them together.
+ const SCEV *Coeff = SE->getMulExpr(Coeffs);
+ // There maybe "sizeof" and others.
+ // TODO: Assert the allowed coeff type.
+ // assert(Coeff && "Expect Coeff to be a const!");
+
+ const SCEV *Var = SE->getMulExpr(Variables);
+
+ return std::make_pair(Var, Coeff);
+ }
+
+ value_type visitCastExpr(const SCEVCastExpr *S) {
+ return std::make_pair(S, getSCEVOne(S));
+ }
+
+ value_type visitTruncateExpr(const SCEVTruncateExpr *S) {
+ return visitCastExpr(S);
+ }
+
+ value_type visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
+ return visitCastExpr(S);
+ }
+
+ value_type visitSignExtendExpr(const SCEVSignExtendExpr *S) {
+ return visitCastExpr(S);
+ }
+
+ value_type visitAddExpr(const SCEVAddExpr *S) {
+ // AddExpr will handled out in visit Next;
+ return std::make_pair(S, getSCEVOne(S));
+ }
+
+ value_type visitAddRecExpr(const SCEVAddRecExpr *S) {
+ // AddRecExpr will handled out in visit Next;
+ return std::make_pair(S, getSCEVOne(S));
+ }
+
+ value_type visitUDivExpr(const SCEVUDivExpr *S) {
+ return std::make_pair(S, getSCEVOne(S));
+ }
+
+ value_type visitSMaxExpr(const SCEVSMaxExpr *S) {
+ return std::make_pair(S, getSCEVOne(S));
+ }
+
+ value_type visitUMaxExpr(const SCEVUMaxExpr *S) {
+ return std::make_pair(S, getSCEVOne(S));
+ }
+
+ /// Get the next {variable, constant} pair of the SCEV.
+ value_type visitNext() {
+ value_type ret(0, 0);
+
+ if (visitStack.empty())
+ return ret;
+ const SCEV* nextS = visitStack.back();
+
+ if (const SCEVAddRecExpr *ARec = dyn_cast<SCEVAddRecExpr>(nextS)){
+ // Visiting the AddRec, check if its Affine;
+ PHINode *IV = ARec->getLoop()->getCanonicalInductionVariable();
+ // Only decompose the AddRec, if the loop has a canonical induction
+ // variable.
+ if (ARec->isAffine() && IV != 0) {
+ ret = visit(ARec->getStepRecurrence(*SE));
+ if (isa<SCEVConstant>(ret.first)) { // If the step is constant.
+ const SCEV *Start = ARec->getStart();
+ visitStack.back() = Start;
+
+ // The AddRec is expect to be decomposed to
+ //
+ // | start + step * {1, +, 1}<loop>
+ //
+ // Now we get the {1, +, 1}<loop> part.
+ ret.first = SE->getSCEV(IV);
+
+ // Push CouldNotCompute to take the place.
+ visitStack.push_back(SE->getCouldNotCompute());
+
+ return ret;
+ }
+ // The step is not a constant. Then this AddRec is not Affine or
+ // no canonical induction variable found.
+ // Fall through.
+ }
+ }
+
+ // Get the constant part and variable part of the SCEV.
+ ret = visit(nextS);
+
+ // If the reach the last constant
+ if (isa<SCEVConstant>(ret.first) && (visitStack.size() != 1)) {
+ // Else, merge all constant component, we will output it at last.
+ visitStack.front() = SE->getAddExpr(visitStack.front(), ret.second);
+ //assert(isa<SCEVConstant>(visitStack.front().first));
+ // Pop the top constant, because it already merged into the bottom of the Stack
+ // and output it last.
+ visitStack.pop_back();
+ // Try again.
+ return visitNext();
+ }
+ // Not a constant or Stack not empty
+ // If ret is in (xxx) * AddExpr form, we will decompose the AddExpr
+ else if (const SCEVAddExpr *AddExpr = dyn_cast<SCEVAddExpr>(ret.first)) {
+ // Pop the current SCEV, we will decompose it.
+ visitStack.pop_back();
+ assert(AddExpr->getNumOperands() && "AddExpr without operand?");
+ for (scev_op_it I = AddExpr->op_begin(), E = AddExpr->op_end(); I != E; ++I){
+ visitStack.push_back(SE->getMulExpr(ret.second, *I));
+ }
+ // Try again with the new SCEV.
+ return visitNext();
+ }
+
+ return ret;
+ }
+
+public:
+
+ /// @brief Create the iterator from a SCEV and the ScalarEvolution analysis.
+ AffineSCEVIterator(const SCEV* S, ScalarEvolution *se ) : SE(se) {
+ // Dont iterate CouldNotCompute.
+ if (isa<SCEVCouldNotCompute>(S))
+ return;
+
+ const Type *Ty = S->getType();
+
+ // Init the constant component.
+ visitStack.push_back(SE->getConstant(Ty, 0));
+
+ // Get the first affine component.
+ visitStack.push_back(S);
+ val = visitNext();
+ }
+
+ /// @brief Create an end iterator.
+ inline AffineSCEVIterator() {}
+
+ inline bool operator==(const Self& x) const {
+ return visitStack == x.visitStack;
+ }
+ inline bool operator!=(const Self& x) const { return !operator==(x); }
+
+ /// @brief Return the current (constant * variable) component of the SCEV.
+ ///
+ /// @return The "first" field of the pair is the variable part,
+ /// the "second" field of the pair is the constant part.
+ inline value_type operator*() const {
+ assert(val.first && val.second && "Cant dereference iterator!");
+ return val;
+ }
+
+ inline const value_type* operator->() const {
+ assert(val.first && val.second && "Cant dereference iterator!");
+ return &val;
+ }
+
+ inline Self& operator++() { // Preincrement
+ assert(!visitStack.empty() && "Cant ++ iterator!");
+ // Pop the last SCEV.
+ visitStack.pop_back();
+ val = visitNext();
+ return *this;
+ }
+
+ inline Self operator++(int) { // Postincrement
+ Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+inline static AffineSCEVIterator affine_begin(const SCEV* S, ScalarEvolution *SE) {
+ return AffineSCEVIterator(S, SE);
+}
+
+inline static AffineSCEVIterator affine_end() {
+ return AffineSCEVIterator();
+}
+
+} // end namespace polly
+#endif
--- /dev/null
+//===- Support/GICHelper.h -- Helper functions for GMP, ISL, and Cloog -----===/
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Helper functions for gmp, isl and Cloog objects.
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef POLLY_SUPPORT_GIC_HELPER_H
+#define POLLY_SUPPORT_GIC_HELPER_H
+
+#include "llvm/ADT/APInt.h"
+#include <gmp.h>
+
+struct isl_map;
+struct isl_union_map;
+struct isl_set;
+struct isl_union_set;
+
+namespace polly {
+
+/// @brief Convert APInt to mpz.
+///
+/// @param v The mpz_t object your want to hold the result.
+/// @param apint The APInt you want to convert.
+void MPZ_from_APInt (mpz_t v, const llvm::APInt apint, bool is_signed = true);
+
+/// @brief Convert mpz to APInt.
+///
+/// @param mpz The mpz_t you want to convert.
+llvm::APInt APInt_from_MPZ (const mpz_t mpz);
+
+/// @brief Get c++ string from Isl objects.
+//@{
+std::string stringFromIslObj(/*__isl_keep*/ isl_map *map);
+std::string stringFromIslObj(/*__isl_keep*/ isl_union_map *umap);
+std::string stringFromIslObj(/*__isl_keep*/ isl_set *set);
+std::string stringFromIslObj(/*__isl_keep*/ isl_union_set *uset);
+//@}
+} //end namespace polly
+
+#endif
--- /dev/null
+//===------ Support/ScopHelper.h -- Some Helper Functions for Scop. --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Small functions that help with LLVM-IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SUPPORT_IRHELPER_H
+#define POLLY_SUPPORT_IRHELPER_H
+
+namespace llvm {
+ class Instruction;
+ class LoopInfo;
+ class Loop;
+ class ScalarEvolution;
+ class SCEV;
+ class Value;
+ class PHINode;
+ class Region;
+ class Pass;
+ class BasicBlock;
+}
+
+namespace polly {
+ // Helper function for Scop.
+ //===----------------------------------------------------------------------===//
+ /// Temporary Hack for extended regiontree.
+ ///
+ /// @brief Cast the region to loop.
+ ///
+ /// @param R The Region to be casted.
+ /// @param LI The LoopInfo to help the casting.
+ ///
+ /// @return If there is a a loop that has the same entry and exit as the region,
+ /// return the loop, otherwise, return null.
+ llvm::Loop *castToLoop(const llvm::Region &R, llvm::LoopInfo &LI);
+
+ //===----------------------------------------------------------------------===//
+ // Functions for checking affine functions.
+ bool isInvariant(const llvm::SCEV *S, llvm::Region &R);
+
+ bool isParameter(const llvm::SCEV *Var, llvm::Region &RefRegion,
+ llvm::LoopInfo &LI, llvm::ScalarEvolution &SE);
+
+ bool isIndVar(const llvm::SCEV *Var, llvm::Region &RefRegion,
+ llvm::LoopInfo &LI, llvm::ScalarEvolution &SE);
+
+ /// @brief Check if the instruction I is the induction variable of a loop.
+ ///
+ /// @param I The instruction to check.
+ /// @param LI The LoopInfo analysis.
+ ///
+ /// @return Return true if I is the induction variable of a loop, false
+ /// otherwise.
+ bool isIndVar(const llvm::Instruction *I, const llvm::LoopInfo *LI);
+
+ /// @brief Check if the PHINode has any incoming Invoke edge.
+ ///
+ /// @param PN The PHINode to check.
+ ///
+ /// @return If the PHINode has an incoming BB that jumps to the parent BB
+ /// of the PHINode with an invoke instruction, return true,
+ /// otherwise, return false.
+ bool hasInvokeEdge(const llvm::PHINode *PN);
+
+ llvm::Value *getPointerOperand(llvm::Instruction &Inst);
+
+ // Helper function for LLVM-IR about Scop.
+ llvm::BasicBlock *createSingleEntryEdge(llvm::Region *R, llvm::Pass *P);
+ llvm::BasicBlock *createSingleExitEdge(llvm::Region *R, llvm::Pass *P);
+
+ /// @brief Split the entry block of a function to store the newly inserted
+ /// allocations outside of all Scops.
+ ///
+ /// @param EntryBlock The entry block of the current function.
+ /// @param P The pass that currently running.
+ ///
+ void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P);
+}
+#endif
--- /dev/null
+//===-------- polly/TempScopInfo.h - Extract TempScops ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect information about the control flow regions detected by the Scop
+// detection, such that this information can be translated info its polyhedral
+// representation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_TEMP_SCOP_EXTRACTION_H
+#define POLLY_TEMP_SCOP_EXTRACTION_H
+
+#include "polly/MayAliasSet.h"
+#include "polly/ScopDetection.h"
+
+#include "llvm/Analysis/RegionPass.h"
+#include "llvm/Instructions.h"
+
+namespace llvm {
+ class TargetData;
+}
+
+using namespace llvm;
+
+namespace polly {
+class MayAliasSetInfo;
+
+//===---------------------------------------------------------------------===//
+/// @brief Affine function represent in llvm SCEV expressions.
+///
+/// A helper class for collect affine function information
+class SCEVAffFunc {
+ // Temporary hack
+ friend class TempScopInfo;
+ // The translation component
+ const SCEV *TransComp;
+
+ // { Variable, Coefficient }
+ typedef std::map<const SCEV*, const SCEV*> LnrTransSet;
+ LnrTransSet LnrTrans;
+
+public:
+ // The type of the scev affine function
+ enum SCEVAffFuncType {
+ None = 0,
+ ReadMem, // Or we could call it "Use"
+ WriteMem, // Or define
+ Eq, // == 0
+ Ne, // != 0
+ GE // >= 0
+ };
+
+private:
+ // The base address of the address SCEV, if the Value is a pointer, this is
+ // an array access, otherwise, this is a value access.
+ // And the Write/Read modifier
+ Value *BaseAddr;
+ unsigned ElemBytes : 28;
+ SCEVAffFuncType FuncType : 3;
+ bool has_sign : 1;
+
+public:
+ /// @brief Create a new SCEV affine function.
+ SCEVAffFunc() : TransComp(0), BaseAddr(0), ElemBytes(0), FuncType(None),
+ has_sign(true) {}
+
+ /// @brief Create a new SCEV affine function with memory access type or
+ /// condition type
+
+ explicit SCEVAffFunc(SCEVAffFuncType Type, unsigned elemBytes = 0,
+ Value* baseAddr = 0)
+ : TransComp(0), BaseAddr(baseAddr), ElemBytes(elemBytes),
+ FuncType(Type), has_sign(true) {}
+
+ /// @brief Construct a new SCEVAffFunc from a SCEV
+ ///
+ /// @param S The SCEV that should be translated.
+ /// @param Type The type of this affine function.
+ /// @param R The region in which the affine function is evaluated.
+ /// @param Param A set of parameters, where new parameters found in this
+ /// affine function will be added.
+ /// @param LI A pointer to a current LoopInfo analysis.
+ /// @param SE A pointer to a current ScalarEvolution analysis.
+ SCEVAffFunc(const SCEV *S, SCEVAffFuncType Type, Region &R,
+ ParamSetType &Param, LoopInfo *LI, ScalarEvolution *SE);
+
+ void setUnsigned() {has_sign = false;}
+
+ // getCoeff - Get the Coefficient of a given variable.
+ const SCEV *getCoeff(const SCEV *Var) const {
+ LnrTransSet::const_iterator At = LnrTrans.find(Var);
+ return At == LnrTrans.end() ? 0 : At->second;
+ }
+
+ const SCEV *getTransComp() const {
+ return TransComp;
+ }
+
+ bool isSigned() const { return has_sign; }
+
+ enum SCEVAffFuncType getType() const { return FuncType; }
+
+ bool isDataRef() const {
+ return getType() == ReadMem || getType() == WriteMem;
+ }
+
+ unsigned getElemSizeInBytes() const {
+ assert(isDataRef() && "getElemSizeInBytes on the wrong type!");
+ return ElemBytes;
+ }
+
+ bool isRead() const { return FuncType == ReadMem; }
+
+ const Value *getBaseAddr() const { return BaseAddr; }
+
+ /// @brief Print the affine function.
+ ///
+ /// @param OS The output stream the affine function is printed to.
+ void print(raw_ostream &OS, bool PrintInequality = true) const;
+ void dump() const;
+};
+
+static inline raw_ostream& operator<<(raw_ostream &OS, const SCEVAffFunc &SAF){
+ SAF.print(OS);
+ return OS;
+}
+
+class Comparison {
+
+ SCEVAffFunc *LHS;
+ SCEVAffFunc *RHS;
+
+ ICmpInst::Predicate Pred;
+
+public:
+ Comparison(SCEVAffFunc *lhs, SCEVAffFunc *rhs, ICmpInst::Predicate pred)
+ : LHS(lhs), RHS(rhs), Pred(pred) {}
+
+ SCEVAffFunc *getLHS() const { return LHS; }
+ SCEVAffFunc *getRHS() const { return RHS; }
+
+ ICmpInst::Predicate getPred() const { return Pred; }
+ void print(raw_ostream &OS) const;
+};
+
+//===---------------------------------------------------------------------===//
+/// Types
+// The condition of a Basicblock, combine brcond with "And" operator.
+typedef SmallVector<Comparison, 4> BBCond;
+
+/// Maps from a loop to the affine function expressing its backedge taken count.
+/// The backedge taken count already enough to express iteration domain as we
+/// only allow loops with canonical induction variable.
+/// A canonical induction variable is:
+/// an integer recurrence that starts at 0 and increments by one each time
+/// through the loop.
+typedef std::map<const Loop*, SCEVAffFunc> LoopBoundMapType;
+
+/// Mapping BBs to its condition constrains
+typedef std::map<const BasicBlock*, BBCond> BBCondMapType;
+
+typedef std::vector<std::pair<SCEVAffFunc, Instruction*> > AccFuncSetType;
+typedef std::map<const BasicBlock*, AccFuncSetType> AccFuncMapType;
+
+//===---------------------------------------------------------------------===//
+/// @brief Scop represent with llvm objects.
+///
+/// A helper class for remembering the parameter number and the max depth in
+/// this Scop, and others context.
+class TempScop {
+ // The Region.
+ Region &R;
+
+ // Parameters used in this Scop.
+ ParamSetType Params;
+
+ // The max loop depth of this Scop
+ unsigned MaxLoopDepth;
+
+ // Remember the bounds of loops, to help us build iteration domain of BBs.
+ const LoopBoundMapType &LoopBounds;
+ const BBCondMapType &BBConds;
+
+ // Access function of bbs.
+ const AccFuncMapType &AccFuncMap;
+
+ // The alias information about this SCoP.
+ MayAliasSetInfo *MayASInfo;
+
+ // Basic blocks detected as reductions
+ std::set<BasicBlock*> Reductions;
+
+ friend class TempScopInfo;
+
+ explicit TempScop(Region &r, LoopBoundMapType &loopBounds,
+ BBCondMapType &BBCmps, AccFuncMapType &accFuncMap)
+ : R(r), MaxLoopDepth(0), LoopBounds(loopBounds), BBConds(BBCmps),
+ AccFuncMap(accFuncMap), MayASInfo(new MayAliasSetInfo()) {}
+
+public:
+ ~TempScop();
+
+ bool is_Reduction(BasicBlock &BB) { return Reductions.count(&BB) != 0; }
+
+ /// @name Information about this Temporary Scop.
+ ///
+ //@{
+ /// @brief Get the parameters used in this Scop.
+ ///
+ /// @return The parameters use in region.
+ ParamSetType &getParamSet() { return Params; }
+
+ /// @brief Get the maximum Region contained by this Scop.
+ ///
+ /// @return The maximum Region contained by this Scop.
+ Region &getMaxRegion() const { return R; }
+
+ /// @brief Get the maximum loop depth of Region R.
+ ///
+ /// @return The maximum loop depth of Region R.
+ unsigned getMaxLoopDepth() const { return MaxLoopDepth; }
+
+ /// @brief Get the loop bounds of the given loop.
+ ///
+ /// @param L The loop to get the bounds.
+ ///
+ /// @return The bounds of the loop L in { Lower bound, Upper bound } form.
+ ///
+ const SCEVAffFunc &getLoopBound(const Loop *L) const {
+ LoopBoundMapType::const_iterator at = LoopBounds.find(L);
+ assert(at != LoopBounds.end() && "Only valid loop is allow!");
+ return at->second;
+ }
+
+ /// @brief Get the condition from entry block of the Scop to a BasicBlock
+ ///
+ /// @param BB The BasicBlock
+ ///
+ /// @return The condition from entry block of the Scop to a BB
+ ///
+ const BBCond *getBBCond(const BasicBlock *BB) const {
+ BBCondMapType::const_iterator at = BBConds.find(BB);
+ return at != BBConds.end() ? &(at->second) : 0;
+ }
+
+ /// @brief Get all access functions in a BasicBlock
+ ///
+ /// @param BB The BasicBlock that containing the access functions.
+ ///
+ /// @return All access functions in BB
+ ///
+ const AccFuncSetType *getAccessFunctions(const BasicBlock* BB) const {
+ AccFuncMapType::const_iterator at = AccFuncMap.find(BB);
+ return at != AccFuncMap.end()? &(at->second) : 0;
+ }
+ //@}
+
+ /// @brief Print the Temporary Scop information.
+ ///
+ /// @param OS The output stream the access functions is printed to.
+ /// @param SE The ScalarEvolution that help printing Temporary Scop
+ /// information.
+ /// @param LI The LoopInfo that help printing the access functions.
+ void print(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI) const;
+
+ /// @brief Print the access functions and loop bounds in this Scop.
+ ///
+ /// @param OS The output stream the access functions is printed to.
+ /// @param SE The ScalarEvolution that help printing the access functions.
+ /// @param LI The LoopInfo that help printing the access functions.
+ void printDetail(raw_ostream &OS, ScalarEvolution *SE,
+ LoopInfo *LI, const Region *Reg, unsigned ind) const;
+};
+
+typedef std::map<const Region*, TempScop*> TempScopMapType;
+//===----------------------------------------------------------------------===//
+/// @brief The Function Pass to extract temporary information for Static control
+/// part in llvm function.
+///
+class TempScopInfo : public FunctionPass {
+ //===-------------------------------------------------------------------===//
+ // DO NOT IMPLEMENT
+ TempScopInfo(const TempScopInfo &);
+ // DO NOT IMPLEMENT
+ const TempScopInfo &operator=(const TempScopInfo &);
+
+ // The ScalarEvolution to help building Scop.
+ ScalarEvolution* SE;
+
+ // LoopInfo for information about loops
+ LoopInfo *LI;
+
+ // The AliasAnalysis to build AliasSetTracker.
+ AliasAnalysis *AA;
+
+ // Valid Regions for Scop
+ ScopDetection *SD;
+
+ // For condition extraction support.
+ DominatorTree *DT;
+ PostDominatorTree *PDT;
+
+ // Target data for element size computing.
+ TargetData *TD;
+
+ // Remember the bounds of loops, to help us build iteration domain of BBs.
+ LoopBoundMapType LoopBounds;
+
+ // And also Remember the constrains for BBs
+ BBCondMapType BBConds;
+
+ // Access function of bbs.
+ AccFuncMapType AccFuncMap;
+
+ // Mapping regions to the corresponding Scop in current function.
+ TempScopMapType TempScops;
+
+ // Clear the context.
+ void clear();
+
+ /// @brief Build an affine function from a SCEV expression.
+ ///
+ /// @param S The SCEV expression to be converted to affine
+ /// function.
+ /// @param Scop The Scope of this expression.
+ /// @param FuncToBuild The SCEVAffFunc to hold the result.
+ ///
+ void buildAffineFunction(const SCEV *S, SCEVAffFunc &FuncToBuild,
+ Region &R, ParamSetType &Params) const;
+
+
+ /// @brief Build condition constrains to BBs in a valid Scop.
+ ///
+ /// @param BB The BasicBlock to build condition constrains
+ /// @param RegionEntry The entry block of the Smallest Region that containing
+ /// BB
+ /// @param Cond The built condition
+ void buildCondition(BasicBlock *BB, BasicBlock *Region, TempScop &Scop);
+
+ // Build the affine function of the given condition
+ void buildAffineCondition(Value &V, bool inverted, Comparison **Comp,
+ TempScop &Scop) const;
+
+ // Return the temporary Scop information of Region R, where R must be a valid
+ // part of Scop
+ TempScop *getTempScop(Region &R);
+
+ // Build the temprory information of Region R, where R must be a valid part
+ // of Scop.
+ TempScop *buildTempScop(Region &R);
+
+ bool isReduction(BasicBlock &BB);
+
+ void buildAccessFunctions(Region &RefRegion, ParamSetType &Params,
+ BasicBlock &BB);
+
+ void buildLoopBounds(TempScop &Scop);
+
+public:
+ static char ID;
+ explicit TempScopInfo() : FunctionPass(ID) {}
+ ~TempScopInfo();
+
+ /// @brief Get the temporay Scop information in LLVM IR represent
+ /// for Region R.
+ ///
+ /// @return The Scop information in LLVM IR represent.
+ TempScop *getTempScop(const Region *R) const;
+
+ /// @name FunctionPass interface
+ //@{
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory() { clear(); }
+ virtual bool runOnFunction(Function &F);
+ virtual void print(raw_ostream &OS, const Module *) const;
+ //@}
+};
+
+} // end namespace polly
+
+
+#endif
--- /dev/null
+add_polly_library(PollyAnalysis
+ Dependences.cpp
+ ScopDetection.cpp
+ ScopInfo.cpp
+ ScopGraphPrinter.cpp
+ ScopPass.cpp
+ TempScopInfo.cpp
+)
--- /dev/null
+//===- Dependency.cpp - Calculate dependency information for a Scop. -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Calculate the data dependency relations for a Scop using ISL.
+//
+// The integer set library (ISL) from Sven, has a integrated dependency analysis
+// to calculate data dependences. This pass takes advantage of this and
+// calculate those dependences a Scop.
+//
+// The dependences in this pass are exact in terms that for a specific read
+// statement instance only the last write statement instance is returned. In
+// case of may writes a set of possible write instances is returned. This
+// analysis will never produce redundant dependences.
+//
+//===----------------------------------------------------------------------===//
+//
+#include "polly/Dependences.h"
+
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopInfo.h"
+#include "polly/Support/GICHelper.h"
+
+#define DEBUG_TYPE "polly-dependences"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <isl/flow.h>
+#include <isl/map.h>
+#include <isl/constraint.h>
+
+using namespace polly;
+using namespace llvm;
+
+static cl::opt<bool>
+ LegalityCheckDisabled("disable-polly-legality",
+ cl::desc("Disable polly legality check"), cl::Hidden,
+ cl::init(false));
+
+//===----------------------------------------------------------------------===//
+Dependences::Dependences() : ScopPass(ID) {
+ must_dep = may_dep = NULL;
+ must_no_source = may_no_source = NULL;
+ sink = must_source = may_source = NULL;
+ war_dep = waw_dep = NULL;
+}
+
+bool Dependences::runOnScop(Scop &S) {
+ isl_dim *dim = isl_dim_alloc(S.getCtx(), S.getNumParams(), 0, 0);
+
+ if (sink)
+ isl_union_map_free(sink);
+
+ if (must_source)
+ isl_union_map_free(must_source);
+
+ if (may_source)
+ isl_union_map_free(may_source);
+
+ sink = isl_union_map_empty(isl_dim_copy(dim));
+ must_source = isl_union_map_empty(isl_dim_copy(dim));
+ may_source = isl_union_map_empty(isl_dim_copy(dim));
+ isl_union_map *schedule = isl_union_map_empty(dim);
+
+ if (must_dep)
+ isl_union_map_free(must_dep);
+
+ if (may_dep)
+ isl_union_map_free(may_dep);
+
+ if (must_no_source)
+ isl_union_map_free(must_no_source);
+
+ if (may_no_source)
+ isl_union_map_free(may_no_source);
+
+ if (war_dep)
+ isl_union_map_free(war_dep);
+
+ if (waw_dep)
+ isl_union_map_free(waw_dep);
+
+ must_dep = may_dep = NULL;
+ must_no_source = may_no_source = NULL;
+
+ war_dep = waw_dep = NULL;
+
+ for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ for (ScopStmt::memacc_iterator MI = Stmt->memacc_begin(),
+ ME = Stmt->memacc_end(); MI != ME; ++MI) {
+ isl_set *domcp = isl_set_copy(Stmt->getDomain());
+ isl_map *accdom = isl_map_copy((*MI)->getAccessFunction());
+
+ accdom = isl_map_intersect_domain(accdom, domcp);
+
+ if ((*MI)->isRead())
+ isl_union_map_add_map(sink, accdom);
+ else
+ isl_union_map_add_map(must_source, accdom);
+ }
+ isl_map *scattering = isl_map_copy(Stmt->getScattering());
+ isl_union_map_add_map(schedule, scattering);
+ }
+
+ DEBUG(
+ dbgs().indent(4) << "Sink:\n";
+ dbgs().indent(8) << stringFromIslObj(sink) << "\n";
+
+ dbgs().indent(4) << "MustSource:\n";
+ dbgs().indent(8) << stringFromIslObj(must_source) << "\n";
+
+ dbgs().indent(4) << "MaySource:\n";
+ dbgs().indent(8) << stringFromIslObj(may_source) << "\n";
+
+ dbgs().indent(4) << "Schedule:\n";
+ dbgs().indent(8) << stringFromIslObj(schedule) << "\n";
+ );
+
+ isl_union_map_compute_flow(isl_union_map_copy(sink),
+ isl_union_map_copy(must_source),
+ isl_union_map_copy(may_source),
+ isl_union_map_copy(schedule),
+ &must_dep, &may_dep, &must_no_source,
+ &may_no_source);
+
+ isl_union_map_compute_flow(isl_union_map_copy(must_source),
+ isl_union_map_copy(must_source),
+ isl_union_map_copy(sink), schedule,
+ &waw_dep, &war_dep, NULL, NULL);
+
+ // Remove redundant statements.
+ must_dep = isl_union_map_coalesce(must_dep);
+ may_dep = isl_union_map_coalesce(may_dep);
+ must_no_source = isl_union_map_coalesce(must_no_source);
+ may_no_source = isl_union_map_coalesce(may_no_source);
+ waw_dep = isl_union_map_coalesce(waw_dep);
+ war_dep = isl_union_map_coalesce(war_dep);
+
+ return false;
+}
+
+bool Dependences::isValidScattering(StatementToIslMapTy *NewScattering) {
+ Scop &S = getCurScop();
+
+ if (LegalityCheckDisabled)
+ return true;
+
+ isl_dim *dim = isl_dim_alloc(S.getCtx(), S.getNumParams(), 0, 0);
+
+ isl_union_map *schedule = isl_union_map_empty(dim);
+
+ for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ isl_map *scattering;
+
+ if (NewScattering->find(*SI) == NewScattering->end())
+ scattering = isl_map_copy(Stmt->getScattering());
+ else
+ scattering = isl_map_copy((*NewScattering)[Stmt]);
+
+ isl_union_map_add_map(schedule, scattering);
+ }
+
+ isl_union_map *temp_must_dep, *temp_may_dep;
+ isl_union_map *temp_must_no_source, *temp_may_no_source;
+
+ DEBUG(
+ dbgs().indent(4) << "Sink :=\n";
+ dbgs().indent(8) << stringFromIslObj(sink) << ";\n";
+
+ dbgs().indent(4) << "MustSource :=\n";
+ dbgs().indent(8) << stringFromIslObj(must_source) << ";\n";
+
+ dbgs().indent(4) << "MaySource :=\n";
+ dbgs().indent(8) << stringFromIslObj(may_source) << ";\n";
+
+ dbgs().indent(4) << "Schedule :=\n";
+ dbgs().indent(8) << stringFromIslObj(schedule) << ";\n";
+ );
+
+ isl_union_map_compute_flow(isl_union_map_copy(sink),
+ isl_union_map_copy(must_source),
+ isl_union_map_copy(may_source), schedule,
+ &temp_must_dep, &temp_may_dep,
+ &temp_must_no_source, &temp_may_no_source);
+
+ DEBUG(dbgs().indent(4) << "\nDependences calculated\n");
+ DEBUG(
+ dbgs().indent(4) << "TempMustDep:=\n";
+ dbgs().indent(8) << stringFromIslObj(temp_must_dep) << ";\n";
+
+ dbgs().indent(4) << "MustDep:=\n";
+ dbgs().indent(8) << stringFromIslObj(must_dep) << ";\n";
+ );
+
+ // Remove redundant statements.
+ temp_must_dep = isl_union_map_coalesce(temp_must_dep);
+ temp_may_dep = isl_union_map_coalesce(temp_may_dep);
+ temp_must_no_source = isl_union_map_coalesce(temp_must_no_source);
+ temp_may_no_source = isl_union_map_coalesce(temp_may_no_source);
+
+ if (!isl_union_map_is_equal(temp_must_dep, must_dep)) {
+ DEBUG(dbgs().indent(4) << "\nEqual 1 calculated\n");
+ return false;
+ }
+
+ DEBUG(dbgs().indent(4) << "\nEqual 1 calculated\n");
+
+ if (!isl_union_map_is_equal(temp_may_dep, may_dep))
+ return false;
+
+ DEBUG(dbgs().indent(4) << "\nEqual 2 calculated\n");
+
+ if (!isl_union_map_is_equal(temp_must_no_source, must_no_source))
+ return false;
+
+ if (!isl_union_map_is_equal(temp_may_no_source, may_no_source))
+ return false;
+
+ return true;
+}
+
+isl_union_map* getCombinedScheduleForDim(Scop *scop, unsigned dimLevel) {
+ isl_dim *dim = isl_dim_alloc(scop->getCtx(), scop->getNumParams(), 0, 0);
+
+ isl_union_map *schedule = isl_union_map_empty(dim);
+
+ for (Scop::iterator SI = scop->begin(), SE = scop->end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+ isl_map *scattering = isl_map_copy(Stmt->getScattering());
+ unsigned remainingDimensions = isl_map_n_out(scattering) - dimLevel;
+ scattering = isl_map_project_out(scattering, isl_dim_out, dimLevel,
+ remainingDimensions);
+ isl_union_map_add_map(schedule, scattering);
+ }
+
+ return schedule;
+}
+
+bool Dependences::isParallelDimension(isl_set *loopDomain,
+ unsigned parallelDimension) {
+ Scop *S = &getCurScop();
+ isl_union_map *schedule = getCombinedScheduleForDim(S, parallelDimension);
+
+ // Calculate distance vector.
+ isl_union_set *scheduleSubset;
+ isl_union_map *scheduleDeps, *restrictedDeps;
+ isl_union_map *scheduleDeps_war, *restrictedDeps_war;
+ isl_union_map *scheduleDeps_waw, *restrictedDeps_waw;
+
+ scheduleSubset = isl_union_set_from_set(isl_set_copy(loopDomain));
+
+ scheduleDeps = isl_union_map_apply_range(isl_union_map_copy(must_dep),
+ isl_union_map_copy(schedule));
+ scheduleDeps = isl_union_map_apply_domain(scheduleDeps,
+ isl_union_map_copy(schedule));
+
+ scheduleDeps_war = isl_union_map_apply_range(isl_union_map_copy(war_dep),
+ isl_union_map_copy(schedule));
+ scheduleDeps_war = isl_union_map_apply_domain(scheduleDeps_war,
+ isl_union_map_copy(schedule));
+
+ scheduleDeps_waw = isl_union_map_apply_range(isl_union_map_copy(waw_dep),
+ isl_union_map_copy(schedule));
+ scheduleDeps_waw = isl_union_map_apply_domain(scheduleDeps_waw,
+ isl_union_map_copy(schedule));
+
+ // Dependences need to originate and to terminate in the scheduling space
+ // enumerated by this loop.
+ restrictedDeps = isl_union_map_intersect_domain(scheduleDeps,
+ isl_union_set_copy(scheduleSubset));
+ restrictedDeps = isl_union_map_intersect_range(restrictedDeps,
+ isl_union_set_copy(scheduleSubset));
+
+ isl_union_set *distance = isl_union_map_deltas(restrictedDeps);
+
+ restrictedDeps_war = isl_union_map_intersect_domain(scheduleDeps_war,
+ isl_union_set_copy(scheduleSubset));
+ restrictedDeps_war = isl_union_map_intersect_range(restrictedDeps_war,
+ isl_union_set_copy(scheduleSubset));
+
+ isl_union_set *distance_war = isl_union_map_deltas(restrictedDeps_war);
+
+ restrictedDeps_waw = isl_union_map_intersect_domain(scheduleDeps_waw,
+ isl_union_set_copy(scheduleSubset));
+ restrictedDeps_waw = isl_union_map_intersect_range(restrictedDeps_waw,
+ isl_union_set_copy(scheduleSubset));
+
+ isl_union_set *distance_waw = isl_union_map_deltas(restrictedDeps_waw);
+
+ isl_dim *dim = isl_dim_set_alloc(S->getCtx(), S->getNumParams(),
+ parallelDimension);
+
+ // [0, 0, 0, 0] - All zero
+ isl_basic_set *allZeroBS = isl_basic_set_universe(isl_dim_copy(dim));
+ unsigned dimensions = isl_dim_size(dim, isl_dim_set);
+
+ for (unsigned i = 0; i < dimensions; i++) {
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+ isl_int v;
+ isl_int_init(v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_set, i, v);
+ allZeroBS = isl_basic_set_add_constraint(allZeroBS, c);
+ isl_int_clear(v);
+ }
+
+ isl_set *allZero = isl_set_from_basic_set(allZeroBS);
+
+ // All zero, last unknown.
+ // [0, 0, 0, ?]
+ isl_basic_set *lastUnknownBS = isl_basic_set_universe(isl_dim_copy(dim));
+ dimensions = isl_dim_size(dim, isl_dim_set);
+
+ for (unsigned i = 0; i < dimensions - 1; i++) {
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+ isl_int v;
+ isl_int_init(v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_set, i, v);
+ lastUnknownBS = isl_basic_set_add_constraint(lastUnknownBS, c);
+ isl_int_clear(v);
+ }
+
+ isl_set *lastUnknown = isl_set_from_basic_set(lastUnknownBS);
+
+ // Valid distance vectors
+ isl_set *validDistances = isl_set_subtract(lastUnknown, allZero);
+ validDistances = isl_set_complement(validDistances);
+ isl_union_set *validDistancesUS = isl_union_set_from_set(validDistances);
+
+ isl_union_set *nonValid = isl_union_set_subtract(distance,
+ isl_union_set_copy(validDistancesUS));
+
+ isl_union_set *nonValid_war = isl_union_set_subtract(distance_war,
+ isl_union_set_copy(validDistancesUS));
+
+ isl_union_set *nonValid_waw = isl_union_set_subtract(distance_waw,
+ validDistancesUS);
+
+ return isl_union_set_is_empty(nonValid)
+ && isl_union_set_is_empty(nonValid_war)
+ && isl_union_set_is_empty(nonValid_waw);
+}
+
+void Dependences::printScop(raw_ostream &OS) const {
+ OS.indent(4) << "Must dependences:\n";
+ OS.indent(8) << stringFromIslObj(must_dep) << "\n";
+
+ OS.indent(4) << "May dependences:\n";
+ OS.indent(8) << stringFromIslObj(may_dep) << "\n";
+
+ OS.indent(4) << "Must no source:\n";
+ OS.indent(8) << stringFromIslObj(must_no_source) << "\n";
+
+ OS.indent(4) << "May no source:\n";
+ OS.indent(8) << stringFromIslObj(may_no_source) << "\n";
+}
+
+void Dependences::releaseMemory() {
+ if (must_dep)
+ isl_union_map_free(must_dep);
+
+ if (may_dep)
+ isl_union_map_free(may_dep);
+
+ if (must_no_source)
+ isl_union_map_free(must_no_source);
+
+ if (may_no_source)
+ isl_union_map_free(may_no_source);
+
+ if (war_dep)
+ isl_union_map_free(war_dep);
+
+ if (waw_dep)
+ isl_union_map_free(waw_dep);
+
+ must_dep = may_dep = NULL;
+ must_no_source = may_no_source = NULL;
+ war_dep = waw_dep = NULL;
+
+ if (sink)
+ isl_union_map_free(sink);
+
+ if (must_source)
+ isl_union_map_free(must_source);
+
+ if (may_source)
+ isl_union_map_free(may_source);
+
+ sink = must_source = may_source = NULL;
+}
+
+void Dependences::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+}
+
+char Dependences::ID = 0;
+
+static RegisterPass<Dependences>
+X("polly-dependences", "Polly - Calculate dependences for Scop");
+
+Pass* polly::createDependencesPass() {
+ return new Dependences();
+}
--- /dev/null
+##===- polly/lib/Exchange/Makefile ----------------*- Makefile -*-===##
+
+#
+# Indicate where we are relative to the top of the source tree.
+#
+LEVEL=../..
+
+LIBRARYNAME=pollyanalysis
+BUILD_ARCHIVE = 1
+
+CPP.Flags += $(POLLY_INC)
+
+#
+# Include Makefile.common so we know what to do.
+#
+include $(LEVEL)/Makefile.common
--- /dev/null
+//===----- ScopDetection.cpp - Detect Scops --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Detect the maximal Scops of a function.
+//
+// A static control part (Scop) is a subgraph of the control flow graph (CFG)
+// that only has statically known control flow and can therefore be described
+// within the polyhedral model.
+//
+// Every Scop fullfills these restrictions:
+//
+// * It is a single entry single exit region
+//
+// * Only affine linear bounds in the loops
+//
+// Every natural loop in a Scop must have a number of loop iterations that can
+// be described as an affine linear function in surrounding loop iterators or
+// parameters. (A parameter is a scalar that does not change its value during
+// execution of the Scop).
+//
+// * Only comparisons of affine linear expressions in conditions
+//
+// * All loops and conditions perfectly nested
+//
+// The control flow needs to be structured such that it could be written using
+// just 'for' and 'if' statements, without the need for any 'goto', 'break' or
+// 'continue'.
+//
+// * Side effect free functions call
+//
+// Only function calls and intrinsics that do not have side effects are allowed
+// (readnone).
+//
+// The Scop detection finds the largest Scops by checking if the largest
+// region is a Scop. If this is not the case, its canonical subregions are
+// checked until a region is a Scop. It is now tried to extend this Scop by
+// creating a larger non canonical region.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/ScopDetection.h"
+
+#include "polly/LinkAllPasses.h"
+#include "polly/Support/ScopHelper.h"
+#include "polly/Support/AffineSCEVIterator.h"
+
+#include "llvm/LLVMContext.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Assembly/Writer.h"
+
+#define DEBUG_TYPE "polly-detect"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+using namespace polly;
+
+//===----------------------------------------------------------------------===//
+// Statistics.
+
+STATISTIC(ValidRegion, "Number of regions that a valid part of Scop");
+
+#define BADSCOP_STAT(NAME, DESC) STATISTIC(Bad##NAME##ForScop, \
+ "Number of bad regions for Scop: "\
+ DESC)
+
+#define STATSCOP(NAME); assert(!Context.Verifying && #NAME); \
+ if (!Context.Verifying) ++Bad##NAME##ForScop;
+
+BADSCOP_STAT(CFG, "CFG too complex");
+BADSCOP_STAT(IndVar, "Non canonical induction variable in loop");
+BADSCOP_STAT(LoopBound, "Loop bounds can not be computed");
+BADSCOP_STAT(FuncCall, "Function call with side effects appeared");
+BADSCOP_STAT(AffFunc, "Expression not affine");
+BADSCOP_STAT(Scalar, "Found scalar dependency");
+BADSCOP_STAT(Alias, "Found base address alias");
+BADSCOP_STAT(SimpleRegion, "Region not simple");
+BADSCOP_STAT(Other, "Others");
+
+//===----------------------------------------------------------------------===//
+// ScopDetection.
+
+bool ScopDetection::isMaxRegionInScop(const Region &R) const {
+ // The Region is valid only if it could be found in the set.
+ return ValidRegions.count(&R);
+}
+
+bool ScopDetection::isValidAffineFunction(const SCEV *S, Region &RefRegion,
+ Value **BasePtr) const {
+ assert(S && "S must not be null!");
+ bool isMemoryAccess = (BasePtr != 0);
+ if (isMemoryAccess) *BasePtr = 0;
+ DEBUG(dbgs() << "Checking " << *S << " ... ");
+
+ if (isa<SCEVCouldNotCompute>(S)) {
+ DEBUG(dbgs() << "Non Affine: SCEV could not be computed\n");
+ return false;
+ }
+
+ for (AffineSCEVIterator I = affine_begin(S, SE), E = affine_end(); I != E;
+ ++I) {
+ // The constant part must be a SCEVConstant.
+ // TODO: support sizeof in coefficient.
+ if (!isa<SCEVConstant>(I->second)) {
+ DEBUG(dbgs() << "Non Affine: Right hand side is not constant\n");
+ return false;
+ }
+
+ const SCEV *Var = I->first;
+
+ // A constant offset is affine.
+ if(isa<SCEVConstant>(Var))
+ continue;
+
+ // Memory accesses are allowed to have a base pointer.
+ if (Var->getType()->isPointerTy()) {
+ if (!isMemoryAccess) {
+ DEBUG(dbgs() << "Non Affine: Pointer in non memory access\n");
+ return false;
+ }
+
+ assert(I->second->isOne() && "Only one as pointer coefficient allowed.\n");
+ const SCEVUnknown *BaseAddr = dyn_cast<SCEVUnknown>(Var);
+
+ if (!BaseAddr || isa<UndefValue>(BaseAddr->getValue())){
+ DEBUG(dbgs() << "Cannot handle base: " << *Var << "\n");
+ return false;
+ }
+
+ // BaseAddr must be invariant in Scop.
+ if (!isParameter(BaseAddr, RefRegion, *LI, *SE)) {
+ DEBUG(dbgs() << "Non Affine: Base address not invariant in SCoP\n");
+ return false;
+ }
+
+ assert(*BasePtr == 0 && "Found second base pointer.\n");
+ *BasePtr = BaseAddr->getValue();
+ continue;
+ }
+
+ if (isParameter(Var, RefRegion, *LI, *SE)
+ || isIndVar(Var, RefRegion, *LI, *SE))
+ continue;
+
+ DEBUG(dbgs() << "Non Affine: " ;
+ Var->print(dbgs());
+ dbgs() << " is neither parameter nor induction variable\n");
+ return false;
+ }
+
+ DEBUG(dbgs() << " is affine.\n");
+ return !isMemoryAccess || (*BasePtr != 0);
+}
+
+bool ScopDetection::isValidCFG(BasicBlock &BB, DetectionContext &Context) const
+{
+ Region &RefRegion = Context.CurRegion;
+ TerminatorInst *TI = BB.getTerminator();
+
+ // Return instructions are only valid if the region is the top level region.
+ if (isa<ReturnInst>(TI) && !RefRegion.getExit() && TI->getNumOperands() == 0)
+ return true;
+
+ BranchInst *Br = dyn_cast<BranchInst>(TI);
+
+ if (!Br) {
+ DEBUG(dbgs() << "Non branch instruction as terminator of BB: ";
+ WriteAsOperand(dbgs(), &BB, false);
+ dbgs() << "\n");
+ STATSCOP(CFG);
+ return false;
+ }
+
+ if (Br->isUnconditional()) return true;
+
+ Value *Condition = Br->getCondition();
+
+ // UndefValue is not allowed as condition.
+ if (isa<UndefValue>(Condition)) {
+ DEBUG(dbgs() << "Undefined value in branch instruction of BB: ";
+ WriteAsOperand(dbgs(), &BB, false);
+ dbgs() << "\n");
+ STATSCOP(AffFunc);
+ return false;
+ }
+
+ // Only Constant and ICmpInst are allowed as condition.
+ if (!(isa<Constant>(Condition) || isa<ICmpInst>(Condition))) {
+ DEBUG(dbgs() << "Non Constant and non ICmpInst instruction in BB: ";
+ WriteAsOperand(dbgs(), &BB, false);
+ dbgs() << "\n");
+ STATSCOP(AffFunc);
+ return false;
+ }
+
+ // Allow perfectly nested conditions.
+ assert(Br->getNumSuccessors() == 2 && "Unexpected number of successors");
+
+ if (ICmpInst *ICmp = dyn_cast<ICmpInst>(Condition)) {
+ // Unsigned comparisons are not allowed. They trigger overflow problems
+ // in the code generation.
+ //
+ // TODO: This is not sufficient and just hides bugs. However it does pretty
+ // well.
+ if(ICmp->isUnsigned())
+ return false;
+
+ // Are both operands of the ICmp affine?
+ if (isa<UndefValue>(ICmp->getOperand(0))
+ || isa<UndefValue>(ICmp->getOperand(1))) {
+ DEBUG(dbgs() << "Undefined operand in branch instruction of BB: ";
+ WriteAsOperand(dbgs(), &BB, false);
+ dbgs() << "\n");
+ STATSCOP(AffFunc);
+ return false;
+ }
+
+ const SCEV *ScevLHS = SE->getSCEV(ICmp->getOperand(0));
+ const SCEV *ScevRHS = SE->getSCEV(ICmp->getOperand(1));
+
+ bool affineLHS = isValidAffineFunction(ScevLHS, RefRegion);
+ bool affineRHS = isValidAffineFunction(ScevRHS, RefRegion);
+
+ if (!affineLHS || !affineRHS) {
+ DEBUG(dbgs() << "Non affine branch instruction in BB: ";
+ WriteAsOperand(dbgs(), &BB, false);
+ dbgs() << "\n");
+ STATSCOP(AffFunc);
+ return false;
+ }
+ }
+
+ // Allow loop exit conditions.
+ Loop *L = LI->getLoopFor(&BB);
+ if (L && L->getExitingBlock() == &BB)
+ return true;
+
+ // Allow perfectly nested conditions.
+ Region *R = RI->getRegionFor(&BB);
+ if (R->getEntry() != &BB) {
+ DEBUG(dbgs() << "Non well structured condition starting at BB: ";
+ WriteAsOperand(dbgs(), &BB, false);
+ dbgs() << "\n");
+ STATSCOP(CFG);
+ return false;
+ }
+
+ return true;
+}
+
+bool ScopDetection::isValidCallInst(CallInst &CI) {
+ if (CI.mayHaveSideEffects() || CI.doesNotReturn())
+ return false;
+
+ if (CI.doesNotAccessMemory())
+ return true;
+
+ Function *CalledFunction = CI.getCalledFunction();
+
+ // Indirect calls are not supported.
+ if (CalledFunction == 0)
+ return false;
+
+ // TODO: Intrinsics.
+ return false;
+}
+
+bool ScopDetection::isValidMemoryAccess(Instruction &Inst,
+ DetectionContext &Context) const {
+ Value *Ptr = getPointerOperand(Inst), *BasePtr;
+ const SCEV *AccessFunction = SE->getSCEV(Ptr);
+
+ if (!isValidAffineFunction(AccessFunction, Context.CurRegion, &BasePtr)) {
+ DEBUG(dbgs() << "Bad memory addr " << *AccessFunction << "\n");
+ STATSCOP(AffFunc);
+ return false;
+ }
+
+ // FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions
+ // created by IndependentBlocks Pass.
+ if (isa<IntToPtrInst>(BasePtr)) {
+ DEBUG(dbgs() << "Find bad intoptr prt: " << *BasePtr << '\n');
+ STATSCOP(Other);
+ return false;
+ }
+
+ // Check if the base pointer of the memory access does alias with
+ // any other pointer. This cannot be handled at the moment.
+ AliasSet &AS =
+ Context.AST.getAliasSetForPointer(BasePtr, AliasAnalysis::UnknownSize,
+ Inst.getMetadata(LLVMContext::MD_tbaa));
+ if (!AS.isMustAlias()) {
+ DEBUG(dbgs() << "Bad pointer alias found:" << *BasePtr << "\nAS:\n" << AS);
+
+ // STATSCOP triggers an assertion if we are in verifying mode.
+ // This is generally good to check that we do not change the SCoP after we
+ // run the SCoP detection and consequently to ensure that we can still
+ // represent that SCoP. However, in case of aliasing this does not work.
+ // The independent blocks pass may create memory references which seem to
+ // alias, if -basicaa is not available. They actually do not. As we do not
+ // not know this and we would fail here if we verify it.
+ if (!Context.Verifying) {
+ STATSCOP(Alias);
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
+
+bool ScopDetection::hasScalarDependency(Instruction &Inst,
+ Region &RefRegion) const {
+ for (Instruction::use_iterator UI = Inst.use_begin(), UE = Inst.use_end();
+ UI != UE; ++UI)
+ if (Instruction *Use = dyn_cast<Instruction>(*UI))
+ if (!RefRegion.contains(Use->getParent())) {
+ // DirtyHack 1: PHINode user outside the Scop is not allow, if this
+ // PHINode is induction variable, the scalar to array transform may
+ // break it and introduce a non-indvar PHINode, which is not allow in
+ // Scop.
+ // This can be fix by:
+ // Introduce a IndependentBlockPrepare pass, which translate all
+ // PHINodes not in Scop to array.
+ // The IndependentBlockPrepare pass can also split the entry block of
+ // the function to hold the alloca instruction created by scalar to
+ // array. and split the exit block of the Scop so the new create load
+ // instruction for escape users will not break other Scops.
+ if (isa<PHINode>(Use))
+ return true;
+ }
+
+ return false;
+}
+
+bool ScopDetection::isValidInstruction(Instruction &Inst,
+ DetectionContext &Context) const {
+ // Only canonical IVs are allowed.
+ if (PHINode *PN = dyn_cast<PHINode>(&Inst))
+ if (!isIndVar(PN, LI)) {
+ DEBUG(dbgs() << "Non canonical PHI node found: ";
+ WriteAsOperand(dbgs(), &Inst, false);
+ dbgs() << "\n");
+ return false;
+ }
+
+ // Scalar dependencies are not allowed.
+ if (hasScalarDependency(Inst, Context.CurRegion)) {
+ DEBUG(dbgs() << "Scalar dependency found: ";
+ WriteAsOperand(dbgs(), &Inst, false);
+ dbgs() << "\n");
+ STATSCOP(Scalar);
+ return false;
+ }
+
+ // We only check the call instruction but not invoke instruction.
+ if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
+ if (isValidCallInst(*CI))
+ return true;
+
+ DEBUG(dbgs() << "Bad call Inst: ";
+ WriteAsOperand(dbgs(), &Inst, false);
+ dbgs() << "\n");
+ STATSCOP(FuncCall);
+ return false;
+ }
+
+ if (!Inst.mayWriteToMemory() && !Inst.mayReadFromMemory()) {
+ // Handle cast instruction.
+ if (isa<IntToPtrInst>(Inst) || isa<BitCastInst>(Inst)) {
+ DEBUG(dbgs() << "Bad cast Inst!\n");
+ STATSCOP(Other);
+ return false;
+ }
+
+ if (isa<AllocaInst>(Inst)) {
+ DEBUG(dbgs() << "AllocaInst is not allowed!!\n");
+ STATSCOP(Other);
+ return false;
+ }
+
+ return true;
+ }
+
+ // Check the access function.
+ if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
+ return isValidMemoryAccess(Inst, Context);
+
+ // We do not know this instruction, therefore we assume it is invalid.
+ DEBUG(dbgs() << "Bad instruction found: ";
+ WriteAsOperand(dbgs(), &Inst, false);
+ dbgs() << "\n");
+ STATSCOP(Other);
+ return false;
+}
+
+bool ScopDetection::isValidBasicBlock(BasicBlock &BB,
+ DetectionContext &Context) const {
+ if (!isValidCFG(BB, Context))
+ return false;
+
+ // Check all instructions, except the terminator instruction.
+ for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
+ if (!isValidInstruction(*I, Context))
+ return false;
+
+ Loop *L = LI->getLoopFor(&BB);
+ if (L && L->getHeader() == &BB && !isValidLoop(L, Context))
+ return false;
+
+ return true;
+}
+
+bool ScopDetection::isValidLoop(Loop *L, DetectionContext &Context) const {
+ PHINode *IndVar = L->getCanonicalInductionVariable();
+ // No canonical induction variable.
+ if (!IndVar) {
+ DEBUG(dbgs() << "No canonical iv for loop: ";
+ WriteAsOperand(dbgs(), L->getHeader(), false);
+ dbgs() << "\n");
+ STATSCOP(IndVar);
+ return false;
+ }
+
+ // Is the loop count affine?
+ const SCEV *LoopCount = SE->getBackedgeTakenCount(L);
+ if (!isValidAffineFunction(LoopCount, Context.CurRegion)) {
+ DEBUG(dbgs() << "Non affine loop bound for loop: ";
+ WriteAsOperand(dbgs(), L->getHeader(), false);
+ dbgs() << "\n");
+ STATSCOP(LoopBound);
+ return false;
+ }
+
+ return true;
+}
+
+Region *ScopDetection::expandRegion(Region &R) {
+ Region *CurrentRegion = &R;
+ Region *TmpRegion = R.getExpandedRegion();
+
+ DEBUG(dbgs() << "\tExpanding " << R.getNameStr() << "\n");
+
+ while (TmpRegion) {
+ DetectionContext Context(*TmpRegion, *AA, false /*verifying*/);
+ DEBUG(dbgs() << "\t\tTrying " << TmpRegion->getNameStr() << "\n");
+
+ if (!allBlocksValid(Context))
+ break;
+
+ if (isValidExit(Context)) {
+ if (CurrentRegion != &R)
+ delete CurrentRegion;
+
+ CurrentRegion = TmpRegion;
+ }
+
+ Region *TmpRegion2 = TmpRegion->getExpandedRegion();
+
+ if (TmpRegion != &R && TmpRegion != CurrentRegion)
+ delete TmpRegion;
+
+ TmpRegion = TmpRegion2;
+ }
+
+ if (&R == CurrentRegion)
+ return NULL;
+
+ DEBUG(dbgs() << "\tto " << CurrentRegion->getNameStr() << "\n");
+
+ return CurrentRegion;
+}
+
+
+void ScopDetection::findScops(Region &R) {
+ DetectionContext Context(R, *AA, false /*verifying*/);
+
+ if (isValidRegion(Context)) {
+ ++ValidRegion;
+ ValidRegions.insert(&R);
+ return;
+ }
+
+ for (Region::iterator I = R.begin(), E = R.end(); I != E; ++I)
+ findScops(**I);
+
+ // Try to expand regions.
+ //
+ // As the region tree normally only contains canonical regions, non canonical
+ // regions that form a Scop are not found. Therefore, those non canonical
+ // regions are checked by expanding the canonical ones.
+
+ std::vector<Region*> ToExpand;
+
+ for (Region::iterator I = R.begin(), E = R.end(); I != E; ++I)
+ ToExpand.push_back(*I);
+
+ for (std::vector<Region*>::iterator RI = ToExpand.begin(),
+ RE = ToExpand.end(); RI != RE; ++RI) {
+ Region *CurrentRegion = *RI;
+
+ // Skip invalid regions. Regions may become invalid, if they are element of
+ // an already expanded region.
+ if (ValidRegions.find(CurrentRegion) == ValidRegions.end())
+ continue;
+
+ Region *ExpandedR = expandRegion(*CurrentRegion);
+
+ if (!ExpandedR)
+ continue;
+
+ R.addSubRegion(ExpandedR, true);
+ ValidRegions.insert(ExpandedR);
+ ValidRegions.erase(CurrentRegion);
+
+ for (Region::iterator I = ExpandedR->begin(), E = ExpandedR->end(); I != E;
+ ++I)
+ ValidRegions.erase(*I);
+ }
+}
+
+bool ScopDetection::allBlocksValid(DetectionContext &Context) const {
+ Region &R = Context.CurRegion;
+
+ for (Region::block_iterator I = R.block_begin(), E = R.block_end(); I != E;
+ ++I)
+ if (!isValidBasicBlock(*(I->getNodeAs<BasicBlock>()), Context))
+ return false;
+
+ return true;
+}
+
+bool ScopDetection::isValidExit(DetectionContext &Context) const {
+ Region &R = Context.CurRegion;
+
+ // PHI nodes are not allowed in the exit basic block.
+ if (BasicBlock *Exit = R.getExit()) {
+ BasicBlock::iterator I = Exit->begin();
+ if (I != Exit->end() && isa<PHINode> (*I)) {
+ DEBUG(dbgs() << "PHI node in exit";
+ dbgs() << "\n");
+ STATSCOP(Other);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ScopDetection::isValidRegion(DetectionContext &Context) const {
+ Region &R = Context.CurRegion;
+
+ DEBUG(dbgs() << "Checking region: " << R.getNameStr() << "\n\t");
+
+ // The toplevel region is no valid region.
+ if (!R.getParent()) {
+ DEBUG(dbgs() << "Top level region is invalid";
+ dbgs() << "\n");
+ return false;
+ }
+
+ // SCoP can not contains the entry block of the function, because we need
+ // to insert alloca instruction there when translate scalar to array.
+ if (R.getEntry() == &(R.getEntry()->getParent()->getEntryBlock())) {
+ DEBUG(dbgs() << "Region containing entry block of function is invalid!\n");
+ STATSCOP(Other);
+ return false;
+ }
+
+ // Only a simple region is allowed.
+ if (!R.isSimple()) {
+ DEBUG(dbgs() << "Region not simple: " << R.getNameStr() << '\n');
+ STATSCOP(SimpleRegion);
+ return false;
+ }
+
+ if (!allBlocksValid(Context))
+ return false;
+
+ if (!isValidExit(Context))
+ return false;
+
+ DEBUG(dbgs() << "OK\n");
+ return true;
+}
+
+bool ScopDetection::isValidFunction(llvm::Function &F) {
+ const std::string &Name = F.getNameStr();
+ size_t found = Name.find(".omp_subfn");
+ if (found != std::string::npos)
+ return false;
+ else
+ return true;
+}
+
+bool ScopDetection::runOnFunction(llvm::Function &F) {
+ AA = &getAnalysis<AliasAnalysis>();
+ SE = &getAnalysis<ScalarEvolution>();
+ LI = &getAnalysis<LoopInfo>();
+ RI = &getAnalysis<RegionInfo>();
+ Region *TopRegion = RI->getTopLevelRegion();
+
+ if(!isValidFunction(F))
+ return false;
+
+ findScops(*TopRegion);
+ return false;
+}
+
+
+void polly::ScopDetection::verifyRegion(const Region &R) const {
+ assert(isMaxRegionInScop(R) && "Expect R is a valid region.");
+ DetectionContext Context(const_cast<Region&>(R), *AA, true /*verifying*/);
+ isValidRegion(Context);
+}
+
+void polly::ScopDetection::verifyAnalysis() const {
+ for (RegionSet::const_iterator I = ValidRegions.begin(),
+ E = ValidRegions.end(); I != E; ++I)
+ verifyRegion(**I);
+}
+
+void ScopDetection::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<DominatorTree>();
+ AU.addRequired<PostDominatorTree>();
+ AU.addRequired<LoopInfo>();
+ AU.addRequired<ScalarEvolution>();
+ // We also need AA and RegionInfo when we are verifying analysis.
+ AU.addRequiredTransitive<AliasAnalysis>();
+ AU.addRequiredTransitive<RegionInfo>();
+ AU.setPreservesAll();
+}
+
+void ScopDetection::print(raw_ostream &OS, const Module *) const {
+ for (RegionSet::const_iterator I = ValidRegions.begin(),
+ E = ValidRegions.end(); I != E; ++I)
+ OS << "Valid Region for Scop: " << (*I)->getNameStr() << '\n';
+
+ OS << "\n";
+}
+
+void ScopDetection::releaseMemory() {
+ ValidRegions.clear();
+}
+
+char ScopDetection::ID = 0;
+
+static RegisterPass<ScopDetection>
+X("polly-detect", "Polly - Detect Scops in functions");
+
--- /dev/null
+//===- GraphPrinter.cpp - Create a DOT output describing the Scop. --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Create a DOT output describing the Scop.
+//
+// For each function a dot file is created that shows the control flow graph of
+// the function and highlights the detected Scops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopDetection.h"
+
+#include "llvm/Analysis/DOTGraphTraitsPass.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionIterator.h"
+
+using namespace polly;
+using namespace llvm;
+
+namespace llvm {
+ template <> struct GraphTraits<ScopDetection*>
+ : public GraphTraits<RegionInfo*> {
+
+ static NodeType *getEntryNode(ScopDetection *SD) {
+ return GraphTraits<RegionInfo*>::getEntryNode(SD->getRI());
+ }
+ static nodes_iterator nodes_begin(ScopDetection* SD) {
+ return nodes_iterator::begin(getEntryNode(SD));
+ }
+ static nodes_iterator nodes_end(ScopDetection *SD) {
+ return nodes_iterator::end(getEntryNode(SD));
+ }
+ };
+
+template<>
+struct DOTGraphTraits<RegionNode*> : public DefaultDOTGraphTraits {
+
+ DOTGraphTraits (bool isSimple=false)
+ : DefaultDOTGraphTraits(isSimple) {}
+
+ std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
+
+ if (!Node->isSubRegion()) {
+ BasicBlock *BB = Node->getNodeAs<BasicBlock>();
+
+ if (isSimple())
+ return DOTGraphTraits<const Function*>
+ ::getSimpleNodeLabel(BB, BB->getParent());
+ else
+ return DOTGraphTraits<const Function*>
+ ::getCompleteNodeLabel(BB, BB->getParent());
+ }
+
+ return "Not implemented";
+ }
+};
+
+template<>
+struct DOTGraphTraits<ScopDetection*> : public DOTGraphTraits<RegionNode*> {
+ DOTGraphTraits (bool isSimple=false)
+ : DOTGraphTraits<RegionNode*>(isSimple) {}
+ static std::string getGraphName(ScopDetection *SD) {
+ return "Scop Graph";
+ }
+
+ std::string getEdgeAttributes(RegionNode *srcNode,
+ GraphTraits<RegionInfo*>::ChildIteratorType CI, ScopDetection *SD) {
+
+ RegionNode *destNode = *CI;
+
+ if (srcNode->isSubRegion() || destNode->isSubRegion())
+ return "";
+
+ // In case of a backedge, do not use it to define the layout of the nodes.
+ BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
+ BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
+
+ RegionInfo *RI = SD->getRI();
+ Region *R = RI->getRegionFor(destBB);
+
+ while (R && R->getParent())
+ if (R->getParent()->getEntry() == destBB)
+ R = R->getParent();
+ else
+ break;
+
+ if (R->getEntry() == destBB && R->contains(srcBB))
+ return "constraint=false";
+
+ return "";
+ }
+
+ std::string getNodeLabel(RegionNode *Node, ScopDetection *SD) {
+ return DOTGraphTraits<RegionNode*>
+ ::getNodeLabel(Node, SD->getRI()->getTopLevelRegion());
+ }
+ // Print the cluster of the subregions. This groups the single basic blocks
+ // and adds a different background color for each group.
+ static void printRegionCluster(const ScopDetection *SD, const Region *R,
+ raw_ostream &O, unsigned depth = 0) {
+ O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(R)
+ << " {\n";
+ O.indent(2 * (depth + 1)) << "label = \"\";\n";
+
+ if (SD->isMaxRegionInScop(*R)) {
+ O.indent(2 * (depth + 1)) << "style = filled;\n";
+
+ // Set color to green.
+ O.indent(2 * (depth + 1)) << "color = 3";
+ } else {
+ O.indent(2 * (depth + 1)) << "style = solid;\n";
+
+ int color = (R->getDepth() * 2 % 12) + 1;
+
+ // We do not want green again.
+ if (color == 3)
+ color = 6;
+
+ O.indent(2 * (depth + 1)) << "color = "
+ << color << "\n";
+ }
+
+ for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
+ printRegionCluster(SD, *RI, O, depth + 1);
+
+ RegionInfo *RI = R->getRegionInfo();
+
+ for (Region::const_block_iterator BI = R->block_begin(),
+ BE = R->block_end(); BI != BE; ++BI) {
+ BasicBlock *BB = (*BI)->getNodeAs<BasicBlock>();
+ if (RI->getRegionFor(BB) == R)
+ O.indent(2 * (depth + 1)) << "Node"
+ << static_cast<const void*>(RI->getTopLevelRegion()->getBBNode(BB))
+ << ";\n";
+ }
+
+ O.indent(2 * depth) << "}\n";
+ }
+ static void addCustomGraphFeatures(const ScopDetection* SD,
+ GraphWriter<ScopDetection*> &GW) {
+ raw_ostream &O = GW.getOStream();
+ O << "\tcolorscheme = \"paired12\"\n";
+ printRegionCluster(SD, SD->getRI()->getTopLevelRegion(), O, 4);
+ }
+};
+
+} //end namespace llvm
+
+struct ScopViewer
+ : public DOTGraphTraitsViewer<ScopDetection, false> {
+ static char ID;
+ ScopViewer() : DOTGraphTraitsViewer<ScopDetection, false>("scops", ID){}
+};
+char ScopViewer::ID = 0;
+
+struct ScopOnlyViewer
+ : public DOTGraphTraitsViewer<ScopDetection, true> {
+ static char ID;
+ ScopOnlyViewer()
+ : DOTGraphTraitsViewer<ScopDetection, true>("scopsonly", ID){}
+};
+char ScopOnlyViewer::ID = 0;
+
+struct ScopPrinter
+ : public DOTGraphTraitsPrinter<ScopDetection, false> {
+ static char ID;
+ ScopPrinter() :
+ DOTGraphTraitsPrinter<ScopDetection, false>("scops", ID) {}
+};
+char ScopPrinter::ID = 0;
+
+struct ScopOnlyPrinter
+ : public DOTGraphTraitsPrinter<ScopDetection, true> {
+ static char ID;
+ ScopOnlyPrinter() :
+ DOTGraphTraitsPrinter<ScopDetection, true>("scopsonly", ID) {}
+};
+char ScopOnlyPrinter::ID = 0;
+
+static RegisterPass<ScopViewer>
+X("view-scops","Polly - View Scops of function");
+
+static RegisterPass<ScopOnlyViewer>
+Y("view-scops-only",
+ "Polly - View Scops of function (with no function bodies)");
+
+static RegisterPass<ScopPrinter>
+M("dot-scops", "Polly - Print Scops of function");
+
+static RegisterPass<ScopOnlyPrinter>
+N("dot-scops-only",
+ "Polly - Print Scops of function (with no function bodies)");
+
+Pass* polly::createDOTViewerPass() {
+ return new ScopViewer();
+}
+
+Pass* polly::createDOTOnlyViewerPass() {
+ return new ScopOnlyViewer();
+}
+
+Pass* polly::createDOTPrinterPass() {
+ return new ScopPrinter();
+}
+
+Pass* polly::createDOTOnlyPrinterPass() {
+ return new ScopOnlyPrinter();
+}
--- /dev/null
+//===--------- ScopInfo.cpp - Create Scops from LLVM IR ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Create a polyhedral description for a static control flow region.
+//
+// The pass creates a polyhedral description of the Scops detected by the Scop
+// detection derived from their LLVM-IR code.
+//
+// This represantation is shared among several tools in the polyhedral
+// community, which are e.g. Cloog, Pluto, Loopo, Graphite.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/ScopInfo.h"
+
+#include "polly/TempScopInfo.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/ScopHelper.h"
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Support/CommandLine.h"
+
+#define DEBUG_TYPE "polly-scops"
+#include "llvm/Support/Debug.h"
+
+#include "isl/constraint.h"
+#include "isl/set.h"
+#include "isl/map.h"
+#include <sstream>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace polly;
+
+STATISTIC(ScopFound, "Number of valid Scops");
+STATISTIC(RichScopFound, "Number of Scops containing a loop");
+
+
+//===----------------------------------------------------------------------===//
+static void setCoefficient(const SCEV *Coeff, mpz_t v, bool negative,
+ bool isSigned = true) {
+ if (Coeff) {
+ const SCEVConstant *C = dyn_cast<SCEVConstant>(Coeff);
+ const APInt &CI = C->getValue()->getValue();
+ MPZ_from_APInt(v, negative ? (-CI) : CI, isSigned);
+ } else
+ isl_int_set_si(v, 0);
+}
+
+static isl_map *getValueOf(const SCEVAffFunc &AffFunc,
+ const ScopStmt *Statement, isl_dim *dim) {
+
+ const SmallVectorImpl<const SCEV*> &Params =
+ Statement->getParent()->getParams();
+ unsigned num_in = Statement->getNumIterators(), num_param = Params.size();
+
+ const char *dimname = isl_dim_get_tuple_name(dim, isl_dim_set);
+ dim = isl_dim_alloc(isl_dim_get_ctx(dim), num_param,
+ isl_dim_size(dim, isl_dim_set), 1);
+ dim = isl_dim_set_tuple_name(dim, isl_dim_in, dimname);
+
+ assert((AffFunc.getType() == SCEVAffFunc::Eq
+ || AffFunc.getType() == SCEVAffFunc::ReadMem
+ || AffFunc.getType() == SCEVAffFunc::WriteMem)
+ && "AffFunc is not an equality");
+
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+
+ isl_int v;
+ isl_int_init(v);
+
+ // Set single output dimension.
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_out, 0, v);
+
+ // Set the coefficient for induction variables.
+ for (unsigned i = 0, e = num_in; i != e; ++i) {
+ setCoefficient(AffFunc.getCoeff(Statement->getSCEVForDimension(i)), v,
+ false, AffFunc.isSigned());
+ isl_constraint_set_coefficient(c, isl_dim_in, i, v);
+ }
+
+ // Set the coefficient of parameters
+ for (unsigned i = 0, e = num_param; i != e; ++i) {
+ setCoefficient(AffFunc.getCoeff(Params[i]), v, false, AffFunc.isSigned());
+ isl_constraint_set_coefficient(c, isl_dim_param, i, v);
+ }
+
+ // Set the constant.
+ setCoefficient(AffFunc.getTransComp(), v, false, AffFunc.isSigned());
+ isl_constraint_set_constant(c, v);
+ isl_int_clear(v);
+
+ isl_basic_map *BasicMap = isl_basic_map_universe(isl_dim_copy(dim));
+ BasicMap = isl_basic_map_add_constraint(BasicMap, c);
+ return isl_map_from_basic_map(BasicMap);
+}
+//===----------------------------------------------------------------------===//
+
+MemoryAccess::~MemoryAccess() {
+ isl_map_free(getAccessFunction());
+}
+
+static void replace(std::string& str, const std::string& find,
+ const std::string& replace) {
+ size_t pos = 0;
+ while((pos = str.find(find, pos)) != std::string::npos)
+ {
+ str.replace(pos, find.length(), replace);
+ pos += replace.length();
+ }
+}
+
+static void makeIslCompatible(std::string& str) {
+ replace(str, ".", "_");
+}
+
+void MemoryAccess::setBaseName() {
+ raw_string_ostream OS(BaseName);
+ WriteAsOperand(OS, getBaseAddr(), false);
+ BaseName = OS.str();
+
+ // Remove the % in the name. This is not supported by isl.
+ BaseName.erase(0,1);
+ makeIslCompatible(BaseName);
+ BaseName = "MemRef_" + BaseName;
+}
+
+std::string MemoryAccess::getAccessFunctionStr() const {
+ return stringFromIslObj(getAccessFunction());
+}
+
+isl_basic_map *MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
+ isl_dim *dim = isl_dim_alloc(Statement->getIslContext(),
+ Statement->getNumParams(),
+ Statement->getNumIterators(), 1);
+ setBaseName();
+
+ dim = isl_dim_set_tuple_name(dim, isl_dim_out, getBaseName().c_str());
+ dim = isl_dim_set_tuple_name(dim, isl_dim_in, Statement->getBaseName());
+
+ return isl_basic_map_universe(dim);
+}
+
+MemoryAccess::MemoryAccess(const SCEVAffFunc &AffFunc, ScopStmt *Statement) {
+ BaseAddr = AffFunc.getBaseAddr();
+ Type = AffFunc.isRead() ? Read : Write;
+ statement = Statement;
+
+ setBaseName();
+
+ isl_dim *dim = isl_dim_set_alloc(Statement->getIslContext(),
+ Statement->getNumParams(),
+ Statement->getNumIterators());
+ dim = isl_dim_set_tuple_name(dim, isl_dim_set, Statement->getBaseName());
+
+ AccessRelation = getValueOf(AffFunc, Statement, dim);
+
+ // Devide the access function by the size of the elements in the function.
+ isl_dim *dim2 = isl_dim_alloc(Statement->getIslContext(),
+ Statement->getNumParams(), 1, 1);
+ isl_basic_map *bmap = isl_basic_map_universe(isl_dim_copy(dim2));
+ isl_constraint *c = isl_equality_alloc(dim2);
+ isl_int v;
+ isl_int_init(v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_in, 0, v);
+ isl_int_set_si(v, AffFunc.getElemSizeInBytes());
+ isl_constraint_set_coefficient(c, isl_dim_out, 0, v);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ isl_map* dataSizeMap = isl_map_from_basic_map(bmap);
+
+ AccessRelation = isl_map_apply_range(AccessRelation, dataSizeMap);
+
+ AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_out,
+ getBaseName().c_str());
+}
+
+MemoryAccess::MemoryAccess(const Value *BaseAddress, ScopStmt *Statement) {
+ BaseAddr = BaseAddress;
+ Type = Read;
+ statement = Statement;
+
+ isl_basic_map *BasicAccessMap = createBasicAccessMap(Statement);
+ AccessRelation = isl_map_from_basic_map(BasicAccessMap);
+}
+
+void MemoryAccess::print(raw_ostream &OS) const {
+ OS.indent(12) << (isRead() ? "Read" : "Write") << "Access := \n";
+ OS.indent(16) << getAccessFunctionStr() << ";\n";
+}
+
+void MemoryAccess::dump() const {
+ print(errs());
+}
+
+// Create a map in the size of the provided set domain, that maps from the
+// one element of the provided set domain to another element of the provided
+// set domain.
+// The mapping is limited to all points that are equal in all but the last
+// dimension and for which the last dimension of the input is strict smaller
+// than the last dimension of the output.
+//
+// getEqualAndLarger(set[i0, i1, ..., iX]):
+//
+// set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
+// : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
+//
+static isl_map *getEqualAndLarger(isl_dim *setDomain) {
+ isl_dim *mapDomain = isl_dim_map_from_set(setDomain);
+ isl_basic_map *bmap = isl_basic_map_universe(mapDomain);
+
+ // Set all but the last dimension to be equal for the input and output
+ //
+ // input[i0, i1, ..., iX] -> output[o0, o1, ..., oX]
+ // : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1)
+ for (unsigned i = 0; i < isl_basic_map_n_in(bmap) - 1; ++i) {
+ isl_int v;
+ isl_int_init(v);
+ isl_constraint *c = isl_equality_alloc(isl_basic_map_get_dim(bmap));
+
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_in, i, v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_out, i, v);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+
+ isl_int_clear(v);
+ }
+
+ // Set the last dimension of the input to be strict smaller than the
+ // last dimension of the output.
+ //
+ // input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
+ //
+ unsigned lastDimension = isl_basic_map_n_in(bmap) - 1;
+ isl_int v;
+ isl_int_init(v);
+ isl_constraint *c = isl_inequality_alloc(isl_basic_map_get_dim(bmap));
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_in, lastDimension, v);
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_out, lastDimension, v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_constant(c, v);
+ isl_int_clear(v);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+
+ return isl_map_from_basic_map(bmap);
+}
+
+isl_set *MemoryAccess::getStride(const isl_set *domainSubset) const {
+ isl_map *accessRelation = isl_map_copy(getAccessFunction());
+ isl_set *scatteringDomain = isl_set_copy(const_cast<isl_set*>(domainSubset));
+ isl_map *scattering = isl_map_copy(getStatement()->getScattering());
+
+ scattering = isl_map_reverse(scattering);
+ int difference = isl_map_n_in(scattering) - isl_set_n_dim(scatteringDomain);
+ scattering = isl_map_project_out(scattering, isl_dim_in,
+ isl_set_n_dim(scatteringDomain),
+ difference);
+
+ // Remove all names of the scattering dimensions, as the names may be lost
+ // anyways during the project. This leads to consistent results.
+ scattering = isl_map_set_tuple_name(scattering, isl_dim_in, "");
+ scatteringDomain = isl_set_set_tuple_name(scatteringDomain, "");
+
+ isl_map *nextScatt = getEqualAndLarger(isl_set_get_dim(scatteringDomain));
+ nextScatt = isl_map_lexmin(nextScatt);
+
+ scattering = isl_map_intersect_domain(scattering, scatteringDomain);
+
+ nextScatt = isl_map_apply_range(nextScatt, isl_map_copy(scattering));
+ nextScatt = isl_map_apply_range(nextScatt, isl_map_copy(accessRelation));
+ nextScatt = isl_map_apply_domain(nextScatt, scattering);
+ nextScatt = isl_map_apply_domain(nextScatt, accessRelation);
+
+ return isl_map_deltas(nextScatt);
+}
+
+bool MemoryAccess::isStrideZero(const isl_set *domainSubset) const {
+ isl_set *stride = getStride(domainSubset);
+ isl_constraint *c = isl_equality_alloc(isl_set_get_dim(stride));
+
+ isl_int v;
+ isl_int_init(v);
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
+ isl_int_set_si(v, 0);
+ isl_constraint_set_constant(c, v);
+ isl_int_clear(v);
+
+ isl_basic_set *bset = isl_basic_set_universe(isl_set_get_dim(stride));
+
+ bset = isl_basic_set_add_constraint(bset, c);
+ isl_set *strideZero = isl_set_from_basic_set(bset);
+
+ return isl_set_is_equal(stride, strideZero);
+}
+
+bool MemoryAccess::isStrideOne(const isl_set *domainSubset) const {
+ isl_set *stride = getStride(domainSubset);
+ isl_constraint *c = isl_equality_alloc(isl_set_get_dim(stride));
+
+ isl_int v;
+ isl_int_init(v);
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_set, 0, v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_constant(c, v);
+ isl_int_clear(v);
+
+ isl_basic_set *bset = isl_basic_set_universe(isl_set_get_dim(stride));
+
+ bset = isl_basic_set_add_constraint(bset, c);
+ isl_set *strideZero = isl_set_from_basic_set(bset);
+
+ return isl_set_is_equal(stride, strideZero);
+}
+
+
+//===----------------------------------------------------------------------===//
+void ScopStmt::buildScattering(SmallVectorImpl<unsigned> &Scatter) {
+ unsigned NumberOfIterators = getNumIterators();
+ unsigned ScatDim = Parent.getMaxLoopDepth() * 2 + 1;
+ isl_dim *dim = isl_dim_alloc(Parent.getCtx(), Parent.getNumParams(),
+ NumberOfIterators, ScatDim);
+ dim = isl_dim_set_tuple_name(dim, isl_dim_out, "scattering");
+ dim = isl_dim_set_tuple_name(dim, isl_dim_in, getBaseName());
+ isl_basic_map *bmap = isl_basic_map_universe(isl_dim_copy(dim));
+ isl_int v;
+ isl_int_init(v);
+
+ // Loop dimensions.
+ for (unsigned i = 0; i < NumberOfIterators; ++i) {
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_out, 2 * i + 1, v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_in, i, v);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ }
+
+ // Constant dimensions
+ for (unsigned i = 0; i < NumberOfIterators + 1; ++i) {
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_out, 2 * i, v);
+ isl_int_set_si(v, Scatter[i]);
+ isl_constraint_set_constant(c, v);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ }
+
+ // Fill scattering dimensions.
+ for (unsigned i = 2 * NumberOfIterators + 1; i < ScatDim ; ++i) {
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_out, i, v);
+ isl_int_set_si(v, 0);
+ isl_constraint_set_constant(c, v);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ }
+
+ isl_int_clear(v);
+ isl_dim_free(dim);
+ Scattering = isl_map_from_basic_map(bmap);
+}
+
+void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) {
+ const AccFuncSetType *AccFuncs = tempScop.getAccessFunctions(BB);
+
+ for (AccFuncSetType::const_iterator I = AccFuncs->begin(),
+ E = AccFuncs->end(); I != E; ++I) {
+ MemAccs.push_back(new MemoryAccess(I->first, this));
+ InstructionToAccess[I->second] = MemAccs.back();
+ }
+}
+
+static isl_map *MapValueToLHS(isl_ctx *Context, unsigned ParameterNumber) {
+ std::string MapString;
+ isl_map *Map;
+
+ MapString = "{[i0] -> [i0, o1]}";
+ Map = isl_map_read_from_str(Context, MapString.c_str(), -1);
+ return isl_map_add_dims(Map, isl_dim_param, ParameterNumber);
+}
+
+static isl_map *MapValueToRHS(isl_ctx *Context, unsigned ParameterNumber) {
+ std::string MapString;
+ isl_map *Map;
+
+ MapString = "{[i0] -> [o0, i0]}";
+ Map = isl_map_read_from_str(Context, MapString.c_str(), -1);
+ return isl_map_add_dims(Map, isl_dim_param, ParameterNumber);
+}
+
+static isl_set *getComparison(isl_ctx *Context, const ICmpInst::Predicate Pred,
+ unsigned ParameterNumber) {
+ std::string SetString;
+
+ switch (Pred) {
+ case ICmpInst::ICMP_EQ:
+ SetString = "{[i0, i1] : i0 = i1}";
+ break;
+ case ICmpInst::ICMP_NE:
+ SetString = "{[i0, i1] : i0 + 1 <= i1; [i0, i1] : i0 - 1 >= i1}";
+ break;
+ case ICmpInst::ICMP_SLT:
+ SetString = "{[i0, i1] : i0 + 1 <= i1}";
+ break;
+ case ICmpInst::ICMP_ULT:
+ SetString = "{[i0, i1] : i0 + 1 <= i1}";
+ break;
+ case ICmpInst::ICMP_SGT:
+ SetString = "{[i0, i1] : i0 >= i1 + 1}";
+ break;
+ case ICmpInst::ICMP_UGT:
+ SetString = "{[i0, i1] : i0 >= i1 + 1}";
+ break;
+ case ICmpInst::ICMP_SLE:
+ SetString = "{[i0, i1] : i0 <= i1}";
+ break;
+ case ICmpInst::ICMP_ULE:
+ SetString = "{[i0, i1] : i0 <= i1}";
+ break;
+ case ICmpInst::ICMP_SGE:
+ SetString = "{[i0, i1] : i0 >= i1}";
+ break;
+ case ICmpInst::ICMP_UGE:
+ SetString = "{[i0, i1] : i0 >= i1}";
+ break;
+ default:
+ llvm_unreachable("Non integer predicate not supported");
+ }
+
+ isl_set *Set = isl_set_read_from_str(Context, SetString.c_str(), -1);
+ return isl_set_add_dims(Set, isl_dim_param, ParameterNumber);
+}
+
+static isl_set *compareValues(isl_map *LeftValue, isl_map *RightValue,
+ const ICmpInst::Predicate Predicate) {
+ isl_ctx *Context = isl_map_get_ctx(LeftValue);
+ unsigned NumberOfParameters = isl_map_n_param(LeftValue);
+
+ isl_map *MapToLHS = MapValueToLHS(Context, NumberOfParameters);
+ isl_map *MapToRHS = MapValueToRHS(Context, NumberOfParameters);
+
+ isl_map *LeftValueAtLHS = isl_map_apply_range(LeftValue, MapToLHS);
+ isl_map *RightValueAtRHS = isl_map_apply_range(RightValue, MapToRHS);
+
+ isl_map *BothValues = isl_map_intersect(LeftValueAtLHS, RightValueAtRHS);
+ isl_set *Comparison = getComparison(Context, Predicate, NumberOfParameters);
+
+ isl_map *ComparedValues = isl_map_intersect_range(BothValues, Comparison);
+ return isl_map_domain(ComparedValues);
+}
+
+isl_set *ScopStmt::toConditionSet(const Comparison &Comp, isl_dim *dim) const {
+ isl_map *LHSValue = getValueOf(*Comp.getLHS(), this, dim);
+ isl_map *RHSValue = getValueOf(*Comp.getRHS(), this, dim);
+
+ return compareValues(LHSValue, RHSValue, Comp.getPred());
+}
+
+isl_set *ScopStmt::toUpperLoopBound(const SCEVAffFunc &UpperBound, isl_dim *dim,
+ unsigned BoundedDimension) const {
+ // Set output dimension to bounded dimension.
+ isl_dim *RHSDim = isl_dim_alloc(Parent.getCtx(), getNumParams(),
+ getNumIterators(), 1);
+ RHSDim = isl_dim_set_tuple_name(RHSDim, isl_dim_in, getBaseName());
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(RHSDim));
+ isl_int v;
+ isl_int_init(v);
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_in, BoundedDimension, v);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_out, 0, v);
+ isl_int_clear(v);
+ isl_basic_map *bmap = isl_basic_map_universe(RHSDim);
+ bmap = isl_basic_map_add_constraint(bmap, c);
+
+ isl_map *LHSValue = isl_map_from_basic_map(bmap);
+
+ isl_map *RHSValue = getValueOf(UpperBound, this, dim);
+
+ return compareValues(LHSValue, RHSValue, ICmpInst::ICMP_SLE);
+}
+
+void ScopStmt::buildIterationDomainFromLoops(TempScop &tempScop) {
+ isl_dim *dim = isl_dim_set_alloc(Parent.getCtx(), getNumParams(),
+ getNumIterators());
+ dim = isl_dim_set_tuple_name(dim, isl_dim_set, getBaseName());
+
+ Domain = isl_set_universe(isl_dim_copy(dim));
+
+ isl_int v;
+ isl_int_init(v);
+
+ for (int i = 0, e = getNumIterators(); i != e; ++i) {
+ // Lower bound: IV >= 0.
+ isl_basic_set *bset = isl_basic_set_universe(isl_dim_copy(dim));
+ isl_constraint *c = isl_inequality_alloc(isl_dim_copy(dim));
+ isl_int_set_si(v, 1);
+ isl_constraint_set_coefficient(c, isl_dim_set, i, v);
+ bset = isl_basic_set_add_constraint(bset, c);
+ Domain = isl_set_intersect(Domain, isl_set_from_basic_set(bset));
+
+ // Upper bound: IV <= NumberOfIterations.
+ const Loop *L = getSCEVForDimension(i)->getLoop();
+ const SCEVAffFunc &UpperBound = tempScop.getLoopBound(L);
+ isl_set *UpperBoundSet = toUpperLoopBound(UpperBound, isl_dim_copy(dim), i);
+ Domain = isl_set_intersect(Domain, UpperBoundSet);
+ }
+
+ isl_int_clear(v);
+}
+
+void ScopStmt::addConditionsToDomain(TempScop &tempScop,
+ const Region &CurRegion) {
+ isl_dim *dim = isl_set_get_dim(Domain);
+ const Region *TopR = tempScop.getMaxRegion().getParent(),
+ *CurR = &CurRegion;
+ const BasicBlock *CurEntry = BB;
+
+ // Build BB condition constrains, by traveling up the region tree.
+ do {
+ assert(CurR && "We exceed the top region?");
+ // Skip when multiple regions share the same entry.
+ if (CurEntry != CurR->getEntry()) {
+ if (const BBCond *Cnd = tempScop.getBBCond(CurEntry))
+ for (BBCond::const_iterator I = Cnd->begin(), E = Cnd->end();
+ I != E; ++I) {
+ isl_set *c = toConditionSet(*I, dim);
+ Domain = isl_set_intersect(Domain, c);
+ }
+ }
+ CurEntry = CurR->getEntry();
+ CurR = CurR->getParent();
+ } while (TopR != CurR);
+
+ isl_dim_free(dim);
+}
+
+void ScopStmt::buildIterationDomain(TempScop &tempScop, const Region &CurRegion)
+{
+ buildIterationDomainFromLoops(tempScop);
+ addConditionsToDomain(tempScop, CurRegion);
+}
+
+ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop,
+ const Region &CurRegion, BasicBlock &bb,
+ SmallVectorImpl<Loop*> &NestLoops,
+ SmallVectorImpl<unsigned> &Scatter)
+ : Parent(parent), BB(&bb), IVS(NestLoops.size()) {
+ // Setup the induction variables.
+ for (unsigned i = 0, e = NestLoops.size(); i < e; ++i) {
+ PHINode *PN = NestLoops[i]->getCanonicalInductionVariable();
+ assert(PN && "Non canonical IV in Scop!");
+ IVS[i] = PN;
+ }
+
+ raw_string_ostream OS(BaseName);
+ WriteAsOperand(OS, &bb, false);
+ BaseName = OS.str();
+
+ // Remove the % in the name. This is not supported by isl.
+ BaseName.erase(0, 1);
+ makeIslCompatible(BaseName);
+ BaseName = "Stmt_" + BaseName;
+
+ buildIterationDomain(tempScop, CurRegion);
+ buildScattering(Scatter);
+ buildAccesses(tempScop, CurRegion);
+
+ IsReduction = tempScop.is_Reduction(*BB);
+}
+
+ScopStmt::ScopStmt(Scop &parent, SmallVectorImpl<unsigned> &Scatter)
+ : Parent(parent), BB(NULL), IVS(0) {
+
+ BaseName = "FinalRead";
+
+ // Build iteration domain.
+ std::string IterationDomainString = "{[i0] : i0 = 0}";
+ Domain = isl_set_read_from_str(Parent.getCtx(), IterationDomainString.c_str(),
+ -1);
+ Domain = isl_set_add_dims(Domain, isl_dim_param, Parent.getNumParams());
+ Domain = isl_set_set_tuple_name(Domain, getBaseName());
+
+ // Build scattering.
+ unsigned ScatDim = Parent.getMaxLoopDepth() * 2 + 1;
+ isl_dim *dim = isl_dim_alloc(Parent.getCtx(), Parent.getNumParams(), 1,
+ ScatDim);
+ dim = isl_dim_set_tuple_name(dim, isl_dim_out, "scattering");
+ dim = isl_dim_set_tuple_name(dim, isl_dim_in, getBaseName());
+ isl_basic_map *bmap = isl_basic_map_universe(isl_dim_copy(dim));
+ isl_int v;
+ isl_int_init(v);
+
+ isl_constraint *c = isl_equality_alloc(dim);
+ isl_int_set_si(v, -1);
+ isl_constraint_set_coefficient(c, isl_dim_out, 0, v);
+
+ // TODO: This is incorrect. We should not use a very large number to ensure
+ // that this statement is executed last.
+ isl_int_set_si(v, 200000000);
+ isl_constraint_set_constant(c, v);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ isl_int_clear(v);
+ Scattering = isl_map_from_basic_map(bmap);
+
+ // Build memory accesses, use SetVector to keep the order of memory accesses
+ // and prevent the same memory access inserted more than once.
+ SetVector<const Value*> BaseAddressSet;
+
+ for (Scop::const_iterator SI = Parent.begin(), SE = Parent.end(); SI != SE;
+ ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ for (MemoryAccessVec::const_iterator I = Stmt->memacc_begin(),
+ E = Stmt->memacc_end(); I != E; ++I)
+ BaseAddressSet.insert((*I)->getBaseAddr());
+ }
+
+ for (SetVector<const Value*>::iterator BI = BaseAddressSet.begin(),
+ BE = BaseAddressSet.end(); BI != BE; ++BI)
+ MemAccs.push_back(new MemoryAccess(*BI, this));
+
+ IsReduction = false;
+}
+
+std::string ScopStmt::getDomainStr() const {
+ return stringFromIslObj(getDomain());
+}
+
+std::string ScopStmt::getScatteringStr() const {
+ return stringFromIslObj(getScattering());
+}
+
+unsigned ScopStmt::getNumParams() const {
+ return Parent.getNumParams();
+}
+
+unsigned ScopStmt::getNumIterators() const {
+ // The final read has one dimension with one element.
+ if (!BB)
+ return 1;
+
+ return IVS.size();
+}
+
+unsigned ScopStmt::getNumScattering() const {
+ return isl_map_dim(Scattering, isl_dim_out);
+}
+
+const char *ScopStmt::getBaseName() const { return BaseName.c_str(); }
+
+const PHINode *ScopStmt::getInductionVariableForDimension(unsigned Dimension)
+ const {
+ return IVS[Dimension];
+}
+
+const SCEVAddRecExpr *ScopStmt::getSCEVForDimension(unsigned Dimension)
+ const {
+ PHINode *PN = IVS[Dimension];
+ return cast<SCEVAddRecExpr>(getParent()->getSE()->getSCEV(PN));
+}
+
+isl_ctx *ScopStmt::getIslContext() {
+ return Parent.getCtx();
+}
+
+ScopStmt::~ScopStmt() {
+ while (!MemAccs.empty()) {
+ delete MemAccs.back();
+ MemAccs.pop_back();
+ }
+
+ isl_set_free(Domain);
+ isl_map_free(Scattering);
+}
+
+void ScopStmt::print(raw_ostream &OS) const {
+ OS << "\t" << getBaseName() << "\n";
+
+ OS.indent(12) << "Domain :=\n";
+
+ if (Domain) {
+ OS.indent(16) << getDomainStr() << ";\n";
+ } else
+ OS.indent(16) << "n/a\n";
+
+ OS.indent(12) << "Scattering :=\n";
+
+ if (Domain) {
+ OS.indent(16) << getScatteringStr() << ";\n";
+ } else
+ OS.indent(16) << "n/a\n";
+
+ for (MemoryAccessVec::const_iterator I = MemAccs.begin(), E = MemAccs.end();
+ I != E; ++I)
+ (*I)->print(OS);
+}
+
+void ScopStmt::dump() const { print(dbgs()); }
+
+//===----------------------------------------------------------------------===//
+/// Scop class implement
+Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution)
+ : SE(&ScalarEvolution), R(tempScop.getMaxRegion()),
+ MaxLoopDepth(tempScop.getMaxLoopDepth()) {
+ isl_ctx *ctx = isl_ctx_alloc();
+
+ ParamSetType &Params = tempScop.getParamSet();
+ Parameters.insert(Parameters.begin(), Params.begin(), Params.end());
+
+ isl_dim *dim = isl_dim_set_alloc(ctx, getNumParams(), 0);
+
+ // TODO: Insert relations between parameters.
+ // TODO: Insert constraints on parameters.
+ Context = isl_set_universe (dim);
+
+ SmallVector<Loop*, 8> NestLoops;
+ SmallVector<unsigned, 8> Scatter;
+
+ Scatter.assign(MaxLoopDepth + 1, 0);
+
+ // Build the iteration domain, access functions and scattering functions
+ // traversing the region tree.
+ buildScop(tempScop, getRegion(), NestLoops, Scatter, LI);
+ Stmts.push_back(new ScopStmt(*this, Scatter));
+
+ assert(NestLoops.empty() && "NestLoops not empty at top level!");
+}
+
+Scop::~Scop() {
+ isl_set_free(Context);
+
+ // Free the statements;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ delete *I;
+
+ // Do we need a singleton to manage this?
+ //isl_ctx_free(ctx);
+}
+
+std::string Scop::getContextStr() const {
+ return stringFromIslObj(getContext());
+}
+
+std::string Scop::getNameStr() const {
+ std::string ExitName, EntryName;
+ raw_string_ostream ExitStr(ExitName);
+ raw_string_ostream EntryStr(EntryName);
+
+ WriteAsOperand(EntryStr, R.getEntry(), false);
+ EntryStr.str();
+
+ if (R.getExit()) {
+ WriteAsOperand(ExitStr, R.getExit(), false);
+ ExitStr.str();
+ } else
+ ExitName = "FunctionExit";
+
+ return EntryName + "---" + ExitName;
+}
+
+void Scop::printContext(raw_ostream &OS) const {
+ OS << "Context:\n";
+
+ if (!Context) {
+ OS.indent(4) << "n/a\n\n";
+ return;
+ }
+
+ OS.indent(4) << getContextStr() << "\n";
+}
+
+void Scop::printStatements(raw_ostream &OS) const {
+ OS << "Statements {\n";
+
+ for (const_iterator SI = begin(), SE = end();SI != SE; ++SI)
+ OS.indent(4) << (**SI);
+
+ OS.indent(4) << "}\n";
+}
+
+
+void Scop::print(raw_ostream &OS) const {
+ printContext(OS.indent(4));
+ printStatements(OS.indent(4));
+}
+
+void Scop::dump() const { print(dbgs()); }
+
+isl_ctx *Scop::getCtx() const { return isl_set_get_ctx(Context); }
+
+ScalarEvolution *Scop::getSE() const { return SE; }
+
+bool Scop::isTrivialBB(BasicBlock *BB, TempScop &tempScop) {
+ if (tempScop.getAccessFunctions(BB))
+ return false;
+
+ return true;
+}
+
+void Scop::buildScop(TempScop &tempScop,
+ const Region &CurRegion,
+ SmallVectorImpl<Loop*> &NestLoops,
+ SmallVectorImpl<unsigned> &Scatter,
+ LoopInfo &LI) {
+ Loop *L = castToLoop(CurRegion, LI);
+
+ if (L)
+ NestLoops.push_back(L);
+
+ unsigned loopDepth = NestLoops.size();
+ assert(Scatter.size() > loopDepth && "Scatter not big enough!");
+
+ for (Region::const_element_iterator I = CurRegion.element_begin(),
+ E = CurRegion.element_end(); I != E; ++I)
+ if (I->isSubRegion())
+ buildScop(tempScop, *(I->getNodeAs<Region>()), NestLoops, Scatter, LI);
+ else {
+ BasicBlock *BB = I->getNodeAs<BasicBlock>();
+
+ if (isTrivialBB(BB, tempScop))
+ continue;
+
+ Stmts.push_back(new ScopStmt(*this, tempScop, CurRegion, *BB, NestLoops,
+ Scatter));
+
+ // Increasing the Scattering function is OK for the moment, because
+ // we are using a depth first iterator and the program is well structured.
+ ++Scatter[loopDepth];
+ }
+
+ if (!L)
+ return;
+
+ // Exiting a loop region.
+ Scatter[loopDepth] = 0;
+ NestLoops.pop_back();
+ ++Scatter[loopDepth-1];
+}
+
+//===----------------------------------------------------------------------===//
+
+void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<LoopInfo>();
+ AU.addRequired<RegionInfo>();
+ AU.addRequired<ScalarEvolution>();
+ AU.addRequired<TempScopInfo>();
+ AU.setPreservesAll();
+}
+
+bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
+ LoopInfo &LI = getAnalysis<LoopInfo>();
+ ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
+
+ TempScop *tempScop = getAnalysis<TempScopInfo>().getTempScop(R);
+
+ // This region is no Scop.
+ if (!tempScop) {
+ scop = 0;
+ return false;
+ }
+
+ // Statistics.
+ ++ScopFound;
+ if (tempScop->getMaxLoopDepth() > 0) ++RichScopFound;
+
+ scop = new Scop(*tempScop, LI, SE);
+
+ return false;
+}
+
+char ScopInfo::ID = 0;
+
+
+static RegisterPass<ScopInfo>
+X("polly-scops", "Polly - Create polyhedral description of Scops");
+
+Pass *polly::createScopInfoPass() {
+ return new ScopInfo();
+}
--- /dev/null
+//===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the definitions of the ScopPass members.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/ScopPass.h"
+#include "polly/ScopInfo.h"
+
+using namespace llvm;
+using namespace polly;
+
+bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) {
+ S = 0;
+
+ if ((S = getAnalysis<ScopInfo>().getScop()))
+ return runOnScop(*S);
+
+ return false;
+}
+
+isl_ctx *ScopPass::getIslContext() {
+ assert(S && "Not in on a Scop!");
+ return S->getCtx();
+}
+
+void ScopPass::print(raw_ostream &OS, const Module *M) const {
+ if (S)
+ printScop(OS);
+}
+
+void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<ScopInfo>();
+ AU.setPreservesAll();
+}
--- /dev/null
+//===---------- TempScopInfo.cpp - Extract TempScops ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect information about the control flow regions detected by the Scop
+// detection, such that this information can be translated info its polyhedral
+// representation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/TempScopInfo.h"
+
+#include "polly/LinkAllPasses.h"
+#include "polly/Support/AffineSCEVIterator.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/ScopHelper.h"
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/ADT/STLExtras.h"
+
+#define DEBUG_TYPE "polly-analyze-ir"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+using namespace polly;
+
+//===----------------------------------------------------------------------===//
+/// Helper Class
+
+SCEVAffFunc::SCEVAffFunc(const SCEV *S, SCEVAffFuncType Type, Region &R,
+ ParamSetType &Params, LoopInfo *LI,
+ ScalarEvolution *SE)
+ : ElemBytes(0), FuncType(Type), has_sign(true) {
+ assert(S && "S can not be null!");
+ assert(!isa<SCEVCouldNotCompute>(S) && "Non affine function in Scop");
+
+ for (AffineSCEVIterator I = affine_begin(S, SE), E = affine_end();
+ I != E; ++I) {
+ // The constant part must be a SCEVConstant.
+ // TODO: support sizeof in coefficient.
+ assert(isa<SCEVConstant>(I->second)
+ && "Expected SCEVConst in coefficient!");
+
+ const SCEV *Var = I->first;
+
+ if (isa<SCEVConstant>(Var)) // Extract the constant part.
+ // Add the translation component.
+ TransComp = I->second;
+ else if (Var->getType()->isPointerTy()) { // Extract the base address.
+ const SCEVUnknown *Addr = dyn_cast<SCEVUnknown>(Var);
+ assert(Addr && "Broken SCEV detected!");
+ BaseAddr = Addr->getValue();
+ } else { // Extract other affine components.
+ LnrTrans.insert(*I);
+
+ if (isIndVar(Var, R, *LI, *SE))
+ continue;
+
+ assert(isParameter(Var, R, *LI, *SE)
+ && "Found non affine function in Scop!");
+ Params.insert(Var);
+ }
+ }
+}
+
+void SCEVAffFunc::print(raw_ostream &OS, bool PrintInequality) const {
+ // Print BaseAddr.
+ if (isDataRef()) {
+ OS << (isRead() ? "Reads" : "Writes") << " ";
+ WriteAsOperand(OS, getBaseAddr(), false);
+ OS << "[";
+ }
+
+ for (LnrTransSet::const_iterator I = LnrTrans.begin(), E = LnrTrans.end();
+ I != E; ++I)
+ OS << *I->second << " * " << *I->first << " + ";
+
+ if (TransComp)
+ OS << *TransComp;
+
+ if (isDataRef())
+ OS << "]";
+
+ if (!PrintInequality)
+ return;
+
+ if (getType() == GE)
+ OS << " >= 0";
+ else if (getType() == Eq)
+ OS << " == 0";
+ else if (getType() == Ne)
+ OS << " != 0";
+}
+
+void SCEVAffFunc::dump() const {
+ print(errs());
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const SCEVAffFunc &AffFunc) {
+ AffFunc.print(OS);
+ return OS;
+}
+
+void Comparison::print(raw_ostream &OS) const {
+ // Not yet implemented.
+}
+
+/// Helper function to print the condition
+static void printBBCond(raw_ostream &OS, const BBCond &Cond) {
+ assert(!Cond.empty() && "Unexpected empty condition!");
+ Cond[0].print(OS);
+ for (unsigned i = 1, e = Cond.size(); i != e; ++i) {
+ OS << " && ";
+ Cond[i].print(OS);
+ }
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS, const BBCond &Cond) {
+ printBBCond(OS, Cond);
+ return OS;
+}
+
+//===----------------------------------------------------------------------===//
+// TempScop implementation
+TempScop::~TempScop() {
+ if (MayASInfo) delete MayASInfo;
+}
+
+void TempScop::print(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI) const {
+ OS << "Scop: " << R.getNameStr() << "\tParameters: (";
+ // Print Parameters.
+ for (ParamSetType::const_iterator PI = Params.begin(), PE = Params.end();
+ PI != PE; ++PI)
+ OS << **PI << ", ";
+
+ OS << "), Max Loop Depth: "<< MaxLoopDepth <<"\n";
+
+ printDetail(OS, SE, LI, &R, 0);
+}
+
+void TempScop::printDetail(llvm::raw_ostream &OS, ScalarEvolution *SE,
+ LoopInfo *LI, const Region *CurR,
+ unsigned ind) const {
+ // Print the loop bounds, if the current region is a loop.
+ LoopBoundMapType::const_iterator at = LoopBounds.find(castToLoop(*CurR, *LI));
+ if (at != LoopBounds.end()) {
+ OS.indent(ind) << "Bounds of Loop: " << at->first->getHeader()->getName()
+ << ":\t{ ";
+ at->second.print(OS, false);
+ OS << " }\n";
+ ind += 2;
+ }
+
+ // Iterate over the region nodes of this Scop to print the access functions
+ // and loop bounds.
+ for (Region::const_element_iterator I = CurR->element_begin(),
+ E = CurR->element_end(); I != E; ++I) {
+ if (I->isSubRegion()) {
+ Region *subR = I->getNodeAs<Region>();
+ printDetail(OS, SE, LI, subR, ind + 2);
+ } else {
+ BasicBlock *BB = I->getNodeAs<BasicBlock>();
+
+ if (const AccFuncSetType *AccFunc = getAccessFunctions(BB)) {
+ OS.indent(ind) << "BB: " << BB->getName() << "{\n";
+
+ for (AccFuncSetType::const_iterator FI = AccFunc->begin(),
+ FE = AccFunc->end(); FI != FE; ++FI) {
+ const SCEVAffFunc &AF = FI->first;
+ const Value *Ptr = AF.getBaseAddr();
+
+ OS.indent(ind + 2) << AF << " Refs: ";
+ for (MayAliasSetInfo::const_alias_iterator
+ MI = MayASInfo->alias_begin(Ptr), ME = MayASInfo->alias_end(Ptr);
+ MI != ME; ++MI) {
+ MI->second->print(OS);
+ OS << ", ";
+ }
+
+ OS << '\n';
+ }
+
+ if (Reductions.count(BB))
+ OS.indent(ind + 2) << "Reduction\n";
+
+ OS.indent(ind) << "}\n";
+ }
+ }
+ }
+}
+
+void TempScopInfo::buildAffineFunction(const SCEV *S, SCEVAffFunc &FuncToBuild,
+ Region &R, ParamSetType &Params) const {
+ assert(S && "S can not be null!");
+
+ assert(!isa<SCEVCouldNotCompute>(S)
+ && "Un Expect broken affine function in Scop!");
+
+ for (AffineSCEVIterator I = affine_begin(S, SE), E = affine_end();
+ I != E; ++I) {
+ // The constant part must be a SCEVConstant.
+ // TODO: support sizeof in coefficient.
+ assert(isa<SCEVConstant>(I->second) && "Expect SCEVConst in coefficient!");
+
+ const SCEV *Var = I->first;
+ // Extract the constant part
+ if (isa<SCEVConstant>(Var))
+ // Add the translation component
+ FuncToBuild.TransComp = I->second;
+ else if (Var->getType()->isPointerTy()) { // Extract the base address
+ const SCEVUnknown *BaseAddr = dyn_cast<SCEVUnknown>(Var);
+ assert(BaseAddr && "Why we got a broken scev?");
+ FuncToBuild.BaseAddr = BaseAddr->getValue();
+ } else { // Extract other affine components.
+ FuncToBuild.LnrTrans.insert(*I);
+ // Do not add the indvar to the parameter list.
+ if (!isIndVar(Var, R, *LI, *SE)) {
+ DEBUG(dbgs() << "Non indvar: "<< *Var << '\n');
+ assert(isParameter(Var, R, *LI, *SE)
+ && "Find non affine function in scop!");
+ Params.insert(Var);
+ }
+ }
+ }
+}
+
+bool TempScopInfo::isReduction(BasicBlock &BB) {
+ int loadAccess = 0, storeAccess = 0;
+ const StoreInst *storeInst;
+ const Value *storePointer;
+ const LoadInst *loadInst[2];
+ const Value *loadPointer[2];
+
+ for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) {
+ Instruction &Inst = *I;
+ if (isa<LoadInst>(&Inst)) {
+ if (loadAccess >= 2)
+ return false;
+ loadInst[loadAccess] = dyn_cast<LoadInst>(&Inst);
+ loadPointer[loadAccess] = loadInst[loadAccess]->getPointerOperand();
+ loadAccess++;
+ } else if (isa<StoreInst>(&Inst)) {
+ if (storeAccess >= 1)
+ return false;
+ storeInst = dyn_cast<StoreInst>(&Inst);
+ storePointer = storeInst->getPointerOperand();
+ storeAccess++;
+ }
+ }
+
+ if (loadAccess < 2)
+ return false;
+
+ if (loadPointer[0] == loadPointer[1])
+ return false;
+
+ const Value *reductionLoadInst;
+ if (storePointer == loadPointer[0])
+ reductionLoadInst = loadInst[0];
+ else if (storePointer == loadPointer[1])
+ reductionLoadInst = loadInst[1];
+ else
+ return false;
+
+ const Instruction *reductionInst =
+ dyn_cast<Instruction>(storeInst->getValueOperand());
+
+ // Check if the value stored is an instruction
+ if (!reductionInst)
+ return false;
+
+ // Reduction operations must be associative and commutative
+ if (!reductionInst->isAssociative() || !reductionInst->isCommutative())
+ return false;
+
+ // Check if this instruction is using the loaded value
+ for (User::const_op_iterator I = reductionInst->op_begin(),
+ E = reductionInst->op_end(); I != E; I++) {
+ const Value *operand = I->get();
+ if (operand == reductionLoadInst) {
+ // The loaded value's one and only use must be this one.
+ return operand->hasOneUse();
+ }
+ }
+
+ return false;
+}
+
+void TempScopInfo::buildAccessFunctions(Region &R, ParamSetType &Params,
+ BasicBlock &BB) {
+ AccFuncSetType Functions;
+ for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) {
+ Instruction &Inst = *I;
+ if (isa<LoadInst>(&Inst) || isa<StoreInst>(&Inst)) {
+ // Create the SCEVAffFunc.
+ if (LoadInst *ld = dyn_cast<LoadInst>(&Inst)) {
+ unsigned size = TD->getTypeStoreSize(ld->getType());
+ Functions.push_back(
+ std::make_pair(SCEVAffFunc(SCEVAffFunc::ReadMem, size), &Inst));
+ } else {//Else it must be a StoreInst.
+ StoreInst *st = cast<StoreInst>(&Inst);
+ unsigned size = TD->getTypeStoreSize(st->getValueOperand()->getType());
+ Functions.push_back(
+ std::make_pair(SCEVAffFunc(SCEVAffFunc::WriteMem, size), &Inst));
+ }
+
+ Value *Ptr = getPointerOperand(Inst);
+ buildAffineFunction(SE->getSCEV(Ptr), Functions.back().first, R, Params);
+ }
+ }
+
+ if (Functions.empty())
+ return;
+
+ AccFuncSetType &Accs = AccFuncMap[&BB];
+ Accs.insert(Accs.end(), Functions.begin(), Functions.end());
+}
+
+void TempScopInfo::buildLoopBounds(TempScop &Scop) {
+ Region &R = Scop.getMaxRegion();
+ unsigned MaxLoopDepth = 0;
+
+ for (Region::block_iterator I = R.block_begin(), E = R.block_end();
+ I != E; ++I) {
+ Loop *L = LI->getLoopFor(I->getNodeAs<BasicBlock>());
+
+ if (!L || !R.contains(L))
+ continue;
+
+ if (LoopBounds.find(L) != LoopBounds.end())
+ continue;
+
+ LoopBounds[L] = SCEVAffFunc(SCEVAffFunc::Eq);
+ const SCEV *LoopCount = SE->getBackedgeTakenCount(L);
+ buildAffineFunction(LoopCount, LoopBounds[L], Scop.getMaxRegion(),
+ Scop.getParamSet());
+
+ Loop *OL = R.outermostLoopInRegion(L);
+ unsigned LoopDepth = L->getLoopDepth() - OL->getLoopDepth() + 1;
+
+ if (LoopDepth > MaxLoopDepth)
+ MaxLoopDepth = LoopDepth;
+ }
+
+ Scop.MaxLoopDepth = MaxLoopDepth;
+}
+
+void TempScopInfo::buildAffineCondition(Value &V, bool inverted,
+ Comparison **Comp,
+ TempScop &Scop) const {
+ Region &R = Scop.getMaxRegion();
+ ParamSetType &Params = Scop.getParamSet();
+ if (ConstantInt *C = dyn_cast<ConstantInt>(&V)) {
+ // If this is always true condition, we will create 1 >= 0,
+ // otherwise we will create 1 == 0.
+ SCEVAffFunc *AffLHS = new SCEVAffFunc(SE->getConstant(C->getType(), 0),
+ SCEVAffFunc::Eq, R, Params, LI, SE);
+ SCEVAffFunc *AffRHS = new SCEVAffFunc(SE->getConstant(C->getType(), 1),
+ SCEVAffFunc::Eq, R, Params, LI, SE);
+ if (C->isOne() == inverted)
+ *Comp = new Comparison(AffRHS, AffLHS, ICmpInst::ICMP_NE);
+ else
+ *Comp = new Comparison(AffLHS, AffLHS, ICmpInst::ICMP_EQ);
+
+ return;
+ }
+
+ ICmpInst *ICmp = dyn_cast<ICmpInst>(&V);
+ assert(ICmp && "Only ICmpInst of constant as condition supported!");
+
+ const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0)),
+ *RHS = SE->getSCEV(ICmp->getOperand(1));
+
+ ICmpInst::Predicate Pred = ICmp->getPredicate();
+
+ // Invert the predicate if needed.
+ if (inverted)
+ Pred = ICmpInst::getInversePredicate(Pred);
+
+ SCEVAffFunc *AffLHS = new SCEVAffFunc(LHS, SCEVAffFunc::Eq, R, Params, LI,
+ SE);
+ SCEVAffFunc *AffRHS = new SCEVAffFunc(RHS, SCEVAffFunc::Eq, R, Params, LI,
+ SE);
+
+ switch (Pred) {
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_ULE:
+ // TODO: At the moment we need to see everything as signed. This is an
+ // correctness issue that needs to be solved.
+ //AffLHS->setUnsigned();
+ //AffRHS->setUnsigned();
+ break;
+ default:
+ break;
+ }
+
+ *Comp = new Comparison(AffLHS, AffRHS, Pred);
+}
+
+void TempScopInfo::buildCondition(BasicBlock *BB, BasicBlock *RegionEntry,
+ TempScop &Scop) {
+ BBCond Cond;
+
+ DomTreeNode *BBNode = DT->getNode(BB), *EntryNode = DT->getNode(RegionEntry);
+ assert(BBNode && EntryNode && "Get null node while building condition!");
+
+ // Walk up the dominance tree until reaching the entry node. Add all
+ // conditions on the path to BB except if BB postdominates the block
+ // containing the condition.
+ while (BBNode != EntryNode) {
+ BasicBlock *CurBB = BBNode->getBlock();
+ BBNode = BBNode->getIDom();
+ assert(BBNode && "BBNode should not reach the root node!");
+
+ if (PDT->dominates(CurBB, BBNode->getBlock()))
+ continue;
+
+ BranchInst *Br = dyn_cast<BranchInst>(BBNode->getBlock()->getTerminator());
+ assert(Br && "A Valid Scop should only contain branch instruction");
+
+ if (Br->isUnconditional())
+ continue;
+
+ // Is BB on the ELSE side of the branch?
+ bool inverted = DT->dominates(Br->getSuccessor(1), BB);
+
+ Comparison *Cmp;
+ buildAffineCondition(*(Br->getCondition()), inverted, &Cmp, Scop);
+ Cond.push_back(*Cmp);
+ }
+
+ if (!Cond.empty())
+ BBConds[BB] = Cond;
+}
+
+TempScop *TempScopInfo::buildTempScop(Region &R) {
+ TempScop *TScop = new TempScop(R, LoopBounds, BBConds, AccFuncMap);
+
+ for (Region::block_iterator I = R.block_begin(), E = R.block_end();
+ I != E; ++I) {
+ BasicBlock *BB = I->getNodeAs<BasicBlock>();
+ buildAccessFunctions(R, TScop->getParamSet(), *BB);
+ buildCondition(BB, R.getEntry(), *TScop);
+ if (isReduction(*BB))
+ TScop->Reductions.insert(BB);
+ }
+
+ buildLoopBounds(*TScop);
+
+ // Build the MayAliasSets.
+ TScop->MayASInfo->buildMayAliasSets(*TScop, *AA);
+ return TScop;
+}
+
+TempScop *TempScopInfo::getTempScop(const Region *R) const {
+ TempScopMapType::const_iterator at = TempScops.find(R);
+ return at == TempScops.end() ? 0 : at->second;
+}
+
+void TempScopInfo::print(raw_ostream &OS, const Module *) const {
+ for (TempScopMapType::const_iterator I = TempScops.begin(),
+ E = TempScops.end(); I != E; ++I)
+ I->second->print(OS, SE, LI);
+}
+
+bool TempScopInfo::runOnFunction(Function &F) {
+ DT = &getAnalysis<DominatorTree>();
+ PDT = &getAnalysis<PostDominatorTree>();
+ SE = &getAnalysis<ScalarEvolution>();
+ LI = &getAnalysis<LoopInfo>();
+ SD = &getAnalysis<ScopDetection>();
+ AA = &getAnalysis<AliasAnalysis>();
+ TD = &getAnalysis<TargetData>();
+
+ for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) {
+ Region *R = const_cast<Region*>(*I);
+ TempScops.insert(std::make_pair(R, buildTempScop(*R)));
+ }
+
+ return false;
+}
+
+void TempScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetData>();
+ AU.addRequiredTransitive<DominatorTree>();
+ AU.addRequiredTransitive<PostDominatorTree>();
+ AU.addRequiredTransitive<LoopInfo>();
+ AU.addRequiredTransitive<ScalarEvolution>();
+ AU.addRequiredTransitive<ScopDetection>();
+ AU.addRequiredID(IndependentBlocksID);
+ AU.addRequired<AliasAnalysis>();
+ AU.setPreservesAll();
+}
+
+TempScopInfo::~TempScopInfo() {
+ clear();
+}
+
+void TempScopInfo::clear() {
+ BBConds.clear();
+ LoopBounds.clear();
+ AccFuncMap.clear();
+ DeleteContainerSeconds(TempScops);
+ TempScops.clear();
+}
+
+//===----------------------------------------------------------------------===//
+// TempScop information extraction pass implement
+char TempScopInfo::ID = 0;
+
+static RegisterPass<TempScopInfo>
+X("polly-analyze-ir", "Polly - Analyse the LLVM-IR in the detected regions");
+
--- /dev/null
+add_subdirectory(Analysis)
+add_subdirectory(Support)
+add_subdirectory(JSON)
+
+set(MODULE TRUE)
+set(LLVM_NO_RTTI 1)
+
+if (OPENSCOP_FOUND)
+ set(POLLY_EXCHANGE_FILES
+ Exchange/OpenScopImporter.cpp Exchange/OpenScopExporter.cpp)
+endif (OPENSCOP_FOUND)
+if (SCOPLIB_FOUND)
+ set(POLLY_SCOPLIB_FILES
+ Pocc.cpp
+ Exchange/ScopLib.cpp
+ Exchange/ScopLibExporter.cpp
+ Exchange/ScopLibImporter.cpp)
+endif (SCOPLIB_FOUND)
+
+set(LLVM_USED_LIBS
+ PollyAnalysis
+ PollySupport
+ PollyJSON
+ )
+
+add_polly_library(LLVMPolly
+ Cloog.cpp
+ CodePreparation.cpp
+ CodeGeneration.cpp
+ IndependentBlocks.cpp
+ Interchange.cpp
+ MayAliasSet.cpp
+ Pocc.cpp
+ RegionSimplify.cpp
+ Exchange/JSONExporter.cpp
+ ${POLLY_EXCHANGE_FILES}
+ ${POLLY_SCOPLIB_FILES}
+ )
+
+add_dependencies(LLVMPolly
+ PollyAnalysis
+ PollySupport
+ PollyJSON
+ )
+
+set_target_properties(LLVMPolly
+ PROPERTIES
+ LINKER_LANGUAGE CXX
+ PREFIX "")
--- /dev/null
+//===- Cloog.cpp - Cloog interface ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Cloog[1] interface.
+//
+// The Cloog interface takes a Scop and generates a Cloog AST (clast). This
+// clast can either be returned directly or it can be pretty printed to stdout.
+//
+// A typical clast output looks like this:
+//
+// for (c2 = max(0, ceild(n + m, 2); c2 <= min(511, floord(5 * n, 3)); c2++) {
+// bb2(c2);
+// }
+//
+// [1] http://www.cloog.org/ - The Chunky Loop Generator
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Cloog.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopInfo.h"
+
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Module.h"
+
+#include "cloog/isl/domain.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace polly {
+class Cloog {
+ Scop *S;
+ CloogOptions *Options;
+ CloogState *State;
+ clast_stmt *ClastRoot;
+
+ void buildCloogOptions();
+ CloogUnionDomain *buildCloogUnionDomain();
+ CloogInput *buildCloogInput();
+
+public:
+ Cloog(Scop *Scop);
+
+ ~Cloog();
+
+ /// Write a .cloog input file
+ void dump(FILE *F);
+
+ /// Print a source code representation of the program.
+ void pprint(llvm::raw_ostream &OS);
+
+ /// Create the Cloog AST from this program.
+ struct clast_stmt *getClast();
+};
+
+Cloog::Cloog(Scop *Scop) : S(Scop) {
+ State = cloog_state_malloc();
+ buildCloogOptions();
+ ClastRoot = cloog_clast_create_from_input(buildCloogInput(), Options);
+}
+
+Cloog::~Cloog() {
+ cloog_options_free(Options);
+ cloog_clast_free(ClastRoot);
+ cloog_state_free(State);
+}
+
+// Create a FILE* write stream and get the output to it written
+// to a std::string.
+class FileToString {
+ int FD[2];
+ FILE *input;
+ static const int BUFFERSIZE = 20;
+
+ char buf[BUFFERSIZE + 1];
+
+
+public:
+ FileToString() {
+ pipe(FD);
+ input = fdopen(FD[1], "w");
+ }
+ ~FileToString() {
+ close(FD[0]);
+ //close(FD[1]);
+ }
+
+ FILE *getInputFile() {
+ return input;
+ }
+
+ void closeInput() {
+ fclose(input);
+ close(FD[1]);
+ }
+
+ std::string getOutput() {
+ std::string output;
+ int readSize;
+
+ while (true) {
+ readSize = read(FD[0], &buf, BUFFERSIZE);
+
+ if (readSize <= 0)
+ break;
+
+ output += std::string(buf, readSize);
+ }
+
+
+ return output;
+ }
+
+};
+
+/// Write .cloog input file.
+void Cloog::dump(FILE *F) {
+ CloogInput *Input = buildCloogInput();
+ cloog_input_dump_cloog(F, Input, Options);
+ cloog_input_free(Input);
+}
+
+/// Print a source code representation of the program.
+void Cloog::pprint(raw_ostream &OS) {
+ FileToString *Output = new FileToString();
+ clast_pprint(Output->getInputFile(), ClastRoot, 0, Options);
+ Output->closeInput();
+ OS << Output->getOutput();
+ delete (Output);
+}
+
+/// Create the Cloog AST from this program.
+struct clast_stmt *Cloog::getClast() {
+ return ClastRoot;
+}
+
+void Cloog::buildCloogOptions() {
+ Options = cloog_options_malloc(State);
+ Options->quiet = 1;
+ Options->strides = 1;
+ Options->save_domains = 1;
+ Options->noscalars = 1;
+}
+
+CloogUnionDomain *Cloog::buildCloogUnionDomain() {
+ CloogUnionDomain *DU = cloog_union_domain_alloc(S->getNumParams());
+
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ if (Stmt->isFinalRead())
+ continue;
+
+ CloogScattering *Scattering=
+ cloog_scattering_from_isl_map(isl_map_copy(Stmt->getScattering()));
+ CloogDomain *Domain =
+ cloog_domain_from_isl_set(isl_set_copy(Stmt->getDomain()));
+
+ std::string entryName = Stmt->getBaseName();
+ char *Name = (char*)malloc(sizeof(char) * (entryName.size() + 1));
+ strcpy(Name, entryName.c_str());
+
+ DU = cloog_union_domain_add_domain(DU, Name, Domain, Scattering, Stmt);
+ }
+
+ return DU;
+}
+
+CloogInput *Cloog::buildCloogInput() {
+ CloogDomain *Context =
+ cloog_domain_from_isl_set(isl_set_copy(S->getContext()));
+ CloogUnionDomain *Statements = buildCloogUnionDomain();
+ CloogInput *Input = cloog_input_alloc (Context, Statements);
+ return Input;
+}
+} // End namespace polly.
+
+namespace {
+
+struct CloogExporter : public ScopPass {
+ static char ID;
+ Scop *S;
+ explicit CloogExporter() : ScopPass(ID) {}
+
+ std::string getFileName(Region *R) const;
+ virtual bool runOnScop(Scop &S);
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+
+}
+std::string CloogExporter::getFileName(Region *R) const {
+ std::string FunctionName = R->getEntry()->getParent()->getNameStr();
+ std::string ExitName, EntryName;
+
+ raw_string_ostream ExitStr(ExitName);
+ raw_string_ostream EntryStr(EntryName);
+
+ WriteAsOperand(EntryStr, R->getEntry(), false);
+ EntryStr.str();
+
+ if (R->getExit()) {
+ WriteAsOperand(ExitStr, R->getExit(), false);
+ ExitStr.str();
+ } else
+ ExitName = "FunctionExit";
+
+ std::string RegionName = EntryName + "---" + ExitName;
+ std::string FileName = FunctionName + "___" + RegionName + ".cloog";
+
+ return FileName;
+}
+
+char CloogExporter::ID = 0;
+bool CloogExporter::runOnScop(Scop &S) {
+ Region &R = S.getRegion();
+ CloogInfo &C = getAnalysis<CloogInfo>();
+
+ std::string FunctionName = R.getEntry()->getParent()->getNameStr();
+ std::string Filename = getFileName(&R);
+
+ errs() << "Writing Scop '" << R.getNameStr() << "' in function '"
+ << FunctionName << "' to '" << Filename << "'...\n";
+
+ FILE *F = fopen(Filename.c_str(), "w");
+ C.dump(F);
+ fclose(F);
+
+ return false;
+}
+
+void CloogExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+ // Get the Common analysis usage of ScopPasses.
+ ScopPass::getAnalysisUsage(AU);
+ AU.addRequired<CloogInfo>();
+}
+
+static RegisterPass<CloogExporter> A("polly-export-cloog",
+ "Polly - Export the Cloog input file"
+ " (Writes a .cloog file for each Scop)"
+ );
+
+llvm::Pass* polly::createCloogExporterPass() {
+ return new CloogExporter();
+}
+
+/// Write a .cloog input file
+void CloogInfo::dump(FILE *F) {
+ C->dump(F);
+}
+
+/// Print a source code representation of the program.
+void CloogInfo::pprint(llvm::raw_ostream &OS) {
+ C->pprint(OS);
+}
+
+/// Create the Cloog AST from this program.
+const struct clast_stmt *CloogInfo::getClast() {
+ return C->getClast();
+}
+
+bool CloogInfo::runOnScop(Scop &S) {
+ if (C)
+ delete C;
+
+ scop = &S;
+
+ C = new Cloog(&S);
+
+ return false;
+}
+
+void CloogInfo::printScop(raw_ostream &OS) const {
+ Function *function = scop->getRegion().getEntry()->getParent();
+
+ OS << function->getNameStr() << "():\n";
+
+ C->pprint(OS);
+}
+
+void CloogInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+ // Get the Common analysis usage of ScopPasses.
+ ScopPass::getAnalysisUsage(AU);
+}
+char CloogInfo::ID = 0;
+
+
+static RegisterPass<CloogInfo> B("polly-cloog",
+ "Execute Cloog code generation");
+
+Pass* polly::createCloogInfoPass() {
+ return new CloogInfo();
+}
--- /dev/null
+//===------ CodeGeneration.cpp - Code generate the Scops. -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The CodeGeneration pass takes a Scop created by ScopInfo and translates it
+// back to LLVM-IR using Cloog.
+//
+// The Scop describes the high level memory behaviour of a control flow region.
+// Transformation passes can update the schedule (execution order) of statements
+// in the Scop. Cloog is used to generate an abstract syntax tree (clast) that
+// reflects the updated execution order. This clast is used to create new
+// LLVM-IR that is computational equivalent to the original control flow region,
+// but executes its code in the new execution order defined by the changed
+// scattering.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "polly-codegen"
+
+#include "polly/LinkAllPasses.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/ScopHelper.h"
+#include "polly/Cloog.h"
+#include "polly/Dependences.h"
+#include "polly/ScopInfo.h"
+#include "polly/TempScopInfo.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/SetVector.h"
+
+#define CLOOG_INT_GMP 1
+#include "cloog/cloog.h"
+#include "cloog/isl/cloog.h"
+
+#include <vector>
+#include <utility>
+
+using namespace polly;
+using namespace llvm;
+
+struct isl_set;
+
+namespace polly {
+
+static cl::opt<bool>
+Vector("enable-polly-vector",
+ cl::desc("Enable polly vector code generation"), cl::Hidden,
+ cl::value_desc("Vector code generation enabled if true"),
+ cl::init(false));
+
+static cl::opt<bool>
+OpenMP("enable-polly-openmp",
+ cl::desc("Generate OpenMP parallel code"), cl::Hidden,
+ cl::value_desc("OpenMP code generation enabled if true"),
+ cl::init(false));
+
+static cl::opt<bool>
+AtLeastOnce("enable-polly-atLeastOnce",
+ cl::desc("Give polly the hint, that every loop is executed at least"
+ "once"), cl::Hidden,
+ cl::value_desc("OpenMP code generation enabled if true"),
+ cl::init(false));
+
+static cl::opt<bool>
+Aligned("enable-polly-aligned",
+ cl::desc("Assumed aligned memory accesses."), cl::Hidden,
+ cl::value_desc("OpenMP code generation enabled if true"),
+ cl::init(false));
+
+static cl::opt<std::string>
+CodegenOnly("polly-codegen-only",
+ cl::desc("Codegen only this function"), cl::Hidden,
+ cl::value_desc("The function name to codegen"),
+ cl::ValueRequired, cl::init(""));
+
+typedef DenseMap<const Value*, Value*> ValueMapT;
+typedef DenseMap<const char*, Value*> CharMapT;
+typedef std::vector<ValueMapT> VectorValueMapT;
+
+// Create a new loop.
+//
+// @param Builder The builder used to create the loop. It also defines the
+// place where to create the loop.
+// @param UB The upper bound of the loop iv.
+// @param Stride The number by which the loop iv is incremented after every
+// iteration.
+static void createLoop(IRBuilder<> *Builder, Value *LB, Value *UB, APInt Stride,
+ PHINode*& IV, BasicBlock*& AfterBB, Value*& IncrementedIV,
+ DominatorTree *DT) {
+ Function *F = Builder->GetInsertBlock()->getParent();
+ LLVMContext &Context = F->getContext();
+
+ BasicBlock *PreheaderBB = Builder->GetInsertBlock();
+ BasicBlock *HeaderBB = BasicBlock::Create(Context, "polly.loop_header", F);
+ BasicBlock *BodyBB = BasicBlock::Create(Context, "polly.loop_body", F);
+ AfterBB = BasicBlock::Create(Context, "polly.after_loop", F);
+
+ Builder->CreateBr(HeaderBB);
+ DT->addNewBlock(HeaderBB, PreheaderBB);
+
+ Builder->SetInsertPoint(BodyBB);
+
+ Builder->SetInsertPoint(HeaderBB);
+
+ // Use the type of upper and lower bound.
+ assert(LB->getType() == UB->getType()
+ && "Different types for upper and lower bound.");
+
+ const IntegerType *LoopIVType = dyn_cast<IntegerType>(UB->getType());
+ assert(LoopIVType && "UB is not integer?");
+
+ // IV
+ IV = Builder->CreatePHI(LoopIVType, 2, "polly.loopiv");
+ IV->addIncoming(LB, PreheaderBB);
+
+ // IV increment.
+ Value *StrideValue = ConstantInt::get(LoopIVType,
+ Stride.zext(LoopIVType->getBitWidth()));
+ IncrementedIV = Builder->CreateAdd(IV, StrideValue, "polly.next_loopiv");
+
+ // Exit condition.
+ if (AtLeastOnce) { // At least on iteration.
+ UB = Builder->CreateAdd(UB, Builder->getInt64(1));
+ Value *CMP = Builder->CreateICmpEQ(IV, UB);
+ Builder->CreateCondBr(CMP, AfterBB, BodyBB);
+ } else { // Maybe not executed at all.
+ Value *CMP = Builder->CreateICmpSLE(IV, UB);
+ Builder->CreateCondBr(CMP, BodyBB, AfterBB);
+ }
+ DT->addNewBlock(BodyBB, HeaderBB);
+ DT->addNewBlock(AfterBB, HeaderBB);
+
+ Builder->SetInsertPoint(BodyBB);
+}
+
+class BlockGenerator {
+ IRBuilder<> &Builder;
+ ValueMapT &VMap;
+ VectorValueMapT &ValueMaps;
+ Scop &S;
+ ScopStmt &statement;
+ isl_set *scatteringDomain;
+
+public:
+ BlockGenerator(IRBuilder<> &B, ValueMapT &vmap, VectorValueMapT &vmaps,
+ ScopStmt &Stmt, isl_set *domain)
+ : Builder(B), VMap(vmap), ValueMaps(vmaps), S(*Stmt.getParent()),
+ statement(Stmt), scatteringDomain(domain) {}
+
+ const Region &getRegion() {
+ return S.getRegion();
+ }
+
+ Value* makeVectorOperand(Value *operand, int vectorWidth) {
+ if (operand->getType()->isVectorTy())
+ return operand;
+
+ VectorType *vectorType = VectorType::get(operand->getType(), vectorWidth);
+ Value *vector = UndefValue::get(vectorType);
+ vector = Builder.CreateInsertElement(vector, operand, Builder.getInt32(0));
+
+ std::vector<Constant*> splat;
+
+ for (int i = 0; i < vectorWidth; i++)
+ splat.push_back (Builder.getInt32(0));
+
+ Constant *splatVector = ConstantVector::get(splat);
+
+ return Builder.CreateShuffleVector(vector, vector, splatVector);
+ }
+
+ Value* getOperand(const Value *OldOperand, ValueMapT &BBMap,
+ ValueMapT *VectorMap = 0) {
+ const Instruction *OpInst = dyn_cast<Instruction>(OldOperand);
+
+ if (!OpInst)
+ return const_cast<Value*>(OldOperand);
+
+ if (VectorMap && VectorMap->count(OldOperand))
+ return (*VectorMap)[OldOperand];
+
+ // IVS and Parameters.
+ if (VMap.count(OldOperand)) {
+ Value *NewOperand = VMap[OldOperand];
+
+ // Insert a cast if types are different
+ if (OldOperand->getType()->getScalarSizeInBits()
+ < NewOperand->getType()->getScalarSizeInBits())
+ NewOperand = Builder.CreateTruncOrBitCast(NewOperand,
+ OldOperand->getType());
+
+ return NewOperand;
+ }
+
+ // Instructions calculated in the current BB.
+ if (BBMap.count(OldOperand)) {
+ return BBMap[OldOperand];
+ }
+
+ // Ignore instructions that are referencing ops in the old BB. These
+ // instructions are unused. They where replace by new ones during
+ // createIndependentBlocks().
+ if (getRegion().contains(OpInst->getParent()))
+ return NULL;
+
+ return const_cast<Value*>(OldOperand);
+ }
+
+ const Type *getVectorPtrTy(const Value *V, int vectorWidth) {
+ const PointerType *pointerType = dyn_cast<PointerType>(V->getType());
+ assert(pointerType && "PointerType expected");
+
+ const Type *scalarType = pointerType->getElementType();
+ VectorType *vectorType = VectorType::get(scalarType, vectorWidth);
+
+ return PointerType::getUnqual(vectorType);
+ }
+
+ /// @brief Load a vector from a set of adjacent scalars
+ ///
+ /// In case a set of scalars is known to be next to each other in memory,
+ /// create a vector load that loads those scalars
+ ///
+ /// %vector_ptr= bitcast double* %p to <4 x double>*
+ /// %vec_full = load <4 x double>* %vector_ptr
+ ///
+ Value *generateStrideOneLoad(const LoadInst *load, ValueMapT &BBMap,
+ int size) {
+ const Value *pointer = load->getPointerOperand();
+ const Type *vectorPtrType = getVectorPtrTy(pointer, size);
+ Value *newPointer = getOperand(pointer, BBMap);
+ Value *VectorPtr = Builder.CreateBitCast(newPointer, vectorPtrType,
+ "vector_ptr");
+ LoadInst *VecLoad = Builder.CreateLoad(VectorPtr,
+ load->getNameStr()
+ + "_p_vec_full");
+ if (!Aligned)
+ VecLoad->setAlignment(8);
+
+ return VecLoad;
+ }
+
+ /// @brief Load a vector initialized from a single scalar in memory
+ ///
+ /// In case all elements of a vector are initialized to the same
+ /// scalar value, this value is loaded and shuffeled into all elements
+ /// of the vector.
+ ///
+ /// %splat_one = load <1 x double>* %p
+ /// %splat = shufflevector <1 x double> %splat_one, <1 x
+ /// double> %splat_one, <4 x i32> zeroinitializer
+ ///
+ Value *generateStrideZeroLoad(const LoadInst *load, ValueMapT &BBMap,
+ int size) {
+ const Value *pointer = load->getPointerOperand();
+ const Type *vectorPtrType = getVectorPtrTy(pointer, 1);
+ Value *newPointer = getOperand(pointer, BBMap);
+ Value *vectorPtr = Builder.CreateBitCast(newPointer, vectorPtrType,
+ load->getNameStr() + "_p_vec_p");
+ LoadInst *scalarLoad= Builder.CreateLoad(vectorPtr,
+ load->getNameStr() + "_p_splat_one");
+
+ if (!Aligned)
+ scalarLoad->setAlignment(8);
+
+ std::vector<Constant*> splat;
+
+ for (int i = 0; i < size; i++)
+ splat.push_back (Builder.getInt32(0));
+
+ Constant *splatVector = ConstantVector::get(splat);
+
+ Value *vectorLoad = Builder.CreateShuffleVector(scalarLoad, scalarLoad,
+ splatVector,
+ load->getNameStr()
+ + "_p_splat");
+ return vectorLoad;
+ }
+
+ /// @Load a vector from scalars distributed in memory
+ ///
+ /// In case some scalars a distributed randomly in memory. Create a vector
+ /// by loading each scalar and by inserting one after the other into the
+ /// vector.
+ ///
+ /// %scalar_1= load double* %p_1
+ /// %vec_1 = insertelement <2 x double> undef, double %scalar_1, i32 0
+ /// %scalar 2 = load double* %p_2
+ /// %vec_2 = insertelement <2 x double> %vec_1, double %scalar_1, i32 1
+ ///
+ Value *generateUnknownStrideLoad(const LoadInst *load,
+ VectorValueMapT &scalarMaps,
+ int size) {
+ const Value *pointer = load->getPointerOperand();
+ VectorType *vectorType = VectorType::get(
+ dyn_cast<PointerType>(pointer->getType())->getElementType(), size);
+
+ Value *vector = UndefValue::get(vectorType);
+
+ for (int i = 0; i < size; i++) {
+ Value *newPointer = getOperand(pointer, scalarMaps[i]);
+ Value *scalarLoad = Builder.CreateLoad(newPointer,
+ load->getNameStr() + "_p_scalar_");
+ vector = Builder.CreateInsertElement(vector, scalarLoad,
+ Builder.getInt32(i),
+ load->getNameStr() + "_p_vec_");
+ }
+
+ return vector;
+ }
+
+ Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap) {
+ const Value *pointer = load->getPointerOperand();
+ Value *newPointer = getOperand(pointer, BBMap);
+ Value *scalarLoad = Builder.CreateLoad(newPointer,
+ load->getNameStr() + "_p_scalar_");
+ return scalarLoad;
+ }
+
+ /// @brief Load a value (or several values as a vector) from memory.
+ void generateLoad(const LoadInst *load, ValueMapT &vectorMap,
+ VectorValueMapT &scalarMaps, int vectorWidth) {
+
+ if (scalarMaps.size() == 1) {
+ scalarMaps[0][load] = generateScalarLoad(load, scalarMaps[0]);
+ return;
+ }
+
+ Value *newLoad;
+
+ MemoryAccess &Access = statement.getAccessFor(load);
+
+ assert(scatteringDomain && "No scattering domain available");
+
+ if (Access.isStrideZero(scatteringDomain))
+ newLoad = generateStrideZeroLoad(load, scalarMaps[0], vectorWidth);
+ else if (Access.isStrideOne(scatteringDomain))
+ newLoad = generateStrideOneLoad(load, scalarMaps[0], vectorWidth);
+ else
+ newLoad = generateUnknownStrideLoad(load, scalarMaps, vectorWidth);
+
+ vectorMap[load] = newLoad;
+ }
+
+ void copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
+ ValueMapT &vectorMap, VectorValueMapT &scalarMaps,
+ int vectorDimension, int vectorWidth) {
+ // If this instruction is already in the vectorMap, a vector instruction
+ // was already issued, that calculates the values of all dimensions. No
+ // need to create any more instructions.
+ if (vectorMap.count(Inst))
+ return;
+
+ // Terminator instructions control the control flow. They are explicitally
+ // expressed in the clast and do not need to be copied.
+ if (Inst->isTerminator())
+ return;
+
+ if (const LoadInst *load = dyn_cast<LoadInst>(Inst)) {
+ generateLoad(load, vectorMap, scalarMaps, vectorWidth);
+ return;
+ }
+
+ if (const BinaryOperator *binaryInst = dyn_cast<BinaryOperator>(Inst)) {
+ Value *opZero = Inst->getOperand(0);
+ Value *opOne = Inst->getOperand(1);
+
+ // This is an old instruction that can be ignored.
+ if (!opZero && !opOne)
+ return;
+
+ bool isVectorOp = vectorMap.count(opZero) || vectorMap.count(opOne);
+
+ if (isVectorOp && vectorDimension > 0)
+ return;
+
+ Value *newOpZero, *newOpOne;
+ newOpZero = getOperand(opZero, BBMap, &vectorMap);
+ newOpOne = getOperand(opOne, BBMap, &vectorMap);
+
+
+ std::string name;
+ if (isVectorOp) {
+ newOpZero = makeVectorOperand(newOpZero, vectorWidth);
+ newOpOne = makeVectorOperand(newOpOne, vectorWidth);
+ name = Inst->getNameStr() + "p_vec";
+ } else
+ name = Inst->getNameStr() + "p_sca";
+
+ Value *newInst = Builder.CreateBinOp(binaryInst->getOpcode(), newOpZero,
+ newOpOne, name);
+ if (isVectorOp)
+ vectorMap[Inst] = newInst;
+ else
+ BBMap[Inst] = newInst;
+
+ return;
+ }
+
+ if (const StoreInst *store = dyn_cast<StoreInst>(Inst)) {
+ if (vectorMap.count(store->getValueOperand()) > 0) {
+
+ // We only need to generate one store if we are in vector mode.
+ if (vectorDimension > 0)
+ return;
+
+ MemoryAccess &Access = statement.getAccessFor(store);
+
+ assert(scatteringDomain && "No scattering domain available");
+
+ const Value *pointer = store->getPointerOperand();
+ Value *vector = getOperand(store->getValueOperand(), BBMap, &vectorMap);
+
+ if (Access.isStrideOne(scatteringDomain)) {
+ const Type *vectorPtrType = getVectorPtrTy(pointer, vectorWidth);
+ Value *newPointer = getOperand(pointer, BBMap, &vectorMap);
+
+ Value *VectorPtr = Builder.CreateBitCast(newPointer, vectorPtrType,
+ "vector_ptr");
+ StoreInst *Store = Builder.CreateStore(vector, VectorPtr);
+
+ if (!Aligned)
+ Store->setAlignment(8);
+ } else {
+ for (unsigned i = 0; i < scalarMaps.size(); i++) {
+ Value *scalar = Builder.CreateExtractElement(vector,
+ Builder.getInt32(i));
+ Value *newPointer = getOperand(pointer, scalarMaps[i]);
+ Builder.CreateStore(scalar, newPointer);
+ }
+ }
+
+ return;
+ }
+ }
+
+ Instruction *NewInst = Inst->clone();
+
+ // Copy the operands in temporary vector, as an in place update
+ // fails if an instruction is referencing the same operand twice.
+ std::vector<Value*> Operands(NewInst->op_begin(), NewInst->op_end());
+
+ // Replace old operands with the new ones.
+ for (std::vector<Value*>::iterator UI = Operands.begin(),
+ UE = Operands.end(); UI != UE; ++UI) {
+ Value *newOperand = getOperand(*UI, BBMap);
+
+ if (!newOperand) {
+ assert(!isa<StoreInst>(NewInst)
+ && "Store instructions are always needed!");
+ delete NewInst;
+ return;
+ }
+
+ NewInst->replaceUsesOfWith(*UI, newOperand);
+ }
+
+ Builder.Insert(NewInst);
+ BBMap[Inst] = NewInst;
+
+ if (!NewInst->getType()->isVoidTy())
+ NewInst->setName("p_" + Inst->getName());
+ }
+
+ int getVectorSize() {
+ return ValueMaps.size();
+ }
+
+ bool isVectorBlock() {
+ return getVectorSize() > 1;
+ }
+
+ // Insert a copy of a basic block in the newly generated code.
+ //
+ // @param Builder The builder used to insert the code. It also specifies
+ // where to insert the code.
+ // @param BB The basic block to copy
+ // @param VMap A map returning for any old value its new equivalent. This
+ // is used to update the operands of the statements.
+ // For new statements a relation old->new is inserted in this
+ // map.
+ void copyBB(BasicBlock *BB, DominatorTree *DT) {
+ Function *F = Builder.GetInsertBlock()->getParent();
+ LLVMContext &Context = F->getContext();
+ BasicBlock *CopyBB = BasicBlock::Create(Context,
+ "polly.stmt_" + BB->getNameStr(),
+ F);
+ Builder.CreateBr(CopyBB);
+ DT->addNewBlock(CopyBB, Builder.GetInsertBlock());
+ Builder.SetInsertPoint(CopyBB);
+
+ // Create two maps that store the mapping from the original instructions of
+ // the old basic block to their copies in the new basic block. Those maps
+ // are basic block local.
+ //
+ // As vector code generation is supported there is one map for scalar values
+ // and one for vector values.
+ //
+ // In case we just do scalar code generation, the vectorMap is not used and
+ // the scalarMap has just one dimension, which contains the mapping.
+ //
+ // In case vector code generation is done, an instruction may either appear
+ // in the vector map once (as it is calculating >vectorwidth< values at a
+ // time. Or (if the values are calculated using scalar operations), it
+ // appears once in every dimension of the scalarMap.
+ VectorValueMapT scalarBlockMap(getVectorSize());
+ ValueMapT vectorBlockMap;
+
+ for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
+ II != IE; ++II)
+ for (int i = 0; i < getVectorSize(); i++) {
+ if (isVectorBlock())
+ VMap = ValueMaps[i];
+
+ copyInstruction(II, scalarBlockMap[i], vectorBlockMap,
+ scalarBlockMap, i, getVectorSize());
+ }
+ }
+};
+
+/// Class to generate LLVM-IR that calculates the value of a clast_expr.
+class ClastExpCodeGen {
+ IRBuilder<> &Builder;
+ const CharMapT *IVS;
+
+ Value *codegen(const clast_name *e, const Type *Ty) {
+ CharMapT::const_iterator I = IVS->find(e->name);
+
+ if (I != IVS->end())
+ return Builder.CreateSExtOrBitCast(I->second, Ty);
+ else
+ llvm_unreachable("Clast name not found");
+ }
+
+ Value *codegen(const clast_term *e, const Type *Ty) {
+ APInt a = APInt_from_MPZ(e->val);
+
+ Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
+ ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
+
+ if (e->var) {
+ Value *var = codegen(e->var, Ty);
+ return Builder.CreateMul(ConstOne, var);
+ }
+
+ return ConstOne;
+ }
+
+ Value *codegen(const clast_binary *e, const Type *Ty) {
+ Value *LHS = codegen(e->LHS, Ty);
+
+ APInt RHS_AP = APInt_from_MPZ(e->RHS);
+
+ Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
+ RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
+
+ switch (e->type) {
+ case clast_bin_mod:
+ return Builder.CreateSRem(LHS, RHS);
+ case clast_bin_fdiv:
+ {
+ // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
+ Value *One = ConstantInt::get(Builder.getInt1Ty(), 1);
+ Value *Zero = ConstantInt::get(Builder.getInt1Ty(), 0);
+ One = Builder.CreateZExtOrBitCast(One, Ty);
+ Zero = Builder.CreateZExtOrBitCast(Zero, Ty);
+ Value *Sum1 = Builder.CreateSub(LHS, RHS);
+ Value *Sum2 = Builder.CreateAdd(Sum1, One);
+ Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
+ Value *Dividend = Builder.CreateSelect(isNegative, Sum2, LHS);
+ return Builder.CreateSDiv(Dividend, RHS);
+ }
+ case clast_bin_cdiv:
+ {
+ // ceild(n,d) ((n < 0) ? n : (n + d - 1)) / d
+ Value *One = ConstantInt::get(Builder.getInt1Ty(), 1);
+ Value *Zero = ConstantInt::get(Builder.getInt1Ty(), 0);
+ One = Builder.CreateZExtOrBitCast(One, Ty);
+ Zero = Builder.CreateZExtOrBitCast(Zero, Ty);
+ Value *Sum1 = Builder.CreateAdd(LHS, RHS);
+ Value *Sum2 = Builder.CreateSub(Sum1, One);
+ Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
+ Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
+ return Builder.CreateSDiv(Dividend, RHS);
+ }
+ case clast_bin_div:
+ return Builder.CreateSDiv(LHS, RHS);
+ default:
+ llvm_unreachable("Unknown clast binary expression type");
+ };
+ }
+
+ Value *codegen(const clast_reduction *r, const Type *Ty) {
+ assert(( r->type == clast_red_min
+ || r->type == clast_red_max
+ || r->type == clast_red_sum)
+ && "Clast reduction type not supported");
+ Value *old = codegen(r->elts[0], Ty);
+
+ for (int i=1; i < r->n; ++i) {
+ Value *exprValue = codegen(r->elts[i], Ty);
+
+ switch (r->type) {
+ case clast_red_min:
+ {
+ Value *cmp = Builder.CreateICmpSLT(old, exprValue);
+ old = Builder.CreateSelect(cmp, old, exprValue);
+ break;
+ }
+ case clast_red_max:
+ {
+ Value *cmp = Builder.CreateICmpSGT(old, exprValue);
+ old = Builder.CreateSelect(cmp, old, exprValue);
+ break;
+ }
+ case clast_red_sum:
+ old = Builder.CreateAdd(old, exprValue);
+ break;
+ default:
+ llvm_unreachable("Clast unknown reduction type");
+ }
+ }
+
+ return old;
+ }
+
+public:
+
+ // A generator for clast expressions.
+ //
+ // @param B The IRBuilder that defines where the code to calculate the
+ // clast expressions should be inserted.
+ // @param IVMAP A Map that translates strings describing the induction
+ // variables to the Values* that represent these variables
+ // on the LLVM side.
+ ClastExpCodeGen(IRBuilder<> &B, CharMapT *IVMap) : Builder(B), IVS(IVMap) {}
+
+ // Generates code to calculate a given clast expression.
+ //
+ // @param e The expression to calculate.
+ // @return The Value that holds the result.
+ Value *codegen(const clast_expr *e, const Type *Ty) {
+ switch(e->type) {
+ case clast_expr_name:
+ return codegen((const clast_name *)e, Ty);
+ case clast_expr_term:
+ return codegen((const clast_term *)e, Ty);
+ case clast_expr_bin:
+ return codegen((const clast_binary *)e, Ty);
+ case clast_expr_red:
+ return codegen((const clast_reduction *)e, Ty);
+ default:
+ llvm_unreachable("Unknown clast expression!");
+ }
+ }
+
+ // @brief Reset the CharMap.
+ //
+ // This function is called to reset the CharMap to new one, while generating
+ // OpenMP code.
+ void setIVS(CharMapT *IVSNew) {
+ IVS = IVSNew;
+ }
+
+};
+
+class ClastStmtCodeGen {
+ // The Scop we code generate.
+ Scop *S;
+ ScalarEvolution &SE;
+
+ DominatorTree *DT;
+ Dependences *DP;
+ TargetData *TD;
+
+ // The Builder specifies the current location to code generate at.
+ IRBuilder<> &Builder;
+
+ // Map the Values from the old code to their counterparts in the new code.
+ ValueMapT ValueMap;
+
+ // clastVars maps from the textual representation of a clast variable to its
+ // current *Value. clast variables are scheduling variables, original
+ // induction variables or parameters. They are used either in loop bounds or
+ // to define the statement instance that is executed.
+ //
+ // for (s = 0; s < n + 3; ++i)
+ // for (t = s; t < m; ++j)
+ // Stmt(i = s + 3 * m, j = t);
+ //
+ // {s,t,i,j,n,m} is the set of clast variables in this clast.
+ CharMapT *clastVars;
+
+ // Codegenerator for clast expressions.
+ ClastExpCodeGen ExpGen;
+
+ // Do we currently generate parallel code?
+ bool parallelCodeGeneration;
+
+ std::vector<std::string> parallelLoops;
+
+public:
+
+ const std::vector<std::string> &getParallelLoops() {
+ return parallelLoops;
+ }
+
+ protected:
+ void codegen(const clast_assignment *a) {
+ (*clastVars)[a->LHS] = ExpGen.codegen(a->RHS,
+ TD->getIntPtrType(Builder.getContext()));
+ }
+
+ void codegen(const clast_assignment *a, ScopStmt *Statement,
+ unsigned Dimension, int vectorDim,
+ std::vector<ValueMapT> *VectorVMap = 0) {
+ Value *RHS = ExpGen.codegen(a->RHS,
+ TD->getIntPtrType(Builder.getContext()));
+
+ assert(!a->LHS && "Statement assignments do not have left hand side");
+ const PHINode *PN;
+ PN = Statement->getInductionVariableForDimension(Dimension);
+ const Value *V = PN;
+
+ if (PN->getNumOperands() == 2)
+ V = *(PN->use_begin());
+
+ if (VectorVMap)
+ (*VectorVMap)[vectorDim][V] = RHS;
+
+ ValueMap[V] = RHS;
+ }
+
+ void codegenSubstitutions(const clast_stmt *Assignment,
+ ScopStmt *Statement, int vectorDim = 0,
+ std::vector<ValueMapT> *VectorVMap = 0) {
+ int Dimension = 0;
+
+ while (Assignment) {
+ assert(CLAST_STMT_IS_A(Assignment, stmt_ass)
+ && "Substitions are expected to be assignments");
+ codegen((const clast_assignment *)Assignment, Statement, Dimension,
+ vectorDim, VectorVMap);
+ Assignment = Assignment->next;
+ Dimension++;
+ }
+ }
+
+ void codegen(const clast_user_stmt *u, std::vector<Value*> *IVS = NULL,
+ const char *iterator = NULL, isl_set *scatteringDomain = 0) {
+ ScopStmt *Statement = (ScopStmt *)u->statement->usr;
+ BasicBlock *BB = Statement->getBasicBlock();
+
+ if (u->substitutions)
+ codegenSubstitutions(u->substitutions, Statement);
+
+ int vectorDimensions = IVS ? IVS->size() : 1;
+
+ VectorValueMapT VectorValueMap(vectorDimensions);
+
+ if (IVS) {
+ assert (u->substitutions && "Substitutions expected!");
+ int i = 0;
+ for (std::vector<Value*>::iterator II = IVS->begin(), IE = IVS->end();
+ II != IE; ++II) {
+ (*clastVars)[iterator] = *II;
+ codegenSubstitutions(u->substitutions, Statement, i, &VectorValueMap);
+ i++;
+ }
+ }
+
+ BlockGenerator Generator(Builder, ValueMap, VectorValueMap, *Statement,
+ scatteringDomain);
+ Generator.copyBB(BB, DT);
+ }
+
+ void codegen(const clast_block *b) {
+ if (b->body)
+ codegen(b->body);
+ }
+
+ /// @brief Create a classical sequential loop.
+ void codegenForSequential(const clast_for *f, Value *lowerBound = 0,
+ Value *upperBound = 0) {
+ APInt Stride = APInt_from_MPZ(f->stride);
+ PHINode *IV;
+ Value *IncrementedIV;
+ BasicBlock *AfterBB;
+ // The value of lowerbound and upperbound will be supplied, if this
+ // function is called while generating OpenMP code. Otherwise get
+ // the values.
+ assert(((lowerBound && upperBound) || (!lowerBound && !upperBound))
+ && "Either give both bounds or none");
+ if (lowerBound == 0 || upperBound == 0) {
+ lowerBound = ExpGen.codegen(f->LB,
+ TD->getIntPtrType(Builder.getContext()));
+ upperBound = ExpGen.codegen(f->UB,
+ TD->getIntPtrType(Builder.getContext()));
+ }
+ createLoop(&Builder, lowerBound, upperBound, Stride, IV, AfterBB,
+ IncrementedIV, DT);
+
+ // Add loop iv to symbols.
+ (*clastVars)[f->iterator] = IV;
+
+ if (f->body)
+ codegen(f->body);
+
+ // Loop is finished, so remove its iv from the live symbols.
+ clastVars->erase(f->iterator);
+
+ BasicBlock *HeaderBB = *pred_begin(AfterBB);
+ BasicBlock *LastBodyBB = Builder.GetInsertBlock();
+ Builder.CreateBr(HeaderBB);
+ IV->addIncoming(IncrementedIV, LastBodyBB);
+ Builder.SetInsertPoint(AfterBB);
+ }
+
+ /// @brief Check if a loop is parallel
+ ///
+ /// Detect if a clast_for loop can be executed in parallel.
+ ///
+ /// @param f The clast for loop to check.
+ bool isParallelFor(const clast_for *f) {
+ isl_set *loopDomain = isl_set_from_cloog_domain(f->domain);
+ assert(loopDomain && "Cannot access domain of loop");
+
+ bool isParallel = DP->isParallelDimension(loopDomain,
+ isl_set_n_dim(loopDomain));
+
+ if (isParallel)
+ DEBUG(dbgs() << "Parallel loop with induction variable '" << f->iterator
+ << "' found\n";);
+
+ return isParallel;
+ }
+
+ /// @brief Add a new definition of an openmp subfunction.
+ Function* addOpenMPSubfunction(Module *M) {
+ Function *F = Builder.GetInsertBlock()->getParent();
+ const std::string &Name = F->getNameStr() + ".omp_subfn";
+
+ std::vector<const Type*> Arguments(1, Builder.getInt8PtrTy());
+ FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
+ Function *FN = Function::Create(FT, Function::InternalLinkage, Name, M);
+
+ Function::arg_iterator AI = FN->arg_begin();
+ AI->setName("omp.userContext");
+
+ return FN;
+ }
+
+ /// @brief Add values to the OpenMP structure.
+ ///
+ /// Create the subfunction structure and add the values from the list.
+ Value *addValuesToOpenMPStruct(SetVector<Value*> OMPDataVals,
+ Function *SubFunction) {
+ Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+ std::vector<const Type*> structMembers;
+
+ // Create the structure.
+ for (unsigned i = 0; i < OMPDataVals.size(); i++)
+ structMembers.push_back(OMPDataVals[i]->getType());
+
+ const std::string &Name = SubFunction->getNameStr() + ".omp.userContext";
+ StructType *structTy = StructType::get(Builder.getContext(),
+ structMembers);
+ M->addTypeName(Name, structTy);
+
+ // Store the values into the structure.
+ Value *structData = Builder.CreateAlloca(structTy, 0, "omp.userContext");
+ for (unsigned i = 0; i < OMPDataVals.size(); i++) {
+ Value *storeAddr = Builder.CreateStructGEP(structData, i);
+ Builder.CreateStore(OMPDataVals[i], storeAddr);
+ }
+
+ return structData;
+ }
+
+ /// @brief Create OpenMP structure values.
+ ///
+ /// Create a list of values that has to be stored into the subfuncition
+ /// structure.
+ SetVector<Value*> createOpenMPStructValues() {
+ SetVector<Value*> OMPDataVals;
+
+ // Push the clast variables available in the clastVars.
+ for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
+ I != E; I++)
+ OMPDataVals.insert(I->second);
+
+ // Push the base addresses of memory references.
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+ for (SmallVector<MemoryAccess*, 8>::iterator I = Stmt->memacc_begin(),
+ E = Stmt->memacc_end(); I != E; ++I) {
+ Value *BaseAddr = const_cast<Value*>((*I)->getBaseAddr());
+ OMPDataVals.insert((BaseAddr));
+ }
+ }
+
+ return OMPDataVals;
+ }
+
+ /// @brief Extract the values from the subfunction parameter.
+ ///
+ /// Extract the values from the subfunction parameter and update the clast
+ /// variables to point to the new values.
+ void extractValuesFromOpenMPStruct(CharMapT *clastVarsOMP,
+ SetVector<Value*> OMPDataVals,
+ Value *userContext) {
+ // Extract the clast variables.
+ unsigned i = 0;
+ for (CharMapT::iterator I = clastVars->begin(), E = clastVars->end();
+ I != E; I++) {
+ Value *loadAddr = Builder.CreateStructGEP(userContext, i);
+ (*clastVarsOMP)[I->first] = Builder.CreateLoad(loadAddr);
+ i++;
+ }
+
+ // Extract the base addresses of memory references.
+ for (unsigned j = i; j < OMPDataVals.size(); j++) {
+ Value *loadAddr = Builder.CreateStructGEP(userContext, j);
+ Value *baseAddr = OMPDataVals[j];
+ ValueMap[baseAddr] = Builder.CreateLoad(loadAddr);
+ }
+
+ }
+
+ /// @brief Add body to the subfunction.
+ void addOpenMPSubfunctionBody(Function *FN, const clast_for *f,
+ Value *structData,
+ SetVector<Value*> OMPDataVals) {
+ Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+ LLVMContext &Context = FN->getContext();
+ const IntegerType *intPtrTy = TD->getIntPtrType(Context);
+
+ // Store the previous basic block.
+ BasicBlock *PrevBB = Builder.GetInsertBlock();
+
+ // Create basic blocks.
+ BasicBlock *HeaderBB = BasicBlock::Create(Context, "omp.setup", FN);
+ BasicBlock *ExitBB = BasicBlock::Create(Context, "omp.exit", FN);
+ BasicBlock *checkNextBB = BasicBlock::Create(Context, "omp.checkNext", FN);
+ BasicBlock *loadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds",
+ FN);
+
+ DT->addNewBlock(HeaderBB, PrevBB);
+ DT->addNewBlock(ExitBB, HeaderBB);
+ DT->addNewBlock(checkNextBB, HeaderBB);
+ DT->addNewBlock(loadIVBoundsBB, HeaderBB);
+
+ // Fill up basic block HeaderBB.
+ Builder.SetInsertPoint(HeaderBB);
+ Value *lowerBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
+ "omp.lowerBoundPtr");
+ Value *upperBoundPtr = Builder.CreateAlloca(intPtrTy, 0,
+ "omp.upperBoundPtr");
+ Value *userContext = Builder.CreateBitCast(FN->arg_begin(),
+ structData->getType(),
+ "omp.userContext");
+
+ CharMapT clastVarsOMP;
+ extractValuesFromOpenMPStruct(&clastVarsOMP, OMPDataVals, userContext);
+
+ Builder.CreateBr(checkNextBB);
+
+ // Add code to check if another set of iterations will be executed.
+ Builder.SetInsertPoint(checkNextBB);
+ Function *runtimeNextFunction = M->getFunction("GOMP_loop_runtime_next");
+ Value *ret1 = Builder.CreateCall2(runtimeNextFunction,
+ lowerBoundPtr, upperBoundPtr);
+ Value *hasNextSchedule = Builder.CreateTrunc(ret1, Builder.getInt1Ty(),
+ "omp.hasNextScheduleBlock");
+ Builder.CreateCondBr(hasNextSchedule, loadIVBoundsBB, ExitBB);
+
+ // Add code to to load the iv bounds for this set of iterations.
+ Builder.SetInsertPoint(loadIVBoundsBB);
+ Value *lowerBound = Builder.CreateLoad(lowerBoundPtr, "omp.lowerBound");
+ Value *upperBound = Builder.CreateLoad(upperBoundPtr, "omp.upperBound");
+
+ // Subtract one as the upper bound provided by openmp is a < comparison
+ // whereas the codegenForSequential function creates a <= comparison.
+ upperBound = Builder.CreateSub(upperBound, ConstantInt::get(intPtrTy, 1),
+ "omp.upperBoundAdjusted");
+
+ // Use clastVarsOMP during code generation of the OpenMP subfunction.
+ CharMapT *oldClastVars = clastVars;
+ clastVars = &clastVarsOMP;
+ ExpGen.setIVS(&clastVarsOMP);
+
+ codegenForSequential(f, lowerBound, upperBound);
+
+ // Restore the old clastVars.
+ clastVars = oldClastVars;
+ ExpGen.setIVS(oldClastVars);
+
+ Builder.CreateBr(checkNextBB);
+
+ // Add code to terminate this openmp subfunction.
+ Builder.SetInsertPoint(ExitBB);
+ Function *endnowaitFunction = M->getFunction("GOMP_loop_end_nowait");
+ Builder.CreateCall(endnowaitFunction);
+ Builder.CreateRetVoid();
+
+ // Restore the builder back to previous basic block.
+ Builder.SetInsertPoint(PrevBB);
+ }
+
+ /// @brief Create an OpenMP parallel for loop.
+ ///
+ /// This loop reflects a loop as if it would have been created by an OpenMP
+ /// statement.
+ void codegenForOpenMP(const clast_for *f) {
+ Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+ const IntegerType *intPtrTy = TD->getIntPtrType(Builder.getContext());
+
+ Function *SubFunction = addOpenMPSubfunction(M);
+ SetVector<Value*> OMPDataVals = createOpenMPStructValues();
+ Value *structData = addValuesToOpenMPStruct(OMPDataVals, SubFunction);
+
+ addOpenMPSubfunctionBody(SubFunction, f, structData, OMPDataVals);
+
+ // Create call for GOMP_parallel_loop_runtime_start.
+ Value *subfunctionParam = Builder.CreateBitCast(structData,
+ Builder.getInt8PtrTy(),
+ "omp_data");
+
+ Value *numberOfThreads = Builder.getInt32(0);
+ Value *lowerBound = ExpGen.codegen(f->LB, intPtrTy);
+ Value *upperBound = ExpGen.codegen(f->UB, intPtrTy);
+
+ // Add one as the upper bound provided by openmp is a < comparison
+ // whereas the codegenForSequential function creates a <= comparison.
+ upperBound = Builder.CreateAdd(upperBound, ConstantInt::get(intPtrTy, 1));
+ APInt APStride = APInt_from_MPZ(f->stride);
+ Value *stride = ConstantInt::get(intPtrTy,
+ APStride.zext(intPtrTy->getBitWidth()));
+
+ SmallVector<Value *, 6> Arguments;
+ Arguments.push_back(SubFunction);
+ Arguments.push_back(subfunctionParam);
+ Arguments.push_back(numberOfThreads);
+ Arguments.push_back(lowerBound);
+ Arguments.push_back(upperBound);
+ Arguments.push_back(stride);
+
+ Function *parallelStartFunction =
+ M->getFunction("GOMP_parallel_loop_runtime_start");
+ Builder.CreateCall(parallelStartFunction, Arguments.begin(),
+ Arguments.end());
+
+ // Create call to the subfunction.
+ Builder.CreateCall(SubFunction, subfunctionParam);
+
+ // Create call for GOMP_parallel_end.
+ Function *FN = M->getFunction("GOMP_parallel_end");
+ Builder.CreateCall(FN);
+ }
+
+ bool isInnermostLoop(const clast_for *f) {
+ const clast_stmt *stmt = f->body;
+
+ while (stmt) {
+ if (!CLAST_STMT_IS_A(stmt, stmt_user))
+ return false;
+
+ stmt = stmt->next;
+ }
+
+ return true;
+ }
+
+ /// @brief Get the number of loop iterations for this loop.
+ /// @param f The clast for loop to check.
+ int getNumberOfIterations(const clast_for *f) {
+ isl_set *loopDomain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
+ isl_set *tmp = isl_set_copy(loopDomain);
+
+ // Calculate a map similar to the identity map, but with the last input
+ // and output dimension not related.
+ // [i0, i1, i2, i3] -> [i0, i1, i2, o0]
+ isl_dim *dim = isl_set_get_dim(loopDomain);
+ dim = isl_dim_drop_outputs(dim, isl_set_n_dim(loopDomain) - 2, 1);
+ dim = isl_dim_map_from_set(dim);
+ isl_map *identity = isl_map_identity(dim);
+ identity = isl_map_add_dims(identity, isl_dim_in, 1);
+ identity = isl_map_add_dims(identity, isl_dim_out, 1);
+
+ isl_map *map = isl_map_from_domain_and_range(tmp, loopDomain);
+ map = isl_map_intersect(map, identity);
+
+ isl_map *lexmax = isl_map_lexmax(isl_map_copy(map));
+ isl_map *lexmin = isl_map_lexmin(isl_map_copy(map));
+ isl_map *sub = isl_map_sum(lexmax, isl_map_neg(lexmin));
+
+ isl_set *elements = isl_map_range(sub);
+
+ if (!isl_set_is_singleton(elements))
+ return -1;
+
+ isl_point *p = isl_set_sample_point(elements);
+
+ isl_int v;
+ isl_int_init(v);
+ isl_point_get_coordinate(p, isl_dim_set, isl_set_n_dim(loopDomain) - 1, &v);
+ int numberIterations = isl_int_get_si(v);
+ isl_int_clear(v);
+
+ return (numberIterations) / isl_int_get_si(f->stride) + 1;
+ }
+
+ /// @brief Create vector instructions for this loop.
+ void codegenForVector(const clast_for *f) {
+ DEBUG(dbgs() << "Vectorizing loop '" << f->iterator << "'\n";);
+ int vectorWidth = getNumberOfIterations(f);
+
+ Value *LB = ExpGen.codegen(f->LB,
+ TD->getIntPtrType(Builder.getContext()));
+
+ APInt Stride = APInt_from_MPZ(f->stride);
+ const IntegerType *LoopIVType = dyn_cast<IntegerType>(LB->getType());
+ Stride = Stride.zext(LoopIVType->getBitWidth());
+ Value *StrideValue = ConstantInt::get(LoopIVType, Stride);
+
+ std::vector<Value*> IVS(vectorWidth);
+ IVS[0] = LB;
+
+ for (int i = 1; i < vectorWidth; i++)
+ IVS[i] = Builder.CreateAdd(IVS[i-1], StrideValue, "p_vector_iv");
+
+ isl_set *scatteringDomain = isl_set_from_cloog_domain(f->domain);
+
+ // Add loop iv to symbols.
+ (*clastVars)[f->iterator] = LB;
+
+ const clast_stmt *stmt = f->body;
+
+ while (stmt) {
+ codegen((const clast_user_stmt *)stmt, &IVS, f->iterator,
+ scatteringDomain);
+ stmt = stmt->next;
+ }
+
+ // Loop is finished, so remove its iv from the live symbols.
+ clastVars->erase(f->iterator);
+ }
+
+ void codegen(const clast_for *f) {
+ if (Vector && isInnermostLoop(f) && isParallelFor(f)
+ && (-1 != getNumberOfIterations(f))
+ && (getNumberOfIterations(f) <= 16)) {
+ codegenForVector(f);
+ } else if (OpenMP && !parallelCodeGeneration && isParallelFor(f)) {
+ parallelCodeGeneration = true;
+ parallelLoops.push_back(f->iterator);
+ codegenForOpenMP(f);
+ parallelCodeGeneration = false;
+ } else
+ codegenForSequential(f);
+ }
+
+ Value *codegen(const clast_equation *eq) {
+ Value *LHS = ExpGen.codegen(eq->LHS,
+ TD->getIntPtrType(Builder.getContext()));
+ Value *RHS = ExpGen.codegen(eq->RHS,
+ TD->getIntPtrType(Builder.getContext()));
+ CmpInst::Predicate P;
+
+ if (eq->sign == 0)
+ P = ICmpInst::ICMP_EQ;
+ else if (eq->sign > 0)
+ P = ICmpInst::ICMP_SGE;
+ else
+ P = ICmpInst::ICMP_SLE;
+
+ return Builder.CreateICmp(P, LHS, RHS);
+ }
+
+ void codegen(const clast_guard *g) {
+ Function *F = Builder.GetInsertBlock()->getParent();
+ LLVMContext &Context = F->getContext();
+ BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
+ BasicBlock *MergeBB = BasicBlock::Create(Context, "polly.merge", F);
+ DT->addNewBlock(ThenBB, Builder.GetInsertBlock());
+ DT->addNewBlock(MergeBB, Builder.GetInsertBlock());
+
+ Value *Predicate = codegen(&(g->eq[0]));
+
+ for (int i = 1; i < g->n; ++i) {
+ Value *TmpPredicate = codegen(&(g->eq[i]));
+ Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
+ }
+
+ Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
+ Builder.SetInsertPoint(ThenBB);
+
+ codegen(g->then);
+
+ Builder.CreateBr(MergeBB);
+ Builder.SetInsertPoint(MergeBB);
+ }
+
+ void codegen(const clast_stmt *stmt) {
+ if (CLAST_STMT_IS_A(stmt, stmt_root))
+ assert(false && "No second root statement expected");
+ else if (CLAST_STMT_IS_A(stmt, stmt_ass))
+ codegen((const clast_assignment *)stmt);
+ else if (CLAST_STMT_IS_A(stmt, stmt_user))
+ codegen((const clast_user_stmt *)stmt);
+ else if (CLAST_STMT_IS_A(stmt, stmt_block))
+ codegen((const clast_block *)stmt);
+ else if (CLAST_STMT_IS_A(stmt, stmt_for))
+ codegen((const clast_for *)stmt);
+ else if (CLAST_STMT_IS_A(stmt, stmt_guard))
+ codegen((const clast_guard *)stmt);
+
+ if (stmt->next)
+ codegen(stmt->next);
+ }
+
+ void addParameters(const CloogNames *names) {
+ SCEVExpander Rewriter(SE);
+
+ // Create an instruction that specifies the location where the parameters
+ // are expanded.
+ CastInst::CreateIntegerCast(ConstantInt::getTrue(Builder.getContext()),
+ Builder.getInt16Ty(), false, "insertInst",
+ Builder.GetInsertBlock());
+
+ int i = 0;
+ for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
+ PI != PE; ++PI) {
+ assert(i < names->nb_parameters && "Not enough parameter names");
+
+ const SCEV *Param = *PI;
+ const Type *Ty = Param->getType();
+
+ Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
+ Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
+ (*clastVars)[names->parameters[i]] = V;
+
+ ++i;
+ }
+ }
+
+ public:
+ void codegen(const clast_root *r) {
+ clastVars = new CharMapT();
+ addParameters(r->names);
+ ExpGen.setIVS(clastVars);
+
+ parallelCodeGeneration = false;
+
+ const clast_stmt *stmt = (const clast_stmt*) r;
+ if (stmt->next)
+ codegen(stmt->next);
+
+ delete clastVars;
+ }
+
+ ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, DominatorTree *dt,
+ Dependences *dp, TargetData *td, IRBuilder<> &B) :
+ S(scop), SE(se), DT(dt), DP(dp), TD(td), Builder(B), ExpGen(Builder, NULL) {}
+
+};
+}
+
+namespace {
+class CodeGeneration : public ScopPass {
+ Region *region;
+ Scop *S;
+ DominatorTree *DT;
+ ScalarEvolution *SE;
+ ScopDetection *SD;
+ CloogInfo *C;
+ LoopInfo *LI;
+ TargetData *TD;
+
+ std::vector<std::string> parallelLoops;
+
+ public:
+ static char ID;
+
+ CodeGeneration() : ScopPass(ID) {}
+
+ void createSeSeEdges(Region *R) {
+ BasicBlock *newEntry = createSingleEntryEdge(R, this);
+
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
+ if ((*SI)->getBasicBlock() == R->getEntry())
+ (*SI)->setBasicBlock(newEntry);
+
+ createSingleExitEdge(R, this);
+ }
+
+
+ // Adding prototypes required if OpenMP is enabled.
+ void addOpenMPDefinitions(IRBuilder<> &Builder)
+ {
+ Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+ LLVMContext &Context = Builder.getContext();
+ const IntegerType *intPtrTy = TD->getIntPtrType(Context);
+
+ if (!M->getFunction("GOMP_parallel_end")) {
+ FunctionType *FT = FunctionType::get(Type::getVoidTy(Context), false);
+ Function::Create(FT, Function::ExternalLinkage, "GOMP_parallel_end", M);
+ }
+
+ if (!M->getFunction("GOMP_parallel_loop_runtime_start")) {
+ // Type of first argument.
+ std::vector<const Type*> Arguments(1, Builder.getInt8PtrTy());
+ FunctionType *FnArgTy = FunctionType::get(Builder.getVoidTy(), Arguments,
+ false);
+ PointerType *FnPtrTy = PointerType::getUnqual(FnArgTy);
+
+ std::vector<const Type*> args;
+ args.push_back(FnPtrTy);
+ args.push_back(Builder.getInt8PtrTy());
+ args.push_back(Builder.getInt32Ty());
+ args.push_back(intPtrTy);
+ args.push_back(intPtrTy);
+ args.push_back(intPtrTy);
+
+ FunctionType *type = FunctionType::get(Builder.getVoidTy(), args, false);
+ Function::Create(type, Function::ExternalLinkage,
+ "GOMP_parallel_loop_runtime_start", M);
+ }
+
+ if (!M->getFunction("GOMP_loop_runtime_next")) {
+ PointerType *intLongPtrTy = PointerType::getUnqual(intPtrTy);
+
+ std::vector<const Type*> args;
+ args.push_back(intLongPtrTy);
+ args.push_back(intLongPtrTy);
+
+ FunctionType *type = FunctionType::get(Builder.getInt8Ty(), args, false);
+ Function::Create(type, Function::ExternalLinkage,
+ "GOMP_loop_runtime_next", M);
+ }
+
+ if (!M->getFunction("GOMP_loop_end_nowait")) {
+ FunctionType *FT = FunctionType::get(Builder.getVoidTy(),
+ std::vector<const Type*>(), false);
+ Function::Create(FT, Function::ExternalLinkage,
+ "GOMP_loop_end_nowait", M);
+ }
+ }
+
+ bool runOnScop(Scop &scop) {
+ S = &scop;
+ region = &S->getRegion();
+ Region *R = region;
+ DT = &getAnalysis<DominatorTree>();
+ Dependences *DP = &getAnalysis<Dependences>();
+ SE = &getAnalysis<ScalarEvolution>();
+ LI = &getAnalysis<LoopInfo>();
+ C = &getAnalysis<CloogInfo>();
+ SD = &getAnalysis<ScopDetection>();
+ TD = &getAnalysis<TargetData>();
+
+ Function *F = R->getEntry()->getParent();
+
+ parallelLoops.clear();
+
+ if (CodegenOnly != "" && CodegenOnly != F->getNameStr()) {
+ errs() << "Codegenerating only function '" << CodegenOnly
+ << "' skipping '" << F->getNameStr() << "' \n";
+ return false;
+ }
+
+ createSeSeEdges(R);
+
+ // Create a basic block in which to start code generation.
+ BasicBlock *PollyBB = BasicBlock::Create(F->getContext(), "pollyBB", F);
+ IRBuilder<> Builder(PollyBB);
+ DT->addNewBlock(PollyBB, R->getEntry());
+
+ const clast_root *clast = (const clast_root *) C->getClast();
+
+ ClastStmtCodeGen CodeGen(S, *SE, DT, DP, TD, Builder);
+
+ if (OpenMP)
+ addOpenMPDefinitions(Builder);
+
+ CodeGen.codegen(clast);
+
+ // Save the parallel loops generated.
+ parallelLoops.insert(parallelLoops.begin(),
+ CodeGen.getParallelLoops().begin(),
+ CodeGen.getParallelLoops().end());
+
+ BasicBlock *AfterScop = *pred_begin(R->getExit());
+ Builder.CreateBr(AfterScop);
+
+ BasicBlock *successorBlock = *succ_begin(R->getEntry());
+
+ // Update old PHI nodes to pass LLVM verification.
+ std::vector<PHINode*> PHINodes;
+ for (BasicBlock::iterator SI = successorBlock->begin(),
+ SE = successorBlock->getFirstNonPHI(); SI != SE; ++SI) {
+ PHINode *PN = static_cast<PHINode*>(&*SI);
+ PHINodes.push_back(PN);
+ }
+
+ for (std::vector<PHINode*>::iterator PI = PHINodes.begin(),
+ PE = PHINodes.end(); PI != PE; ++PI)
+ (*PI)->removeIncomingValue(R->getEntry());
+
+ DT->changeImmediateDominator(AfterScop, Builder.GetInsertBlock());
+
+ BasicBlock *OldRegionEntry = *succ_begin(R->getEntry());
+
+ // Enable the new polly code.
+ R->getEntry()->getTerminator()->setSuccessor(0, PollyBB);
+
+ // Remove old Scop nodes from dominator tree.
+ std::vector<DomTreeNode*> ToVisit;
+ std::vector<DomTreeNode*> Visited;
+ ToVisit.push_back(DT->getNode(OldRegionEntry));
+
+ while (!ToVisit.empty()) {
+ DomTreeNode *Node = ToVisit.back();
+
+ ToVisit.pop_back();
+
+ if (AfterScop == Node->getBlock())
+ continue;
+
+ Visited.push_back(Node);
+
+ std::vector<DomTreeNode*> Children = Node->getChildren();
+ ToVisit.insert(ToVisit.end(), Children.begin(), Children.end());
+ }
+
+ for (std::vector<DomTreeNode*>::reverse_iterator I = Visited.rbegin(),
+ E = Visited.rend(); I != E; ++I)
+ DT->eraseNode((*I)->getBlock());
+
+ R->getParent()->removeSubRegion(R);
+
+ // And forget the Scop if we remove the region.
+ SD->forgetScop(*R);
+
+ return false;
+ }
+
+ virtual void printScop(raw_ostream &OS) const {
+ for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
+ PE = parallelLoops.end(); PI != PE; ++PI)
+ OS << "Parallel loop with iterator '" << *PI << "' generated\n";
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<CloogInfo>();
+ AU.addRequired<Dependences>();
+ AU.addRequired<DominatorTree>();
+ AU.addRequired<ScalarEvolution>();
+ AU.addRequired<LoopInfo>();
+ AU.addRequired<RegionInfo>();
+ AU.addRequired<ScopDetection>();
+ AU.addRequired<ScopInfo>();
+ AU.addRequired<TargetData>();
+
+ AU.addPreserved<CloogInfo>();
+ AU.addPreserved<Dependences>();
+ AU.addPreserved<LoopInfo>();
+ AU.addPreserved<DominatorTree>();
+ AU.addPreserved<PostDominatorTree>();
+ AU.addPreserved<ScopDetection>();
+ AU.addPreserved<ScalarEvolution>();
+ AU.addPreserved<RegionInfo>();
+ AU.addPreserved<TempScopInfo>();
+ AU.addPreserved<ScopInfo>();
+ AU.addPreservedID(IndependentBlocksID);
+ }
+};
+}
+
+char CodeGeneration::ID = 1;
+
+static RegisterPass<CodeGeneration>
+Z("polly-codegen", "Polly - Create LLVM-IR from the polyhedral information");
+
+Pass* polly::createCodeGenerationPass() {
+ return new CodeGeneration();
+}
--- /dev/null
+//===---- CodePreparation.cpp - Code preparation for Scop Detection -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implement the code preparation for Scop detect, which will:
+// 1. Translate all PHINodes that not induction variable to memory access,
+// this will easier parameter and scalar dependencies checking.
+//
+//===----------------------------------------------------------------------===//
+#include "polly/LinkAllPasses.h"
+#include "polly/Support/ScopHelper.h"
+
+#include "llvm/Instruction.h"
+#include "llvm/Pass.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Transforms/Utils/Local.h"
+
+#define DEBUG_TYPE "polly-code-prep"
+#include "llvm/Support/Debug.h"
+
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+//===----------------------------------------------------------------------===//
+/// @brief Scop Code Preparation - Perform some transforms to make scop detect
+/// easier.
+///
+class CodePreperation : public FunctionPass {
+ // DO NOT IMPLEMENT.
+ CodePreperation(const CodePreperation &);
+ // DO NOT IMPLEMENT.
+ const CodePreperation &operator=(const CodePreperation &);
+
+ // LoopInfo to compute canonical induction variable.
+ LoopInfo *LI;
+
+ // Clear the context.
+ void clear();
+
+ bool eliminatePHINodes(Function &F);
+
+public:
+ static char ID;
+
+ explicit CodePreperation() : FunctionPass(ID) {}
+ ~CodePreperation();
+
+ /// @name FunctionPass interface.
+ //@{
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+ virtual bool runOnFunction(Function &F);
+ virtual void print(raw_ostream &OS, const Module *) const;
+ //@}
+
+};
+}
+
+//===----------------------------------------------------------------------===//
+/// CodePreperation implement.
+
+void CodePreperation::clear() {
+}
+
+CodePreperation::~CodePreperation() {
+ clear();
+}
+
+bool CodePreperation::eliminatePHINodes(Function &F) {
+ // The PHINodes that will be deleted.
+ std::vector<PHINode*> PNtoDel;
+ // The PHINodes that will be preserved.
+ std::vector<PHINode*> PreservedPNs;
+
+ // Scan the PHINodes in this function.
+ for (Function::iterator ibb = F.begin(), ibe = F.end();
+ ibb != ibe; ++ibb)
+ for (BasicBlock::iterator iib = ibb->begin(), iie = ibb->getFirstNonPHI();
+ iib != iie; ++iib)
+ if (PHINode *PN = cast<PHINode>(iib)) {
+ if (Loop *L = LI->getLoopFor(ibb)) {
+ // Induction variable will be preserved.
+ if (L->getCanonicalInductionVariable() == PN) {
+ PreservedPNs.push_back(PN);
+ continue;
+ }
+ }
+
+ // As DemotePHIToStack does not support invoke edges, we preserve
+ // PHINodes that have invoke edges.
+ if (hasInvokeEdge(PN))
+ PreservedPNs.push_back(PN);
+ else
+ PNtoDel.push_back(PN);
+ }
+
+ if (PNtoDel.empty())
+ return false;
+
+ // Eliminate the PHINodes that not an Induction variable.
+ while (!PNtoDel.empty()) {
+ PHINode *PN = PNtoDel.back();
+ PNtoDel.pop_back();
+
+ DemotePHIToStack(PN);
+ }
+
+ // Move all preserved PHINodes to the beginning of the BasicBlock.
+ while (!PreservedPNs.empty()) {
+ PHINode *PN = PreservedPNs.back();
+ PreservedPNs.pop_back();
+
+ BasicBlock *BB = PN->getParent();
+ if (PN == BB->begin())
+ continue;
+
+ PN->moveBefore(BB->begin());
+ }
+
+ return true;
+}
+
+void CodePreperation::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<LoopInfo>();
+
+ AU.addPreserved<LoopInfo>();
+ AU.addPreserved<RegionInfo>();
+ AU.addPreserved<DominatorTree>();
+ AU.addPreserved<DominanceFrontier>();
+}
+
+bool CodePreperation::runOnFunction(Function &F) {
+ LI = &getAnalysis<LoopInfo>();
+
+ splitEntryBlockForAlloca(&F.getEntryBlock(), this);
+
+ eliminatePHINodes(F);
+
+ return false;
+}
+
+void CodePreperation::releaseMemory() {
+ clear();
+}
+
+void CodePreperation::print(raw_ostream &OS, const Module *) const {
+}
+
+char CodePreperation::ID = 0;
+
+RegisterPass<CodePreperation> X("polly-prepare",
+ "Polly - Prepare code for polly.",
+ false, true);
+
+char &polly::CodePreperationID = CodePreperation::ID;
+
+Pass *polly::createCodePreperationPass() {
+ return new CodePreperation();
+}
--- /dev/null
+//===-- JSONExporter.cpp - Export Scops as JSON -------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Export the Scops build by ScopInfo pass as a JSON file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+#include "polly/Dependences.h"
+#include "polly/ScopInfo.h"
+#include "polly/ScopPass.h"
+
+#include "json/reader.h"
+#include "json/writer.h"
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Assembly/Writer.h"
+
+#include "stdio.h"
+#include "isl/set.h"
+#include "isl/map.h"
+#include "isl/constraint.h"
+#include "isl/printer.h"
+
+#include <string>
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+static cl::opt<std::string>
+ImportDir("polly-import-jscop-dir",
+ cl::desc("The directory to import the .jscop files from."), cl::Hidden,
+ cl::value_desc("Directory path"), cl::ValueRequired, cl::init("."));
+static cl::opt<std::string>
+ImportPostfix("polly-import-jscop-postfix",
+ cl::desc("Postfix to append to the import .jsop files."),
+ cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired,
+ cl::init(""));
+
+struct JSONExporter : public ScopPass {
+ static char ID;
+ Scop *S;
+ explicit JSONExporter() : ScopPass(ID) {}
+
+ std::string getFileName(Scop *S) const;
+ Json::Value getJSON(Scop &scop) const;
+ virtual bool runOnScop(Scop &S);
+ void printScop(raw_ostream &OS) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+struct JSONImporter : public ScopPass {
+ static char ID;
+ Scop *S;
+ explicit JSONImporter() : ScopPass(ID) {}
+
+ std::string getFileName(Scop *S) const;
+ virtual bool runOnScop(Scop &S);
+ void printScop(raw_ostream &OS) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+
+}
+
+char JSONExporter::ID = 0;
+std::string JSONExporter::getFileName(Scop *S) const {
+ std::string FunctionName =
+ S->getRegion().getEntry()->getParent()->getNameStr();
+ std::string FileName = FunctionName + "___" + S->getNameStr() + ".jscop";
+ return FileName;
+}
+
+void JSONExporter::printScop(raw_ostream &OS) const {
+ S->print(OS);
+}
+
+Json::Value JSONExporter::getJSON(Scop &scop) const {
+ Json::Value root;
+
+ root["name"] = S->getRegion().getNameStr();
+ root["context"] = S->getContextStr();
+ root["statements"];
+
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ if (Stmt->isFinalRead())
+ continue;
+
+ Json::Value statement;
+
+ statement["name"] = Stmt->getBaseName();
+ statement["domain"] = Stmt->getDomainStr();
+ statement["schedule"] = Stmt->getScatteringStr();
+ statement["accesses"];
+
+ for (ScopStmt::memacc_iterator MI = Stmt->memacc_begin(),
+ ME = Stmt->memacc_end(); MI != ME; ++MI) {
+ Json::Value access;
+
+ access["kind"] = (*MI)->isRead() ? "read" : "write";
+ access["relation"] = (*MI)->getAccessFunctionStr();
+
+ statement["accesses"].append(access);
+ }
+
+ root["statements"].append(statement);
+ }
+
+ return root;
+}
+
+bool JSONExporter::runOnScop(Scop &scop) {
+ S = &scop;
+ Region &R = S->getRegion();
+
+ std::string FileName = ImportDir + "/" + getFileName(S);
+ char *text;
+
+ Json::Value jscop = getJSON(scop);
+ Json::StyledWriter writer;
+ std::string fileContent = writer.write(jscop);
+
+ // Write to file.
+ std::string ErrInfo;
+ tool_output_file F(FileName.c_str(), ErrInfo);
+
+ std::string FunctionName = R.getEntry()->getParent()->getNameStr();
+ errs() << "Writing JScop '" << R.getNameStr() << "' in function '"
+ << FunctionName << "' to '" << FileName << "'.\n";
+
+ if (ErrInfo.empty()) {
+ F.os() << fileContent;
+ F.os().close();
+ if (!F.os().has_error()) {
+ errs() << "\n";
+ F.keep();
+ return false;
+ }
+ }
+
+ errs() << " error opening file for writing!\n";
+ F.os().clear_error();
+
+ return false;
+}
+
+void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<ScopInfo>();
+}
+
+static RegisterPass<JSONExporter> A("polly-export-jscop",
+ "Polly - Export Scops as JSON"
+ " (Writes a .jscop file for each Scop)"
+ );
+
+Pass *polly::createJSONExporterPass() {
+ return new JSONExporter();
+}
+
+char JSONImporter::ID = 0;
+std::string JSONImporter::getFileName(Scop *S) const {
+ std::string FunctionName =
+ S->getRegion().getEntry()->getParent()->getNameStr();
+ std::string FileName = FunctionName + "___" + S->getNameStr() + ".jscop";
+
+ if (ImportPostfix != "")
+ FileName += "." + ImportPostfix;
+
+ return FileName;
+}
+void JSONImporter::printScop(raw_ostream &OS) const {
+ S->print(OS);
+}
+
+typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
+
+bool JSONImporter::runOnScop(Scop &scop) {
+ S = &scop;
+ Region &R = S->getRegion();
+ Dependences *D = &getAnalysis<Dependences>();
+
+
+ std::string FileName = ImportDir + "/" + getFileName(S);
+
+ std::string FunctionName = R.getEntry()->getParent()->getNameStr();
+ errs() << "Reading JScop '" << R.getNameStr() << "' in function '"
+ << FunctionName << "' from '" << FileName << "'.\n";
+ OwningPtr<MemoryBuffer> result;
+ error_code ec = MemoryBuffer::getFile(FileName, result);
+
+ if (ec) {
+ errs() << "File could not be read: " << ec.message() << "\n";
+ return false;
+ }
+
+ Json::Reader reader;
+ Json::Value jscop;
+
+ bool parsingSuccessful = reader.parse(result->getBufferStart(), jscop);
+
+ if (!parsingSuccessful) {
+ errs() << "JSCoP file could not be parsed\n";
+ return false;
+ }
+
+ StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy());
+
+ int index = 0;
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ if (Stmt->isFinalRead())
+ continue;
+ Json::Value schedule = jscop["statements"][index]["schedule"];
+
+ isl_map *m = isl_map_read_from_str(S->getCtx(), schedule.asCString(), -1);
+ NewScattering[*SI] = m;
+ index++;
+ }
+
+ if (!D->isValidScattering(&NewScattering)) {
+ errs() << "JScop file contains a scattering that changes the "
+ << "dependences. Use -disable-polly-legality to continue anyways\n";
+ return false;
+ }
+
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ if (NewScattering.find(Stmt) != NewScattering.end())
+ Stmt->setScattering((NewScattering)[Stmt]);
+ }
+
+ return false;
+}
+
+void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+ AU.addRequired<Dependences>();
+}
+
+static RegisterPass<JSONImporter> B("polly-import-jscop",
+ "Polly - Import Scops from JSON"
+ " (Reads a .jscop file for each Scop)"
+ );
+
+Pass *polly::createJSONImporterPass() {
+ return new JSONImporter();
+}
--- /dev/null
+##===- polly/lib/Exchange/Makefile ----------------*- Makefile -*-===##
+
+#
+# Indicate where we are relative to the top of the source tree.
+#
+LEVEL=../..
+
+LIBRARYNAME=pollyexchange
+BUILD_ARCHIVE = 1
+
+CPP.Flags += $(POLLY_INC)
+
+#
+# Include Makefile.common so we know what to do.
+#
+include $(LEVEL)/Makefile.common
\ No newline at end of file
--- /dev/null
+//===-- OpenScopExporter.cpp - Export Scops with openscop library --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Export the Scops build by ScopInfo pass to text file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+
+#ifdef OPENSCOP_FOUND
+
+#include "polly/ScopInfo.h"
+#include "polly/ScopPass.h"
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Assembly/Writer.h"
+
+#define OPENSCOP_INT_T_IS_MP
+#include "openscop/openscop.h"
+
+#include "stdio.h"
+#include "isl/set.h"
+#include "isl/constraint.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+static cl::opt<std::string>
+ExportDir("polly-export-dir",
+ cl::desc("The directory to export the .scop files to."), cl::Hidden,
+ cl::value_desc("Directory path"), cl::ValueRequired, cl::init("."));
+
+struct ScopExporter : public ScopPass {
+ static char ID;
+ Scop *S;
+ explicit ScopExporter() : ScopPass(ID) {}
+
+ std::string getFileName(Scop *S) const;
+
+ virtual bool runOnScop(Scop &S);
+ void printScop(raw_ostream &OS) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+
+}
+
+char ScopExporter::ID = 0;
+
+class OpenScop {
+ Scop *PollyScop;
+ openscop_scop_p openscop;
+
+ std::map<const Value*, int> ArrayMap;
+
+ void initializeArrays();
+ void initializeParameters();
+ void initializeScattering();
+ void initializeStatements();
+ openscop_statement_p initializeStatement(ScopStmt *stmt);
+ void freeStatement(openscop_statement_p stmt);
+ static int accessToMatrix_constraint(isl_constraint *c, void *user);
+ static int accessToMatrix_basic_map(isl_basic_map *bmap, void *user);
+ openscop_matrix_p createAccessMatrix(ScopStmt *S, bool isRead);
+ static int domainToMatrix_constraint(isl_constraint *c, void *user);
+ static int domainToMatrix_basic_set(isl_basic_set *bset, void *user);
+ openscop_matrix_p domainToMatrix(isl_set *PS);
+ static int scatteringToMatrix_constraint(isl_constraint *c, void *user);
+ static int scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user);
+ openscop_matrix_p scatteringToMatrix(isl_map *pmap);
+
+public:
+ OpenScop(Scop *S);
+ ~OpenScop();
+ void print(FILE *F);
+
+};
+
+OpenScop::OpenScop(Scop *S) : PollyScop(S) {
+ openscop = openscop_scop_malloc();
+
+ initializeArrays();
+ initializeParameters();
+ initializeScattering();
+ initializeStatements();
+}
+
+void OpenScop::initializeParameters() {
+ openscop->nb_parameters = PollyScop->getNumParams();
+ openscop->parameters = new char*[openscop->nb_parameters];
+
+ for (int i = 0; i < openscop->nb_parameters; ++i) {
+ openscop->parameters[i] = new char[20];
+ sprintf(openscop->parameters[i], "p_%d", i);
+ }
+}
+
+void OpenScop::initializeArrays() {
+ int nb_arrays = 0;
+
+ for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE;
+ ++SI)
+ for (ScopStmt::memacc_iterator MI = (*SI)->memacc_begin(),
+ ME = (*SI)->memacc_end(); MI != ME; ++MI) {
+ const Value *BaseAddr = (*MI)->getBaseAddr();
+ if (ArrayMap.find(BaseAddr) == ArrayMap.end()) {
+ ArrayMap.insert(std::make_pair(BaseAddr, nb_arrays));
+ ++nb_arrays;
+ }
+ }
+
+ openscop->nb_arrays = nb_arrays;
+ openscop->arrays = new char*[nb_arrays];
+
+ for (int i = 0; i < nb_arrays; ++i)
+ for (std::map<const Value*, int>::iterator VI = ArrayMap.begin(),
+ VE = ArrayMap.end(); VI != VE; ++VI)
+ if ((*VI).second == i) {
+ const Value *V = (*VI).first;
+ std::string name = V->getNameStr();
+ openscop->arrays[i] = new char[name.size() + 1];
+ strcpy(openscop->arrays[i], name.c_str());
+ }
+}
+
+void OpenScop::initializeScattering() {
+ openscop->nb_scattdims = PollyScop->getScatterDim();
+ openscop->scattdims = new char*[openscop->nb_scattdims];
+
+ for (int i = 0; i < openscop->nb_scattdims; ++i) {
+ openscop->scattdims[i] = new char[20];
+ sprintf(openscop->scattdims[i], "s_%d", i);
+ }
+}
+
+openscop_statement_p OpenScop::initializeStatement(ScopStmt *stmt) {
+ openscop_statement_p Stmt = openscop_statement_malloc();
+
+ // Domain & Schedule
+ Stmt->domain = domainToMatrix(stmt->getDomain());
+ Stmt->schedule = scatteringToMatrix(stmt->getScattering());
+
+ // Statement name
+ const char* entryName = stmt->getBaseName();
+ Stmt->body = (char*)malloc(sizeof(char) * (strlen(entryName) + 1));
+ strcpy(Stmt->body, entryName);
+
+ // Iterator names
+ Stmt->nb_iterators = isl_set_n_dim(stmt->getDomain());
+ Stmt->iterators = new char*[Stmt->nb_iterators];
+
+ for (int i = 0; i < Stmt->nb_iterators; ++i) {
+ Stmt->iterators[i] = new char[20];
+ sprintf(Stmt->iterators[i], "i_%d", i);
+ }
+
+ // Memory Accesses
+ Stmt->read = createAccessMatrix(stmt, true);
+ Stmt->write = createAccessMatrix(stmt, false);
+
+ return Stmt;
+}
+
+void OpenScop::initializeStatements() {
+ for (Scop::reverse_iterator SI = PollyScop->rbegin(), SE = PollyScop->rend();
+ SI != SE; ++SI) {
+ if ((*SI)->isFinalRead())
+ continue;
+ openscop_statement_p stmt = initializeStatement(*SI);
+ stmt->next = openscop->statement;
+ openscop->statement = stmt;
+ }
+}
+
+void OpenScop::freeStatement(openscop_statement_p stmt) {
+
+ if (stmt->read)
+ openscop_matrix_free(stmt->read);
+ stmt->read = NULL;
+
+ if (stmt->write)
+ openscop_matrix_free(stmt->write);
+ stmt->write = NULL;
+
+ if (stmt->domain)
+ openscop_matrix_free(stmt->domain);
+ stmt->domain = NULL;
+
+ if (stmt->schedule)
+ openscop_matrix_free(stmt->schedule);
+ stmt->schedule = NULL;
+
+ for (int i = 0; i < stmt->nb_iterators; ++i)
+ delete[](stmt->iterators[i]);
+
+ delete[](stmt->iterators);
+ stmt->iterators = NULL;
+ stmt->nb_iterators = 0;
+
+ delete[](stmt->body);
+ stmt->body = NULL;
+
+ openscop_statement_free(stmt);
+}
+
+void OpenScop::print(FILE *F) {
+ openscop_scop_print_dot_scop(F, openscop);
+}
+
+/// Add an isl constraint to an OpenScop matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int OpenScop::domainToMatrix_constraint(isl_constraint *c, void *user) {
+ openscop_matrix_p m = (openscop_matrix_p) user;
+
+ int nb_params = isl_constraint_dim(c, isl_dim_param);
+ int nb_vars = isl_constraint_dim(c, isl_dim_set);
+ int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+ assert(!nb_div && "Existentially quantified variables not yet supported");
+
+ openscop_vector_p vec = openscop_vector_malloc(nb_params + nb_vars + 2);
+
+ // Assign type
+ if (isl_constraint_is_equality(c))
+ openscop_vector_tag_equality(vec);
+ else
+ openscop_vector_tag_inequality(vec);
+
+ isl_int v;
+ isl_int_init(v);
+
+ // Assign variables
+ for (int i = 0; i < nb_vars; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_set, i, &v);
+ isl_int_set(vec->p[i + 1], v);
+ }
+
+ // Assign parameters
+ for (int i = 0; i < nb_params; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
+ isl_int_set(vec->p[nb_vars + i + 1], v);
+ }
+
+ // Assign constant
+ isl_constraint_get_constant(c, &v);
+ isl_int_set(vec->p[nb_params + nb_vars + 1], v);
+
+ openscop_matrix_insert_vector(m, vec, m->NbRows);
+
+ return 0;
+}
+
+/// Add an isl basic set to a OpenScop matrix_list
+///
+/// @param bset The basic set to add
+/// @param user The matrix list we should add the basic set to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in OpenScop. So union of
+/// polyhedron are not yet supported
+int OpenScop::domainToMatrix_basic_set(isl_basic_set *bset, void *user) {
+ openscop_matrix_p m = (openscop_matrix_p) user;
+ assert(!m->NbRows && "Union of polyhedron not yet supported");
+
+ isl_basic_set_foreach_constraint(bset, &domainToMatrix_constraint, user);
+ return 0;
+}
+
+/// Translate a isl_set to a OpenScop matrix.
+///
+/// @param PS The set to be translated
+/// @return A OpenScop Matrix
+openscop_matrix_p OpenScop::domainToMatrix(isl_set *PS) {
+
+ // Create a canonical copy of this set.
+ isl_set *set = isl_set_copy(PS);
+ set = isl_set_compute_divs (set);
+ set = isl_set_align_divs (set);
+
+ // Initialize the matrix.
+ unsigned NbRows, NbColumns;
+ NbRows = 0;
+ NbColumns = isl_set_n_dim(PS) + isl_set_n_param(PS) + 2;
+ openscop_matrix_p matrix = openscop_matrix_malloc(NbRows, NbColumns);
+
+ // Copy the content into the matrix.
+ isl_set_foreach_basic_set(set, &domainToMatrix_basic_set, matrix);
+
+ isl_set_free(set);
+
+ return matrix;
+}
+
+/// Add an isl constraint to an OpenScop matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int OpenScop::scatteringToMatrix_constraint(isl_constraint *c, void *user) {
+ openscop_matrix_p m = (openscop_matrix_p) user;
+
+ int nb_params = isl_constraint_dim(c, isl_dim_param);
+ int nb_in = isl_constraint_dim(c, isl_dim_in);
+ int nb_out = isl_constraint_dim(c, isl_dim_out);
+ int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+ assert(!nb_div && "Existentially quantified variables not yet supported");
+
+ openscop_vector_p vec =
+ openscop_vector_malloc(nb_params + nb_in + nb_out + 2);
+
+ // Assign type
+ if (isl_constraint_is_equality(c))
+ openscop_vector_tag_equality(vec);
+ else
+ openscop_vector_tag_inequality(vec);
+
+ isl_int v;
+ isl_int_init(v);
+
+ // Assign scattering
+ for (int i = 0; i < nb_out; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_out, i, &v);
+ isl_int_set(vec->p[i + 1], v);
+ }
+
+ // Assign variables
+ for (int i = 0; i < nb_in; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_in, i, &v);
+ isl_int_set(vec->p[nb_out + i + 1], v);
+ }
+
+ // Assign parameters
+ for (int i = 0; i < nb_params; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
+ isl_int_set(vec->p[nb_out + nb_in + i + 1], v);
+ }
+
+ // Assign constant
+ isl_constraint_get_constant(c, &v);
+ isl_int_set(vec->p[nb_out + nb_in + nb_params + 1], v);
+
+ openscop_matrix_insert_vector(m, vec, m->NbRows);
+
+ return 0;
+}
+
+/// Add an isl basic map to a OpenScop matrix_list
+///
+/// @param bmap The basic map to add
+/// @param user The matrix list we should add the basic map to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in OpenScop. So union of
+/// polyhedron are not yet supported
+int OpenScop::scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user) {
+ openscop_matrix_p m = (openscop_matrix_p) user;
+ assert(!m->NbRows && "Union of polyhedron not yet supported");
+
+ isl_basic_map_foreach_constraint(bmap, &scatteringToMatrix_constraint, user);
+ return 0;
+}
+
+/// Translate a isl_map to a OpenScop matrix.
+///
+/// @param map The map to be translated
+/// @return A OpenScop Matrix
+openscop_matrix_p OpenScop::scatteringToMatrix(isl_map *pmap) {
+
+ // Create a canonical copy of this set.
+ isl_map *map = isl_map_copy(pmap);
+ map = isl_map_compute_divs (map);
+ map = isl_map_align_divs (map);
+
+ // Initialize the matrix.
+ unsigned NbRows, NbColumns;
+ NbRows = 0;
+ NbColumns = isl_map_n_in(pmap) + isl_map_n_out(pmap) + isl_map_n_param(pmap)
+ + 2;
+ openscop_matrix_p matrix = openscop_matrix_malloc(NbRows, NbColumns);
+
+ // Copy the content into the matrix.
+ isl_map_foreach_basic_map(map, &scatteringToMatrix_basic_map, matrix);
+
+ isl_map_free(map);
+
+ return matrix;
+}
+
+/// Add an isl constraint to an OpenScop matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int OpenScop::accessToMatrix_constraint(isl_constraint *c, void *user) {
+ openscop_matrix_p m = (openscop_matrix_p) user;
+
+ int nb_params = isl_constraint_dim(c, isl_dim_param);
+ int nb_in = isl_constraint_dim(c, isl_dim_in);
+ int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+ assert(!nb_div && "Existentially quantified variables not yet supported");
+
+ openscop_vector_p vec =
+ openscop_vector_malloc(nb_params + nb_in + 2);
+
+ isl_int v;
+ isl_int_init(v);
+
+ // The access dimension has to be one.
+ isl_constraint_get_coefficient(c, isl_dim_out, 0, &v);
+ assert(isl_int_is_one(v));
+ bool inverse = true ;
+
+ // Assign variables
+ for (int i = 0; i < nb_in; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_in, i, &v);
+
+ if (inverse) isl_int_neg(v,v);
+
+ isl_int_set(vec->p[i + 1], v);
+ }
+
+ // Assign parameters
+ for (int i = 0; i < nb_params; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
+
+ if (inverse) isl_int_neg(v,v);
+
+ isl_int_set(vec->p[nb_in + i + 1], v);
+ }
+
+ // Assign constant
+ isl_constraint_get_constant(c, &v);
+
+ if (inverse) isl_int_neg(v,v);
+
+ isl_int_set(vec->p[nb_in + nb_params + 1], v);
+
+ openscop_matrix_insert_vector(m, vec, m->NbRows);
+
+ return 0;
+}
+
+
+/// Add an isl basic map to a OpenScop matrix_list
+///
+/// @param bmap The basic map to add
+/// @param user The matrix list we should add the basic map to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in OpenScop. So union of
+/// polyhedron are not yet supported
+int OpenScop::accessToMatrix_basic_map(isl_basic_map *bmap, void *user) {
+ isl_basic_map_foreach_constraint(bmap, &accessToMatrix_constraint, user);
+ return 0;
+}
+
+/// Create the memory access matrix for openscop
+///
+/// @param S The polly statement the access matrix is created for.
+/// @param isRead Are we looking for read or write accesses?
+/// @param ArrayMap A map translating from the memory references to the openscop
+/// indeces
+///
+/// @return The memory access matrix, as it is required by openscop.
+openscop_matrix_p OpenScop::createAccessMatrix(ScopStmt *S, bool isRead) {
+
+ unsigned NbColumns = S->getNumIterators() + S->getNumParams() + 2;
+ openscop_matrix_p m = openscop_matrix_malloc(0, NbColumns);
+
+ for (ScopStmt::memacc_iterator MI = S->memacc_begin(), ME = S->memacc_end();
+ MI != ME; ++MI)
+ if ((*MI)->isRead() == isRead) {
+ // Extract the access function.
+ isl_map_foreach_basic_map((*MI)->getAccessFunction(),
+ &accessToMatrix_basic_map, m);
+
+ // Set the index of the memory access base element.
+ std::map<const Value*, int>::iterator BA =
+ ArrayMap.find((*MI)->getBaseAddr());
+ isl_int_set_si(m->p[m->NbRows - 1][0], (*BA).second + 1);
+ }
+
+ return m;
+}
+
+OpenScop::~OpenScop() {
+ // Free array names.
+ for (int i = 0; i < openscop->nb_arrays; ++i)
+ delete[](openscop->arrays[i]);
+
+ delete[](openscop->arrays);
+ openscop->arrays = NULL;
+ openscop->nb_arrays = 0;
+
+ // Free scattering names.
+ for (int i = 0; i < openscop->nb_scattdims; ++i)
+ delete[](openscop->scattdims[i]);
+
+ delete[](openscop->scattdims);
+ openscop->scattdims = NULL;
+ openscop->nb_scattdims = 0;
+
+ // Free parameters
+ for (int i = 0; i < openscop->nb_parameters; ++i)
+ delete[](openscop->parameters[i]);
+
+ delete[](openscop->parameters);
+ openscop->parameters = NULL;
+ openscop->nb_parameters = 0;
+
+ openscop_statement_p stmt = openscop->statement;
+
+ // Free Statements
+ while (stmt) {
+ openscop_statement_p TempStmt = stmt->next;
+ stmt->next = NULL;
+ freeStatement(stmt);
+ stmt = TempStmt;
+ }
+
+ openscop->statement = NULL;
+
+ openscop_scop_free(openscop);
+}
+
+std::string ScopExporter::getFileName(Scop *S) const {
+ std::string FunctionName =
+ S->getRegion().getEntry()->getParent()->getNameStr();
+ std::string FileName = FunctionName + "___" + S->getNameStr() + ".scop";
+ return FileName;
+}
+
+void ScopExporter::printScop(raw_ostream &OS) const {
+ S->print(OS);
+}
+
+bool ScopExporter::runOnScop(Scop &scop) {
+ S = &scop;
+ Region &R = S->getRegion();
+
+ std::string FileName = ExportDir + "/" + getFileName(S);
+ FILE *F = fopen(FileName.c_str(), "w");
+
+ if (!F) {
+ errs() << "Cannot open file: " << FileName << "\n";
+ errs() << "Skipping export.\n";
+ return false;
+ }
+
+ OpenScop openscop(S);
+ openscop.print(F);
+ fclose(F);
+
+ std::string FunctionName = R.getEntry()->getParent()->getNameStr();
+ errs() << "Writing Scop '" << R.getNameStr() << "' in function '"
+ << FunctionName << "' to '" << FileName << "'.\n";
+
+ return false;
+}
+
+void ScopExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+}
+
+static RegisterPass<ScopExporter> A("polly-export",
+ "Polly - Export Scops with OpenScop library"
+ " (Writes a .scop file for each Scop)"
+ );
+
+Pass *polly::createScopExporterPass() {
+ return new ScopExporter();
+}
+
+#endif
+
--- /dev/null
+//===-- OpenScopImporter.cpp - Import Scops with openscop library --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Import modified .scop files into Polly. This allows to change the schedule of
+// statements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+
+#include "polly/Dependences.h"
+#include "polly/ScopInfo.h"
+#include "polly/ScopPass.h"
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Assembly/Writer.h"
+
+#ifdef OPENSCOP_FOUND
+
+#define OPENSCOP_INT_T_IS_MP
+#include "openscop/openscop.h"
+
+#include "isl/set.h"
+#include "isl/constraint.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+ static cl::opt<std::string>
+ ImportDir("polly-import-dir",
+ cl::desc("The directory to import the .scop files from."),
+ cl::Hidden, cl::value_desc("Directory path"), cl::ValueRequired,
+ cl::init("."));
+ static cl::opt<std::string>
+ ImportPostfix("polly-import-postfix",
+ cl::desc("Postfix to append to the import .scop files."),
+ cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired,
+ cl::init(""));
+
+ struct ScopImporter : public ScopPass {
+ static char ID;
+ Scop *S;
+ Dependences *D;
+ explicit ScopImporter() : ScopPass(ID) {}
+ bool updateScattering(Scop *S, openscop_scop_p OScop);
+
+ std::string getFileName(Scop *S) const;
+ virtual bool runOnScop(Scop &S);
+ virtual void printScop(raw_ostream &OS) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ };
+}
+
+char ScopImporter::ID = 0;
+
+/// @brief Create an isl constraint from a row of OpenScop integers.
+///
+/// @param row An array of isl/OpenScop integers.
+/// @param dim An isl dim object, describing how to spilt the dimensions.
+///
+/// @return An isl constraint representing this integer array.
+isl_constraint *constraintFromMatrixRow(isl_int *row, isl_dim *dim) {
+ isl_constraint *c;
+
+ unsigned NbOut = isl_dim_size(dim, isl_dim_out);
+ unsigned NbIn = isl_dim_size(dim, isl_dim_in);
+ unsigned NbParam = isl_dim_size(dim, isl_dim_param);
+
+ if (isl_int_is_zero(row[0]))
+ c = isl_equality_alloc(isl_dim_copy(dim));
+ else
+ c = isl_inequality_alloc(isl_dim_copy(dim));
+
+ unsigned current_column = 1;
+
+ for (unsigned j = 0; j < NbOut; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_out, j, row[current_column++]);
+
+ for (unsigned j = 0; j < NbIn; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_in, j, row[current_column++]);
+
+ for (unsigned j = 0; j < NbParam; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_param, j, row[current_column++]);
+
+ isl_constraint_set_constant(c, row[current_column]);
+
+ return c;
+}
+
+/// @brief Create an isl map from a OpenScop matrix.
+///
+/// @param m The OpenScop matrix to translate.
+/// @param dim The dimensions that are contained in the OpenScop matrix.
+///
+/// @return An isl map representing m.
+isl_map *mapFromMatrix(openscop_matrix_p m, isl_dim *dim) {
+ isl_basic_map *bmap = isl_basic_map_universe(isl_dim_copy(dim));
+
+ for (unsigned i = 0; i < m->NbRows; ++i) {
+ isl_constraint *c;
+
+ c = constraintFromMatrixRow(m->p[i], dim);
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ }
+
+ return isl_map_from_basic_map(bmap);
+}
+
+/// @brief Create a new scattering for PollyStmt.
+///
+/// @param m The matrix describing the new scattering.
+/// @param PollyStmt The statement to create the scattering for.
+///
+/// @return An isl_map describing the scattering.
+isl_map *scatteringForStmt(openscop_matrix_p m, ScopStmt *PollyStmt) {
+
+ unsigned NbParam = PollyStmt->getNumParams();
+ unsigned NbIterators = PollyStmt->getNumIterators();
+ unsigned NbScattering = m->NbColumns - 2 - NbParam - NbIterators;
+
+ isl_ctx *ctx = PollyStmt->getParent()->getCtx();
+ isl_dim *dim = isl_dim_alloc(ctx, NbParam, NbIterators, NbScattering);
+ dim = isl_dim_set_tuple_name(dim, isl_dim_out, "scattering");
+ dim = isl_dim_set_tuple_name(dim, isl_dim_in, PollyStmt->getBaseName());
+ isl_map *map = mapFromMatrix(m, dim);
+ isl_dim_free(dim);
+
+ return map;
+}
+
+typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
+
+/// @brief Read the new scattering from the OpenScop description.
+///
+/// @S The Scop to update
+/// @OScop The OpenScop data structure describing the new scattering.
+/// @return A map that contains for each Statement the new scattering.
+StatementToIslMapTy *readScattering(Scop *S, openscop_scop_p OScop) {
+ StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy());
+ openscop_statement_p stmt = OScop->statement;
+
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+
+ if ((*SI)->isFinalRead())
+ continue;
+
+ if (!stmt) {
+ errs() << "Not enough statements available in OpenScop file\n";
+ delete &NewScattering;
+ return NULL;
+ }
+
+ NewScattering[*SI] = scatteringForStmt(stmt->schedule, *SI);
+ stmt = stmt->next;
+ }
+
+ if (stmt) {
+ errs() << "Too many statements in OpenScop file\n";
+ delete &NewScattering;
+ return NULL;
+ }
+
+ return &NewScattering;
+}
+
+/// @brief Update the scattering in a Scop using the OpenScop description of
+/// the scattering.
+///
+/// @S The Scop to update
+/// @OScop The OpenScop data structure describing the new scattering.
+/// @return Returns false, if the update failed.
+bool ScopImporter::updateScattering(Scop *S, openscop_scop_p OScop) {
+ StatementToIslMapTy *NewScattering = readScattering(S, OScop);
+
+ if (!NewScattering)
+ return false;
+
+ if (!D->isValidScattering(NewScattering)) {
+ errs() << "OpenScop file contains a scattering that changes the "
+ << "dependences. Use -disable-polly-legality to continue anyways\n";
+ return false;
+ }
+
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ if (NewScattering->find(Stmt) != NewScattering->end())
+ Stmt->setScattering((*NewScattering)[Stmt]);
+ }
+
+ return true;
+}
+std::string ScopImporter::getFileName(Scop *S) const {
+ std::string FunctionName =
+ S->getRegion().getEntry()->getParent()->getNameStr();
+ std::string FileName = FunctionName + "___" + S->getNameStr() + ".scop";
+ return FileName;
+}
+
+void ScopImporter::printScop(raw_ostream &OS) const {
+ S->print(OS);
+}
+
+bool ScopImporter::runOnScop(Scop &scop) {
+ S = &scop;
+ Region &R = scop.getRegion();
+ D = &getAnalysis<Dependences>();
+
+ std::string FileName = ImportDir + "/" + getFileName(S) + ImportPostfix;
+ FILE *F = fopen(FileName.c_str(), "r");
+
+ if (!F) {
+ errs() << "Cannot open file: " << FileName << "\n";
+ errs() << "Skipping import.\n";
+ return false;
+ }
+
+ openscop_scop_p openscop = openscop_scop_read(F);
+ fclose(F);
+
+ std::string FunctionName = R.getEntry()->getParent()->getNameStr();
+ errs() << "Reading Scop '" << R.getNameStr() << "' in function '"
+ << FunctionName << "' from '" << FileName << "'.\n";
+
+ bool UpdateSuccessfull = updateScattering(S, openscop);
+
+ if (!UpdateSuccessfull) {
+ errs() << "Update failed" << "\n";
+ }
+
+ return false;
+}
+
+void ScopImporter::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+ AU.addRequired<Dependences>();
+}
+
+static RegisterPass<ScopImporter> A("polly-import",
+ "Polly - Import Scops with OpenScop library"
+ " (Reads a .scop file for each Scop)"
+ );
+
+Pass *polly::createScopImporterPass() {
+ return new ScopImporter();
+}
+
+#endif
--- /dev/null
+//===- ScopLib.cpp - ScopLib interface ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// ScopLib Interface
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+
+#ifdef SCOPLIB_FOUND
+
+#include "polly/Dependences.h"
+#include "polly/ScopLib.h"
+#include "polly/ScopInfo.h"
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Assembly/Writer.h"
+
+#include "stdio.h"
+#include "isl/set.h"
+#include "isl/constraint.h"
+
+using namespace llvm;
+
+namespace polly {
+
+ScopLib::ScopLib(Scop *S) : PollyScop(S) {
+ scoplib = scoplib_scop_malloc();
+
+ initializeArrays();
+ initializeParameters();
+ initializeScattering();
+ initializeStatements();
+}
+
+ScopLib::ScopLib(Scop *S, FILE *F, Dependences *dep) : PollyScop(S), D(dep) {
+ scoplib = scoplib_scop_read(F);
+}
+
+void ScopLib::initializeParameters() {
+ scoplib->nb_parameters = PollyScop->getNumParams();
+ scoplib->parameters = (char**) malloc(sizeof(char*) * scoplib->nb_parameters);
+
+ for (int i = 0; i < scoplib->nb_parameters; ++i) {
+ scoplib->parameters[i] = (char *) malloc(sizeof(char*) * 20);
+ sprintf(scoplib->parameters[i], "p_%d", i);
+ }
+}
+
+void ScopLib::initializeArrays() {
+ int nb_arrays = 0;
+
+ for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE;
+ ++SI)
+ for (ScopStmt::memacc_iterator MI = (*SI)->memacc_begin(),
+ ME = (*SI)->memacc_end(); MI != ME; ++MI) {
+ const Value *BaseAddr = (*MI)->getBaseAddr();
+ if (ArrayMap.find(BaseAddr) == ArrayMap.end()) {
+ ArrayMap.insert(std::make_pair(BaseAddr, nb_arrays));
+ ++nb_arrays;
+ }
+ }
+
+ scoplib->nb_arrays = nb_arrays;
+ scoplib->arrays = (char**)malloc(sizeof(char*) * nb_arrays);
+
+ for (int i = 0; i < nb_arrays; ++i)
+ for (std::map<const Value*, int>::iterator VI = ArrayMap.begin(),
+ VE = ArrayMap.end(); VI != VE; ++VI)
+ if ((*VI).second == i) {
+ const Value *V = (*VI).first;
+ std::string name = V->getNameStr();
+ scoplib->arrays[i] = (char*) malloc(sizeof(char*) * (name.size() + 1));
+ strcpy(scoplib->arrays[i], name.c_str());
+ }
+}
+
+void ScopLib::initializeScattering() {
+}
+
+scoplib_statement_p ScopLib::initializeStatement(ScopStmt *stmt) {
+ scoplib_statement_p Stmt = scoplib_statement_malloc();
+
+ // Domain & Schedule
+ Stmt->domain = scoplib_matrix_list_malloc();
+ Stmt->domain->elt = domainToMatrix(stmt->getDomain());
+ Stmt->domain->next = NULL;
+ Stmt->schedule = scatteringToMatrix(stmt->getScattering());
+
+ // Statement name
+ std::string entryName;
+ raw_string_ostream OS(entryName);
+ WriteAsOperand(OS, stmt->getBasicBlock(), false);
+ entryName = OS.str();
+ Stmt->body = (char*)malloc(sizeof(char) * (entryName.size() + 1));
+ strcpy(Stmt->body, entryName.c_str());
+
+ // Iterator names
+ Stmt->nb_iterators = isl_set_n_dim(stmt->getDomain());
+ Stmt->iterators = (char**) malloc(sizeof(char*) * Stmt->nb_iterators);
+
+ for (int i = 0; i < Stmt->nb_iterators; ++i) {
+ Stmt->iterators[i] = (char*) malloc(sizeof(char*) * 20);
+ sprintf(Stmt->iterators[i], "i_%d", i);
+ }
+
+ // Memory Accesses
+ Stmt->read = createAccessMatrix(stmt, true);
+ Stmt->write = createAccessMatrix(stmt, false);
+
+ return Stmt;
+}
+
+void ScopLib::initializeStatements() {
+ for (Scop::reverse_iterator SI = PollyScop->rbegin(), SE = PollyScop->rend();
+ SI != SE; ++SI) {
+
+ if ((*SI)->isFinalRead())
+ continue;
+
+ scoplib_statement_p stmt = initializeStatement(*SI);
+ stmt->next = scoplib->statement;
+ scoplib->statement = stmt;
+ }
+}
+
+void ScopLib::freeStatement(scoplib_statement_p stmt) {
+
+ if (stmt->read)
+ scoplib_matrix_free(stmt->read);
+ stmt->read = NULL;
+
+ if (stmt->write)
+ scoplib_matrix_free(stmt->write);
+ stmt->write = NULL;
+
+ while (stmt->domain) {
+ scoplib_matrix_free(stmt->domain->elt);
+ stmt->domain = stmt->domain->next;
+ }
+
+ if (stmt->schedule)
+ scoplib_matrix_free(stmt->schedule);
+ stmt->schedule = NULL;
+
+ for (int i = 0; i < stmt->nb_iterators; ++i)
+ free(stmt->iterators[i]);
+
+ free(stmt->iterators);
+ stmt->iterators = NULL;
+ stmt->nb_iterators = 0;
+
+ scoplib_statement_free(stmt);
+}
+
+void ScopLib::print(FILE *F) {
+ scoplib_scop_print_dot_scop(F, scoplib);
+}
+
+/// Add an isl constraint to an ScopLib matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int ScopLib::domainToMatrix_constraint(isl_constraint *c, void *user) {
+ scoplib_matrix_p m = (scoplib_matrix_p) user;
+
+ int nb_params = isl_constraint_dim(c, isl_dim_param);
+ int nb_vars = isl_constraint_dim(c, isl_dim_set);
+ int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+ assert(!nb_div && "Existentially quantified variables not yet supported");
+
+ scoplib_vector_p vec = scoplib_vector_malloc(nb_params + nb_vars + 2);
+
+ // Assign type
+ if (isl_constraint_is_equality(c))
+ scoplib_vector_tag_equality(vec);
+ else
+ scoplib_vector_tag_inequality(vec);
+
+ isl_int v;
+ isl_int_init(v);
+
+ // Assign variables
+ for (int i = 0; i < nb_vars; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_set, i, &v);
+ isl_int_set(vec->p[i + 1], v);
+ }
+
+ // Assign parameters
+ for (int i = 0; i < nb_params; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
+ isl_int_set(vec->p[nb_vars + i + 1], v);
+ }
+
+ // Assign constant
+ isl_constraint_get_constant(c, &v);
+ isl_int_set(vec->p[nb_params + nb_vars + 1], v);
+
+ scoplib_matrix_insert_vector(m, vec, m->NbRows);
+
+ return 0;
+}
+
+/// Add an isl basic set to a ScopLib matrix_list
+///
+/// @param bset The basic set to add
+/// @param user The matrix list we should add the basic set to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in ScopLib. So union of
+/// polyhedron are not yet supported
+int ScopLib::domainToMatrix_basic_set(isl_basic_set *bset, void *user) {
+ scoplib_matrix_p m = (scoplib_matrix_p) user;
+ assert(!m->NbRows && "Union of polyhedron not yet supported");
+
+ isl_basic_set_foreach_constraint(bset, &domainToMatrix_constraint, user);
+ return 0;
+}
+
+/// Translate a isl_set to a ScopLib matrix.
+///
+/// @param PS The set to be translated
+/// @return A ScopLib Matrix
+scoplib_matrix_p ScopLib::domainToMatrix(isl_set *PS) {
+
+ // Create a canonical copy of this set.
+ isl_set *set = isl_set_copy(PS);
+ set = isl_set_compute_divs (set);
+ set = isl_set_align_divs (set);
+
+ // Initialize the matrix.
+ unsigned NbRows, NbColumns;
+ NbRows = 0;
+ NbColumns = isl_set_n_dim(PS) + isl_set_n_param(PS) + 2;
+ scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns);
+
+ // Copy the content into the matrix.
+ isl_set_foreach_basic_set(set, &domainToMatrix_basic_set, matrix);
+
+ isl_set_free(set);
+
+ return matrix;
+}
+
+/// Add an isl constraint to an ScopLib matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int ScopLib::scatteringToMatrix_constraint(isl_constraint *c, void *user) {
+ scoplib_matrix_p m = (scoplib_matrix_p) user;
+
+ int nb_params = isl_constraint_dim(c, isl_dim_param);
+ int nb_in = isl_constraint_dim(c, isl_dim_in);
+ int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+ assert(!nb_div && "Existentially quantified variables not yet supported");
+
+ scoplib_vector_p vec =
+ scoplib_vector_malloc(nb_params + nb_in + 2);
+
+ // Assign type
+ if (isl_constraint_is_equality(c))
+ scoplib_vector_tag_equality(vec);
+ else
+ scoplib_vector_tag_inequality(vec);
+
+ isl_int v;
+ isl_int_init(v);
+
+ // Assign variables
+ for (int i = 0; i < nb_in; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_in, i, &v);
+ isl_int_set(vec->p[i + 1], v);
+ }
+
+ // Assign parameters
+ for (int i = 0; i < nb_params; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
+ isl_int_set(vec->p[nb_in + i + 1], v);
+ }
+
+ // Assign constant
+ isl_constraint_get_constant(c, &v);
+ isl_int_set(vec->p[nb_in + nb_params + 1], v);
+
+ scoplib_vector_p null =
+ scoplib_vector_malloc(nb_params + nb_in + 2);
+
+ vec = scoplib_vector_sub(null, vec);
+ scoplib_matrix_insert_vector(m, vec, 0);
+
+ return 0;
+}
+
+/// Add an isl basic map to a ScopLib matrix_list
+///
+/// @param bmap The basic map to add
+/// @param user The matrix list we should add the basic map to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in ScopLib. So union of
+/// polyhedron are not yet supported
+int ScopLib::scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user) {
+ scoplib_matrix_p m = (scoplib_matrix_p) user;
+ assert(!m->NbRows && "Union of polyhedron not yet supported");
+
+ isl_basic_map_foreach_constraint(bmap, &scatteringToMatrix_constraint, user);
+ return 0;
+}
+
+/// Translate a isl_map to a ScopLib matrix.
+///
+/// @param map The map to be translated
+/// @return A ScopLib Matrix
+scoplib_matrix_p ScopLib::scatteringToMatrix(isl_map *pmap) {
+
+ // Create a canonical copy of this set.
+ isl_map *map = isl_map_copy(pmap);
+ map = isl_map_compute_divs (map);
+ map = isl_map_align_divs (map);
+
+ // Initialize the matrix.
+ unsigned NbRows, NbColumns;
+ NbRows = 0;
+ NbColumns = isl_map_n_in(pmap) + isl_map_n_param(pmap) + 2;
+ scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns);
+
+ // Copy the content into the matrix.
+ isl_map_foreach_basic_map(map, &scatteringToMatrix_basic_map, matrix);
+
+ // Only keep the relevant rows.
+ scoplib_matrix_p reduced = scoplib_matrix_ncopy(matrix,
+ isl_map_n_in(pmap) * 2 + 1);
+
+ scoplib_matrix_free (matrix);
+ isl_map_free(map);
+
+ return reduced;
+}
+
+/// Add an isl constraint to an ScopLib matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int ScopLib::accessToMatrix_constraint(isl_constraint *c, void *user) {
+ scoplib_matrix_p m = (scoplib_matrix_p) user;
+
+ int nb_params = isl_constraint_dim(c, isl_dim_param);
+ int nb_in = isl_constraint_dim(c, isl_dim_in);
+ int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+ assert(!nb_div && "Existentially quantified variables not yet supported");
+
+ scoplib_vector_p vec =
+ scoplib_vector_malloc(nb_params + nb_in + 2);
+
+ isl_int v;
+ isl_int_init(v);
+
+ // The access dimension has to be one.
+ isl_constraint_get_coefficient(c, isl_dim_out, 0, &v);
+ assert(isl_int_is_one(v));
+ bool inverse = true ;
+
+ // Assign variables
+ for (int i = 0; i < nb_in; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_in, i, &v);
+
+ if (inverse) isl_int_neg(v,v);
+
+ isl_int_set(vec->p[i + 1], v);
+ }
+
+ // Assign parameters
+ for (int i = 0; i < nb_params; ++i) {
+ isl_constraint_get_coefficient(c, isl_dim_param, i, &v);
+
+ if (inverse) isl_int_neg(v,v);
+
+ isl_int_set(vec->p[nb_in + i + 1], v);
+ }
+
+ // Assign constant
+ isl_constraint_get_constant(c, &v);
+
+ if (inverse) isl_int_neg(v,v);
+
+ isl_int_set(vec->p[nb_in + nb_params + 1], v);
+
+ scoplib_matrix_insert_vector(m, vec, m->NbRows);
+
+ return 0;
+}
+
+
+/// Add an isl basic map to a ScopLib matrix_list
+///
+/// @param bmap The basic map to add
+/// @param user The matrix list we should add the basic map to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in ScopLib. So union of
+/// polyhedron are not yet supported
+int ScopLib::accessToMatrix_basic_map(isl_basic_map *bmap, void *user) {
+ isl_basic_map_foreach_constraint(bmap, &accessToMatrix_constraint, user);
+ return 0;
+}
+
+/// Create the memory access matrix for scoplib
+///
+/// @param S The polly statement the access matrix is created for.
+/// @param isRead Are we looking for read or write accesses?
+/// @param ArrayMap A map translating from the memory references to the scoplib
+/// indeces
+///
+/// @return The memory access matrix, as it is required by scoplib.
+scoplib_matrix_p ScopLib::createAccessMatrix(ScopStmt *S, bool isRead) {
+
+ unsigned NbColumns = S->getNumIterators() + S->getNumParams() + 2;
+ scoplib_matrix_p m = scoplib_matrix_malloc(0, NbColumns);
+
+ for (ScopStmt::memacc_iterator MI = S->memacc_begin(), ME = S->memacc_end();
+ MI != ME; ++MI)
+ if ((*MI)->isRead() == isRead) {
+ // Extract the access function.
+ isl_map_foreach_basic_map((*MI)->getAccessFunction(),
+ &accessToMatrix_basic_map, m);
+
+ // Set the index of the memory access base element.
+ std::map<const Value*, int>::iterator BA =
+ ArrayMap.find((*MI)->getBaseAddr());
+ isl_int_set_si(m->p[m->NbRows - 1][0], (*BA).second + 1);
+ }
+
+ return m;
+}
+
+ScopLib::~ScopLib() {
+ if (!scoplib)
+ return;
+
+ // Free array names.
+ for (int i = 0; i < scoplib->nb_arrays; ++i)
+ free(scoplib->arrays[i]);
+
+ free(scoplib->arrays);
+ scoplib->arrays = NULL;
+ scoplib->nb_arrays = 0;
+
+ // Free parameters
+ for (int i = 0; i < scoplib->nb_parameters; ++i)
+ free(scoplib->parameters[i]);
+
+ free(scoplib->parameters);
+ scoplib->parameters = NULL;
+ scoplib->nb_parameters = 0;
+
+ scoplib_statement_p stmt = scoplib->statement;
+
+ // Free Statements
+ while (stmt) {
+ scoplib_statement_p TempStmt = stmt->next;
+ stmt->next = NULL;
+ freeStatement(stmt);
+ stmt = TempStmt;
+ }
+
+ scoplib->statement = NULL;
+
+ scoplib_scop_free(scoplib);
+}
+/// @brief Create an isl constraint from a row of OpenScop integers.
+///
+/// @param row An array of isl/OpenScop integers.
+/// @param dim An isl dim object, describing how to spilt the dimensions.
+///
+/// @return An isl constraint representing this integer array.
+isl_constraint *constraintFromMatrixRow(isl_int *row, isl_dim *dim) {
+ isl_constraint *c;
+
+ unsigned NbIn = isl_dim_size(dim, isl_dim_in);
+ unsigned NbParam = isl_dim_size(dim, isl_dim_param);
+
+ if (isl_int_is_zero(row[0]))
+ c = isl_equality_alloc(isl_dim_copy(dim));
+ else
+ c = isl_inequality_alloc(isl_dim_copy(dim));
+
+ unsigned current_column = 1;
+
+ for (unsigned j = 0; j < NbIn; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_in, j, row[current_column++]);
+
+ for (unsigned j = 0; j < NbParam; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_param, j, row[current_column++]);
+
+ isl_constraint_set_constant(c, row[current_column]);
+
+ return c;
+}
+
+/// @brief Create an isl map from a OpenScop matrix.
+///
+/// @param m The OpenScop matrix to translate.
+/// @param dim The dimensions that are contained in the OpenScop matrix.
+///
+/// @return An isl map representing m.
+isl_map *mapFromMatrix(scoplib_matrix_p m, isl_dim *dim,
+ unsigned scatteringDims) {
+ isl_basic_map *bmap = isl_basic_map_universe(isl_dim_copy(dim));
+
+ for (unsigned i = 0; i < m->NbRows; ++i) {
+ isl_constraint *c;
+
+ c = constraintFromMatrixRow(m->p[i], dim);
+
+ mpz_t minusOne;
+ mpz_init(minusOne);
+ mpz_set_si(minusOne, -1);
+ isl_constraint_set_coefficient(c, isl_dim_out, i, minusOne);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ }
+
+ for (unsigned i = m->NbRows; i < scatteringDims; i++) {
+ isl_constraint *c;
+
+ c = isl_equality_alloc(isl_dim_copy(dim));
+
+ mpz_t One;
+ mpz_init(One);
+ mpz_set_si(One, 1);
+ isl_constraint_set_coefficient(c, isl_dim_out, i, One);
+
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ }
+
+ return isl_map_from_basic_map(bmap);
+}
+/// @brief Create an isl constraint from a row of OpenScop integers.
+///
+/// @param row An array of isl/OpenScop integers.
+/// @param dim An isl dim object, describing how to spilt the dimensions.
+///
+/// @return An isl constraint representing this integer array.
+isl_constraint *constraintFromMatrixRowFull(isl_int *row, isl_dim *dim) {
+ isl_constraint *c;
+
+ unsigned NbOut = isl_dim_size(dim, isl_dim_out);
+ unsigned NbIn = isl_dim_size(dim, isl_dim_in);
+ unsigned NbParam = isl_dim_size(dim, isl_dim_param);
+
+ if (isl_int_is_zero(row[0]))
+ c = isl_equality_alloc(isl_dim_copy(dim));
+ else
+ c = isl_inequality_alloc(isl_dim_copy(dim));
+
+ unsigned current_column = 1;
+
+ for (unsigned j = 0; j < NbOut; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_out, j, row[current_column++]);
+
+ for (unsigned j = 0; j < NbIn; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_in, j, row[current_column++]);
+
+ for (unsigned j = 0; j < NbParam; ++j)
+ isl_constraint_set_coefficient(c, isl_dim_param, j, row[current_column++]);
+
+ isl_constraint_set_constant(c, row[current_column]);
+
+ return c;
+}
+
+/// @brief Create an isl map from a OpenScop matrix.
+///
+/// @param m The OpenScop matrix to translate.
+/// @param dim The dimensions that are contained in the OpenScop matrix.
+///
+/// @return An isl map representing m.
+isl_map *mapFromMatrix(scoplib_matrix_p m, isl_dim *dim) {
+ isl_basic_map *bmap = isl_basic_map_universe(isl_dim_copy(dim));
+
+ for (unsigned i = 0; i < m->NbRows; ++i) {
+ isl_constraint *c;
+
+ c = constraintFromMatrixRowFull(m->p[i], dim);
+ bmap = isl_basic_map_add_constraint(bmap, c);
+ }
+
+ return isl_map_from_basic_map(bmap);
+}
+
+/// @brief Create a new scattering for PollyStmt.
+///
+/// @param m The matrix describing the new scattering.
+/// @param PollyStmt The statement to create the scattering for.
+///
+/// @return An isl_map describing the scattering.
+isl_map *scatteringForStmt(scoplib_matrix_p m, ScopStmt *PollyStmt,
+ int scatteringDims) {
+
+ unsigned NbParam = PollyStmt->getNumParams();
+ unsigned NbIterators = PollyStmt->getNumIterators();
+ unsigned NbScattering;
+
+ if (scatteringDims == -1)
+ NbScattering = m->NbColumns - 2 - NbParam - NbIterators;
+ else
+ NbScattering = scatteringDims;
+
+ isl_ctx *ctx = PollyStmt->getParent()->getCtx();
+ isl_dim *dim = isl_dim_alloc(ctx, NbParam, NbIterators, NbScattering);
+ dim = isl_dim_set_tuple_name(dim, isl_dim_out, "scattering");
+ dim = isl_dim_set_tuple_name(dim, isl_dim_in, PollyStmt->getBaseName());
+
+ isl_map *map;
+
+ if (scatteringDims == -1)
+ map = mapFromMatrix(m, dim);
+ else
+ map = mapFromMatrix(m, dim, scatteringDims);
+
+ isl_dim_free(dim);
+
+ return map;
+}
+
+unsigned maxScattering(scoplib_statement_p stmt) {
+ unsigned max = 0;
+
+ while (stmt) {
+ max = std::max(max, stmt->schedule->NbRows);
+ stmt = stmt->next;
+ }
+
+ return max;
+}
+
+typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
+
+/// @brief Read the new scattering from the scoplib description.
+///
+/// @S The Scop to update
+/// @OScop The ScopLib data structure describing the new scattering.
+/// @return A map that contains for each Statement the new scattering.
+StatementToIslMapTy *readScattering(Scop *S, scoplib_scop_p OScop) {
+ StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy());
+
+ scoplib_statement_p stmt = OScop->statement;
+
+ // Check if we have dimensions for each scattering or if each row
+ // represents a scattering dimension.
+ int numScatteringDims = -1;
+ ScopStmt *pollyStmt = *S->begin();
+
+ if (stmt->schedule->NbColumns
+ == 2 + pollyStmt->getNumParams() + pollyStmt->getNumIterators()) {
+ numScatteringDims = maxScattering(stmt);
+ }
+
+ for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+
+ if ((*SI)->isFinalRead())
+ continue;
+
+ if (!stmt) {
+ errs() << "Not enough statements available in OpenScop file\n";
+ delete &NewScattering;
+ return NULL;
+ }
+
+ NewScattering[*SI] = scatteringForStmt(stmt->schedule, *SI,
+ numScatteringDims);
+ stmt = stmt->next;
+ }
+
+ if (stmt) {
+ errs() << "Too many statements in OpenScop file\n";
+ delete &NewScattering;
+ return NULL;
+ }
+
+ return &NewScattering;
+}
+
+/// @brief Update the scattering in a Scop using the scoplib description of
+/// the scattering.
+bool ScopLib::updateScattering() {
+ if (!scoplib)
+ return false;
+
+ StatementToIslMapTy *NewScattering = readScattering(PollyScop, scoplib);
+
+ if (!NewScattering)
+ return false;
+
+ if (!D->isValidScattering(NewScattering)) {
+ errs() << "OpenScop file contains a scattering that changes the "
+ << "dependences. Use -disable-polly-legality to continue anyways\n";
+ return false;
+ }
+
+ for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE;
+ ++SI) {
+ ScopStmt *Stmt = *SI;
+
+ if (NewScattering->find(Stmt) != NewScattering->end())
+ Stmt->setScattering((*NewScattering)[Stmt]);
+ }
+
+ return true;
+}
+}
+
+#endif
--- /dev/null
+//===-- ScopLibExporter.cpp - Export Scops with scoplib ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Export the Scops build by ScopInfo pass to text file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+
+#ifdef SCOPLIB_FOUND
+
+#include "polly/ScopInfo.h"
+#include "polly/ScopPass.h"
+#include "polly/ScopLib.h"
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Assembly/Writer.h"
+
+#include "stdio.h"
+#include "isl/set.h"
+#include "isl/constraint.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+ static cl::opt<std::string>
+ ExportDir("polly-export-scoplib-dir",
+ cl::desc("The directory to export the .scoplib files to."),
+ cl::Hidden, cl::value_desc("Directory path"), cl::ValueRequired,
+ cl::init("."));
+
+ class ScopLibExporter : public ScopPass {
+ Scop *S;
+
+ std::string getFileName(Scop *S) const;
+ public:
+ static char ID;
+ explicit ScopLibExporter() : ScopPass(ID) {}
+
+ virtual bool runOnScop(Scop &scop);
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ };
+
+}
+
+char ScopLibExporter::ID = 0;
+
+std::string ScopLibExporter::getFileName(Scop *S) const {
+ std::string FunctionName =
+ S->getRegion().getEntry()->getParent()->getNameStr();
+ std::string FileName = FunctionName + "___" + S->getNameStr() + ".scoplib";
+ return FileName;
+}
+
+bool ScopLibExporter::runOnScop(Scop &scop) {
+ S = &scop;
+ Region *R = &S->getRegion();
+
+ std::string FileName = ExportDir + "/" + getFileName(S);
+ FILE *F = fopen(FileName.c_str(), "w");
+
+ if (!F) {
+ errs() << "Cannot open file: " << FileName << "\n";
+ errs() << "Skipping export.\n";
+ return false;
+ }
+
+ ScopLib scoplib(S);
+ scoplib.print(F);
+ fclose(F);
+
+ std::string FunctionName = R->getEntry()->getParent()->getNameStr();
+ errs() << "Writing Scop '" << R->getNameStr() << "' in function '"
+ << FunctionName << "' to '" << FileName << "'.\n";
+
+ return false;
+}
+
+void ScopLibExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+}
+
+static RegisterPass<ScopLibExporter> A("polly-export-scoplib",
+ "Polly - Export Scops with ScopLib library"
+ " (Writes a .scoplib file for each Scop)"
+ );
+
+Pass *polly::createScopLibExporterPass() {
+ return new ScopLibExporter();
+}
+
+#endif
--- /dev/null
+//===-- ScopLibImporter.cpp - Import Scops with scoplib. -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Import modified .scop files into Polly. This allows to change the schedule of
+// statements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+
+#ifdef SCOPLIB_FOUND
+
+#include "polly/ScopInfo.h"
+#include "polly/ScopLib.h"
+#include "polly/Dependences.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Assembly/Writer.h"
+
+#define SCOPLIB_INT_T_IS_MP
+#include "scoplib/scop.h"
+
+#include "isl/set.h"
+#include "isl/constraint.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+ static cl::opt<std::string>
+ ImportDir("polly-import-scoplib-dir",
+ cl::desc("The directory to import the .scoplib files from."),
+ cl::Hidden, cl::value_desc("Directory path"), cl::ValueRequired,
+ cl::init("."));
+ static cl::opt<std::string>
+ ImportPostfix("polly-import-scoplib-postfix",
+ cl::desc("Postfix to append to the import .scoplib files."),
+ cl::Hidden, cl::value_desc("File postfix"), cl::ValueRequired,
+ cl::init(""));
+
+ struct ScopLibImporter : public RegionPass {
+ static char ID;
+ Scop *S;
+ Dependences *D;
+ explicit ScopLibImporter() : RegionPass(ID) {}
+
+ bool updateScattering(Scop *S, scoplib_scop_p OScop);
+ std::string getFileName(Scop *S) const;
+ virtual bool runOnRegion(Region *R, RGPassManager &RGM);
+ virtual void print(raw_ostream &OS, const Module *) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ };
+}
+
+char ScopLibImporter::ID = 0;
+
+namespace {
+std::string ScopLibImporter::getFileName(Scop *S) const {
+ std::string FunctionName =
+ S->getRegion().getEntry()->getParent()->getNameStr();
+ std::string FileName = FunctionName + "___" + S->getNameStr() + ".scoplib";
+ return FileName;
+}
+
+void ScopLibImporter::print(raw_ostream &OS, const Module *) const {}
+
+bool ScopLibImporter::runOnRegion(Region *R, RGPassManager &RGM) {
+ S = getAnalysis<ScopInfo>().getScop();
+ D = &getAnalysis<Dependences>();
+
+ if (!S)
+ return false;
+
+ std::string FileName = ImportDir + "/" + getFileName(S) + ImportPostfix;
+ FILE *F = fopen(FileName.c_str(), "r");
+
+ if (!F) {
+ errs() << "Cannot open file: " << FileName << "\n";
+ errs() << "Skipping import.\n";
+ return false;
+ }
+
+ std::string FunctionName = R->getEntry()->getParent()->getNameStr();
+ errs() << "Reading Scop '" << R->getNameStr() << "' in function '"
+ << FunctionName << "' from '" << FileName << "'.\n";
+
+ ScopLib scoplib(S, F, D);
+ bool UpdateSuccessfull = scoplib.updateScattering();
+ fclose(F);
+
+ if (!UpdateSuccessfull) {
+ errs() << "Update failed" << "\n";
+ }
+
+ return false;
+}
+
+void ScopLibImporter::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<ScopInfo>();
+ AU.addRequired<Dependences>();
+}
+
+}
+
+static RegisterPass<ScopLibImporter> A("polly-import-scoplib",
+ "Polly - Import Scops with ScopLib library"
+ " (Reads a .scoplib file for each Scop)"
+ );
+
+Pass *polly::createScopLibImporterPass() {
+ return new ScopLibImporter();
+}
+
+#endif
--- /dev/null
+//===------ IndependentBlocks.cpp - Create Independent Blocks in Regions --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Create independent blocks in the regions detected by ScopDetection.
+//
+//===----------------------------------------------------------------------===//
+//
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopDetection.h"
+#include "polly/Support/ScopHelper.h"
+#include "polly/Cloog.h"
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionPass.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Assembly/Writer.h"
+
+#define DEBUG_TYPE "polly-independent"
+#include "llvm/Support/Debug.h"
+
+#include <vector>
+
+using namespace polly;
+using namespace llvm;
+
+namespace {
+struct IndependentBlocks : public FunctionPass {
+ RegionInfo *RI;
+ ScalarEvolution *SE;
+ ScopDetection *SD;
+ LoopInfo *LI;
+
+ BasicBlock *AllocaBlock;
+
+ static char ID;
+
+ IndependentBlocks() : FunctionPass(ID) {}
+
+ // Create new code for every instruction operator that can be expressed by a
+ // SCEV. Like this there are just two types of instructions left:
+ //
+ // 1. Instructions that only reference loop ivs or parameters outside the
+ // region.
+ //
+ // 2. Instructions that are not used for any memory modification. (These
+ // will be ignored later on.)
+ //
+ // Blocks containing only these kind of instructions are called independent
+ // blocks as they can be scheduled arbitrarily.
+ bool createIndependentBlocks(BasicBlock *BB, const Region *R);
+ bool createIndependentBlocks(const Region *R);
+
+ // Elimination on the Scop to eliminate the scalar dependences come with
+ // trivially dead instructions.
+ bool eliminateDeadCode(const Region *R);
+
+ //===--------------------------------------------------------------------===//
+ /// Non trivial scalar dependences checking functions.
+ /// Non trivial scalar dependences occur when the def and use are located in
+ /// different BBs and we can not move them into the same one. This will
+ /// prevent use from schedule BBs arbitrarily.
+ ///
+ /// @brief This function checks if a scalar value that is part of the
+ /// Scop is used outside of the Scop.
+ ///
+ /// @param Use The use of the instruction.
+ /// @param R The maximum region in the Scop.
+ ///
+ /// @return Return true if the Use of an instruction and the instruction
+ /// itself form a non trivial scalar dependence.
+ static bool isEscapeUse(const Value *Use, const Region *R);
+
+ /// @brief This function just checks if a Value is either defined in the same
+ /// basic block or outside the region, such that there are no scalar
+ /// dependences between basic blocks that are both part of the same
+ /// region.
+ ///
+ /// @param Operand The operand of the instruction.
+ /// @param CurBB The BasicBlock that contains the instruction.
+ /// @param R The maximum region in the Scop.
+ ///
+ /// @return Return true if the Operand of an instruction and the instruction
+ /// itself form a non trivial scalar (true) dependence.
+ bool isEscapeOperand(const Value *Operand, const BasicBlock *CurBB,
+ const Region *R) const;
+
+ //===--------------------------------------------------------------------===//
+ /// Operand tree moving functions.
+ /// Trivial scalar dependences can eliminate by move the def to the same BB
+ /// that containing use.
+ ///
+ /// @brief Check if the instruction can be moved to another place safely.
+ ///
+ /// @param Inst The instruction.
+ ///
+ /// @return Return true if the instruction can be moved safely, false
+ /// otherwise.
+ static bool isSafeToMove(Instruction *Inst);
+
+ typedef std::map<Instruction*, Instruction*> ReplacedMapType;
+
+ /// @brief Move all safe to move instructions in the Operand Tree (DAG) to
+ /// eliminate trivial scalar dependences.
+ ///
+ /// @param Inst The root of the operand Tree.
+ /// @param R The maximum region in the Scop.
+ /// @param ReplacedMap The map that mapping original instruction to the moved
+ /// instruction.
+ /// @param InsertPos The insert position of the moved instructions.
+ void moveOperandTree(Instruction *Inst, const Region *R,
+ ReplacedMapType &ReplacedMap,
+ Instruction *InsertPos);
+
+ bool isIndependentBlock(const Region *R, BasicBlock *BB) const;
+ bool areAllBlocksIndependent(const Region *R) const;
+
+ // Split the exit block to hold load instructions.
+ bool splitExitBlock(Region *R);
+
+ bool translateScalarToArray(BasicBlock *BB, const Region *R);
+ bool translateScalarToArray(Instruction *Inst, const Region *R);
+ bool translateScalarToArray(const Region *R);
+
+ bool runOnFunction(Function &F);
+ void verifyAnalysis() const;
+ void verifyScop(const Region *R) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+}
+
+bool IndependentBlocks::isSafeToMove(Instruction *Inst) {
+ if (Inst->mayReadFromMemory() ||
+ Inst->mayWriteToMemory())
+ return false;
+
+ return Inst->isSafeToSpeculativelyExecute();
+}
+
+void IndependentBlocks::moveOperandTree(Instruction *Inst, const Region *R,
+ ReplacedMapType &ReplacedMap,
+ Instruction *InsertPos) {
+ BasicBlock *CurBB = Inst->getParent();
+
+ // Depth first traverse the operand tree (or operand dag, because we will
+ // stop at PHINodes, so there are no cycle).
+ typedef Instruction::op_iterator ChildIt;
+ std::vector<std::pair<Instruction*, ChildIt> > WorkStack;
+
+ WorkStack.push_back(std::make_pair(Inst, Inst->op_begin()));
+
+ while (!WorkStack.empty()) {
+ Instruction *CurInst = WorkStack.back().first;
+ ChildIt It = WorkStack.back().second;
+ DEBUG(dbgs() << "Checking Operand of Node:\n" << *CurInst << "\n------>\n");
+ if (It == CurInst->op_end()) {
+ // Insert the new instructions in topological order.
+ if (!CurInst->getParent())
+ CurInst->insertBefore(InsertPos);
+
+ WorkStack.pop_back();
+ } else {
+ // for each node N,
+ Instruction *Operand = dyn_cast<Instruction>(*It);
+ ++WorkStack.back().second;
+
+ // Can not move no instruction value.
+ if (Operand == 0) continue;
+
+ DEBUG(dbgs() << "For Operand:\n" << *Operand << "\n--->");
+
+ // If the Scop Region does not contain N, skip it and all its operand and
+ // continue. because we reach a "parameter".
+ // FIXME: we must keep the predicate instruction inside the Scop, otherwise
+ // it will be translated to a load instruction, and we can not handle load
+ // as affine predicate at this moment.
+ if (!R->contains(Operand) && !isa<TerminatorInst>(CurInst)) {
+ DEBUG(dbgs() << "Out of region.\n");
+ continue;
+ }
+
+ // No need to move induction variable.
+ if (isIndVar(Operand, LI)) {
+ DEBUG(dbgs() << "is IV.\n");
+ continue;
+ }
+
+ // We can not move the operand, a non trivial scalar dependence found!
+ if (!isSafeToMove(Operand)) {
+ DEBUG(dbgs() << "Can not move!\n");
+ continue;
+ }
+
+ // Do not need to move instruction if it contained in the same BB with
+ // the root instruction.
+ // FIXME: Remember this in visited Map.
+ if (Operand->getParent() == CurBB) {
+ DEBUG(dbgs() << "No need to move.\n");
+ // Try to move its operand.
+ WorkStack.push_back(std::make_pair(Operand, Operand->op_begin()));
+ continue;
+ }
+
+ // Now we need to move Operand to CurBB.
+ // Check if we already moved it.
+ ReplacedMapType::iterator At = ReplacedMap.find(Operand);
+ if (At != ReplacedMap.end()) {
+ DEBUG(dbgs() << "Moved.\n");
+ Instruction *MovedOp = At->second;
+ It->set(MovedOp);
+ // Skip all its children as we already processed them.
+ continue;
+ } else {
+ // Note that NewOp is not inserted in any BB now, we will insert it when
+ // it popped form the work stack, so it will be inserted in topological
+ // order.
+ Instruction *NewOp = Operand->clone();
+ NewOp->setName(Operand->getName() + ".moved.to." + CurBB->getName());
+ DEBUG(dbgs() << "Move to " << *NewOp << "\n");
+ It->set(NewOp);
+ ReplacedMap.insert(std::make_pair(Operand, NewOp));
+ // Process its operands.
+ WorkStack.push_back(std::make_pair(NewOp, NewOp->op_begin()));
+ }
+ }
+ }
+
+ SE->forgetValue(Inst);
+}
+
+bool IndependentBlocks::createIndependentBlocks(BasicBlock *BB,
+ const Region *R) {
+ std::vector<Instruction*> WorkList;
+ for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE; ++II)
+ if (!isSafeToMove(II) && !isIndVar(II, LI))
+ WorkList.push_back(II);
+
+ ReplacedMapType ReplacedMap;
+ Instruction *InsertPos = BB->getFirstNonPHIOrDbg();
+
+ for (std::vector<Instruction*>::iterator I = WorkList.begin(),
+ E = WorkList.end(); I != E; ++I)
+ moveOperandTree(*I, R, ReplacedMap, InsertPos);
+
+ // The BB was changed if we replaced any operand.
+ return !ReplacedMap.empty();
+}
+
+bool IndependentBlocks::createIndependentBlocks(const Region *R) {
+ bool Changed = false;
+
+ for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end();
+ SI != SE; ++SI)
+ Changed |= createIndependentBlocks((*SI)->getNodeAs<BasicBlock>(), R);
+
+ return Changed;
+}
+
+bool IndependentBlocks::eliminateDeadCode(const Region *R) {
+ std::vector<Instruction*> WorkList;
+
+ // Find all trivially dead instructions.
+ for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end();
+ SI != SE; ++SI) {
+ BasicBlock *BB = (*SI)->getNodeAs<BasicBlock>();
+ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+ if (isInstructionTriviallyDead(I))
+ WorkList.push_back(I);
+ }
+
+ if (WorkList.empty()) return false;
+
+ // Delete them so the cross BB scalar dependences come with them will
+ // also be eliminated.
+ while (!WorkList.empty()) {
+ RecursivelyDeleteTriviallyDeadInstructions(WorkList.back());
+ WorkList.pop_back();
+ }
+
+ return true;
+}
+
+bool IndependentBlocks::isEscapeUse(const Value *Use, const Region *R) {
+ // Non-instruction user will never escape.
+ if (!isa<Instruction>(Use)) return false;
+
+ return !R->contains(cast<Instruction>(Use));
+}
+
+bool IndependentBlocks::isEscapeOperand(const Value *Operand,
+ const BasicBlock *CurBB,
+ const Region *R) const {
+ const Instruction *OpInst = dyn_cast<Instruction>(Operand);
+
+ // Non-instruction operand will never escape.
+ if (OpInst == 0) return false;
+
+ // Induction variables are valid operands.
+ if (isIndVar(OpInst, LI)) return false;
+
+ // A value from a different BB is used in the same region.
+ return R->contains(OpInst) && (OpInst->getParent() != CurBB);
+}
+
+bool IndependentBlocks::splitExitBlock(Region *R) {
+ // Split the exit BB to place the load instruction of escaped users.
+ BasicBlock *ExitBB = R->getExit();
+ Region *ExitRegion = RI->getRegionFor(ExitBB);
+
+ if (ExitBB != ExitRegion->getEntry())
+ return false;
+
+ BasicBlock *NewExit = createSingleExitEdge(R, this);
+
+ std::vector<Region*> toUpdate;
+ toUpdate.push_back(R);
+
+ while (!toUpdate.empty()) {
+ Region *Reg = toUpdate.back();
+ toUpdate.pop_back();
+
+ for (Region::iterator I = Reg->begin(), E = Reg->end(); I != E; ++I) {
+ Region *SubR = *I;
+
+ if (SubR->getExit() == ExitBB)
+ toUpdate.push_back(SubR);
+ }
+
+ Reg->replaceExit(NewExit);
+ }
+
+ RI->setRegionFor(NewExit, R->getParent());
+ return true;
+}
+
+bool IndependentBlocks::translateScalarToArray(const Region *R) {
+ bool Changed = false;
+
+ for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end();
+ SI != SE; ++SI)
+ Changed |= translateScalarToArray((*SI)->getNodeAs<BasicBlock>(), R);
+
+ return Changed;
+}
+
+bool IndependentBlocks::translateScalarToArray(Instruction *Inst,
+ const Region *R) {
+ if (isIndVar(Inst, LI))
+ return false;
+
+ SmallVector<Instruction*, 4> LoadInside, LoadOutside;
+ for (Instruction::use_iterator UI = Inst->use_begin(),
+ UE = Inst->use_end(); UI != UE; ++UI)
+ // Inst is referenced outside or referenced as an escaped operand.
+ if (Instruction *U = dyn_cast<Instruction>(*UI)) {
+ BasicBlock *UParent = U->getParent();
+
+ if (isEscapeUse(U, R))
+ LoadOutside.push_back(U);
+
+ if (isIndVar(U, LI))
+ continue;
+
+ if (R->contains(UParent) && isEscapeOperand(Inst, UParent, R))
+ LoadInside.push_back(U);
+ }
+
+ if (LoadOutside.empty() && LoadInside.empty())
+ return false;
+
+ // Create the alloca.
+ AllocaInst *Slot = new AllocaInst(Inst->getType(), 0,
+ Inst->getName() + ".s2a",
+ AllocaBlock->begin());
+ assert(!isa<InvokeInst>(Inst) && "Unexpect Invoke in Scop!");
+ // Store right after Inst.
+ BasicBlock::iterator StorePos = Inst;
+ (void) new StoreInst(Inst, Slot, ++StorePos);
+
+ if (!LoadOutside.empty()) {
+ LoadInst *ExitLoad = new LoadInst(Slot, Inst->getName()+".loadoutside",
+ false, R->getExit()->getFirstNonPHI());
+
+ while (!LoadOutside.empty()) {
+ Instruction *U = LoadOutside.pop_back_val();
+ assert(!isa<PHINode>(U) && "Can not handle PHI node outside!");
+ SE->forgetValue(U);
+ U->replaceUsesOfWith(Inst, ExitLoad);
+ }
+ }
+
+ while (!LoadInside.empty()) {
+ Instruction *U = LoadInside.pop_back_val();
+ assert(!isa<PHINode>(U) && "Can not handle PHI node outside!");
+ SE->forgetValue(U);
+ LoadInst *L = new LoadInst(Slot, Inst->getName()+".loadarray",
+ false, U);
+ U->replaceUsesOfWith(Inst, L);
+ }
+
+ return true;
+}
+
+bool IndependentBlocks::translateScalarToArray(BasicBlock *BB,
+ const Region *R) {
+ bool changed = false;
+
+ SmallVector<Instruction*, 32> Insts;
+ for (BasicBlock::iterator II = BB->begin(), IE = --BB->end();
+ II != IE; ++II)
+ Insts.push_back(II);
+
+ while (!Insts.empty()) {
+ Instruction *Inst = Insts.pop_back_val();
+ changed |= translateScalarToArray(Inst, R);
+ }
+
+ return changed;
+}
+
+bool IndependentBlocks::isIndependentBlock(const Region *R,
+ BasicBlock *BB) const {
+ for (BasicBlock::iterator II = BB->begin(), IE = --BB->end();
+ II != IE; ++II) {
+ Instruction *Inst = &*II;
+
+ if (isIndVar(Inst, LI))
+ continue;
+
+ // A value inside the Scop is referenced outside.
+ for (Instruction::use_iterator UI = Inst->use_begin(),
+ UE = Inst->use_end(); UI != UE; ++UI) {
+ if (isEscapeUse(*UI, R)) {
+ DEBUG(dbgs() << "Instruction not independent:\n");
+ DEBUG(dbgs() << "Instruction used outside the Scop!\n");
+ DEBUG(Inst->print(dbgs()));
+ DEBUG(dbgs() << "\n");
+ return false;
+ }
+ }
+
+ for (Instruction::op_iterator OI = Inst->op_begin(),
+ OE = Inst->op_end(); OI != OE; ++OI) {
+ if (isEscapeOperand(*OI, BB, R)) {
+ DEBUG(dbgs() << "Instruction in function '";
+ WriteAsOperand(dbgs(), BB->getParent(), false);
+ dbgs() << "' not independent:\n");
+ DEBUG(dbgs() << "Uses invalid operator\n");
+ DEBUG(Inst->print(dbgs()));
+ DEBUG(dbgs() << "\n");
+ DEBUG(dbgs() << "Invalid operator is: ";
+ WriteAsOperand(dbgs(), *OI, false);
+ dbgs() << "\n");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool IndependentBlocks::areAllBlocksIndependent(const Region *R) const {
+ for (Region::const_block_iterator SI = R->block_begin(), SE = R->block_end();
+ SI != SE; ++SI)
+ if (!isIndependentBlock(R, (*SI)->getNodeAs<BasicBlock>()))
+ return false;
+
+ return true;
+}
+
+void IndependentBlocks::getAnalysisUsage(AnalysisUsage &AU) const {
+ // FIXME: If we set preserves cfg, the cfg only passes do not need to
+ // be "addPreserved"?
+ AU.addPreserved<DominatorTree>();
+ AU.addPreserved<DominanceFrontier>();
+ AU.addPreserved<PostDominatorTree>();
+ AU.addRequired<RegionInfo>();
+ AU.addPreserved<RegionInfo>();
+ AU.addRequired<LoopInfo>();
+ AU.addPreserved<LoopInfo>();
+ AU.addRequired<ScalarEvolution>();
+ AU.addPreserved<ScalarEvolution>();
+ AU.addRequired<ScopDetection>();
+ AU.addPreserved<ScopDetection>();
+ AU.addPreserved<CloogInfo>();
+}
+
+bool IndependentBlocks::runOnFunction(llvm::Function &F) {
+ bool Changed = false;
+
+ RI = &getAnalysis<RegionInfo>();
+ LI = &getAnalysis<LoopInfo>();
+ SD = &getAnalysis<ScopDetection>();
+ SE = &getAnalysis<ScalarEvolution>();
+
+ AllocaBlock = &F.getEntryBlock();
+
+ DEBUG(dbgs() << "Run IndepBlock on " << F.getName() << '\n');
+
+ for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) {
+ const Region *R = *I;
+ Changed |= createIndependentBlocks(R);
+ Changed |= eliminateDeadCode(R);
+ // This may change the RegionTree.
+ Changed |= splitExitBlock(const_cast<Region*>(R));
+ }
+
+ DEBUG(dbgs() << "Before Scalar to Array------->\n");
+ DEBUG(F.dump());
+
+ for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I)
+ Changed |= translateScalarToArray(*I);
+
+ DEBUG(dbgs() << "After Independent Blocks------------->\n");
+ DEBUG(F.dump());
+
+ verifyAnalysis();
+
+ return Changed;
+}
+
+void IndependentBlocks::verifyAnalysis() const {
+ for (ScopDetection::const_iterator I = SD->begin(), E = SD->end();I != E;++I)
+ verifyScop(*I);
+}
+
+void IndependentBlocks::verifyScop(const Region *R) const {
+ assert (areAllBlocksIndependent(R) && "Cannot generate independent blocks");
+}
+
+char IndependentBlocks::ID = 0;
+
+static RegisterPass<IndependentBlocks>
+Z("polly-independent", "Polly - Create independent blocks");
+
+char &polly::IndependentBlocksID = IndependentBlocks::ID;
+
+Pass* polly::createIndependentBlocksPass() {
+ return new IndependentBlocks();
+}
--- /dev/null
+//===- Interchange.cpp - Interchange interface ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Cloog.h"
+#include "polly/LinkAllPasses.h"
+
+#include "polly/ScopInfo.h"
+#include "polly/Dependences.h"
+
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/CommandLine.h"
+
+#include <isl/map.h>
+
+#define DEBUG_TYPE "polly-interchange"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+
+ class Interchange : public ScopPass {
+ public:
+ static char ID;
+ explicit Interchange() : ScopPass(ID) {}
+
+ virtual bool runOnScop(Scop &S);
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ };
+
+}
+
+char Interchange::ID = 0;
+bool Interchange::runOnScop(Scop &S) {
+ if (std::distance(S.begin(), S.end()) != 2) // One statement besides the final statement
+ return false;
+
+ for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
+ ScopStmt *Stmt = *SI;
+ if (!Stmt->isReduction())
+ continue;
+
+ isl_map *Scattering = isl_map_copy(Stmt->getScattering());
+
+ const std::string MapString = "{scattering[i0, i1, i2, i3, i4] -> scattering[i0, i3, i2, i1, i4]}";
+ isl_map *Map = isl_map_read_from_str(Stmt->getIslContext(), MapString.c_str(), -1);
+
+ isl_map_add_dims(Map, isl_dim_param, Stmt->getNumParams());
+ Scattering = isl_map_apply_range(Scattering, Map);
+ Stmt->setScattering(Scattering);
+
+ DEBUG(
+ isl_printer *p = isl_printer_to_str(S.getCtx());
+ isl_printer_print_map(p, Scattering);
+ dbgs() << isl_printer_get_str(p) << '\n';
+ isl_printer_flush(p);
+ isl_printer_free(p);
+ );
+ }
+
+ return false;
+}
+
+void Interchange::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+ AU.addRequired<Dependences>();
+}
+
+static RegisterPass<Interchange> A("polly-interchange",
+ "Polly - Perform loop interchange");
+
+Pass* polly::createInterchangePass() {
+ return new Interchange();
+}
--- /dev/null
+add_polly_library(PollyJSON
+ json_reader.cpp
+ json_value.cpp
+ json_writer.cpp
+)
+
--- /dev/null
+The json-cpp library and this documentation are in Public Domain.
--- /dev/null
+##===- polly/lib/Support/Makefile ----------------*- Makefile -*-===##
+
+#
+# Indicate where we are relative to the top of the source tree.
+#
+LEVEL=../..
+
+LIBRARYNAME=pollyjson
+BUILD_ARCHIVE = 1
+
+CPP.Flags += $(POLLY_INC)
+
+#
+# Include Makefile.common so we know what to do.
+#
+include $(LEVEL)/Makefile.common
--- /dev/null
+#ifndef JSON_AUTOLINK_H_INCLUDED
+# define JSON_AUTOLINK_H_INCLUDED
+
+# include "config.h"
+
+# ifdef JSON_IN_CPPTL
+# include <cpptl/cpptl_autolink.h>
+# endif
+
+# if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && !defined(JSON_IN_CPPTL)
+# define CPPTL_AUTOLINK_NAME "json"
+# undef CPPTL_AUTOLINK_DLL
+# ifdef JSON_DLL
+# define CPPTL_AUTOLINK_DLL
+# endif
+# include "autolink.h"
+# endif
+
+#endif // JSON_AUTOLINK_H_INCLUDED
--- /dev/null
+#ifndef JSON_CONFIG_H_INCLUDED
+# define JSON_CONFIG_H_INCLUDED
+
+/// If defined, indicates that json library is embedded in CppTL library.
+//# define JSON_IN_CPPTL 1
+
+/// If defined, indicates that json may leverage CppTL library
+//# define JSON_USE_CPPTL 1
+/// If defined, indicates that cpptl vector based map should be used instead of std::map
+/// as Value container.
+//# define JSON_USE_CPPTL_SMALLMAP 1
+/// If defined, indicates that Json specific container should be used
+/// (hash table & simple deque container with customizable allocator).
+/// THIS FEATURE IS STILL EXPERIMENTAL!
+//# define JSON_VALUE_USE_INTERNAL_MAP 1
+/// Force usage of standard new/malloc based allocator instead of memory pool based allocator.
+/// The memory pools allocator used optimization (initializing Value and ValueInternalLink
+/// as if it was a POD) that may cause some validation tool to report errors.
+/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined.
+//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1
+
+/// If defined, indicates that Json use exception to report invalid type manipulation
+/// instead of C assert macro.
+# define JSON_USE_EXCEPTION 1
+
+# ifdef JSON_IN_CPPTL
+# include <cpptl/config.h>
+# ifndef JSON_USE_CPPTL
+# define JSON_USE_CPPTL 1
+# endif
+# endif
+
+# ifdef JSON_IN_CPPTL
+# define JSON_API CPPTL_API
+# elif defined(JSON_DLL_BUILD)
+# define JSON_API __declspec(dllexport)
+# elif defined(JSON_DLL)
+# define JSON_API __declspec(dllimport)
+# else
+# define JSON_API
+# endif
+
+#endif // JSON_CONFIG_H_INCLUDED
--- /dev/null
+#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
+# define CPPTL_JSON_FEATURES_H_INCLUDED
+
+# include "forwards.h"
+
+namespace Json {
+
+ /** \brief Configuration passed to reader and writer.
+ * This configuration object can be used to force the Reader or Writer
+ * to behave in a standard conforming way.
+ */
+ class JSON_API Features
+ {
+ public:
+ /** \brief A configuration that allows all features and assumes all strings are UTF-8.
+ * - C & C++ comments are allowed
+ * - Root object can be any JSON value
+ * - Assumes Value strings are encoded in UTF-8
+ */
+ static Features all();
+
+ /** \brief A configuration that is strictly compatible with the JSON specification.
+ * - Comments are forbidden.
+ * - Root object must be either an array or an object value.
+ * - Assumes Value strings are encoded in UTF-8
+ */
+ static Features strictMode();
+
+ /** \brief Initialize the configuration like JsonConfig::allFeatures;
+ */
+ Features();
+
+ /// \c true if comments are allowed. Default: \c true.
+ bool allowComments_;
+
+ /// \c true if root must be either an array or an object value. Default: \c false.
+ bool strictRoot_;
+ };
+
+} // namespace Json
+
+#endif // CPPTL_JSON_FEATURES_H_INCLUDED
--- /dev/null
+#ifndef JSON_FORWARDS_H_INCLUDED
+# define JSON_FORWARDS_H_INCLUDED
+
+# include "config.h"
+
+namespace Json {
+
+ // writer.h
+ class FastWriter;
+ class StyledWriter;
+
+ // reader.h
+ class Reader;
+
+ // features.h
+ class Features;
+
+ // value.h
+ typedef int Int;
+ typedef unsigned int UInt;
+ class StaticString;
+ class Path;
+ class PathArgument;
+ class Value;
+ class ValueIteratorBase;
+ class ValueIterator;
+ class ValueConstIterator;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ class ValueAllocator;
+ class ValueMapAllocator;
+ class ValueInternalLink;
+ class ValueInternalArray;
+ class ValueInternalMap;
+#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+} // namespace Json
+
+
+#endif // JSON_FORWARDS_H_INCLUDED
--- /dev/null
+#ifndef JSON_JSON_H_INCLUDED
+# define JSON_JSON_H_INCLUDED
+
+# include "autolink.h"
+# include "value.h"
+# include "reader.h"
+# include "writer.h"
+# include "features.h"
+
+#endif // JSON_JSON_H_INCLUDED
--- /dev/null
+#ifndef CPPTL_JSON_READER_H_INCLUDED
+# define CPPTL_JSON_READER_H_INCLUDED
+
+# include "features.h"
+# include "value.h"
+# include <deque>
+# include <stack>
+# include <string>
+# include <iostream>
+
+namespace Json {
+
+ /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value.
+ *
+ */
+ class JSON_API Reader
+ {
+ public:
+ typedef char Char;
+ typedef const Char *Location;
+
+ /** \brief Constructs a Reader allowing all features
+ * for parsing.
+ */
+ Reader();
+
+ /** \brief Constructs a Reader allowing the specified feature set
+ * for parsing.
+ */
+ Reader( const Features &features );
+
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
+ * \param document UTF-8 encoded string containing the document to read.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param collectComments \c true to collect comment and allow writing them back during
+ * serialization, \c false to discard comments.
+ * This parameter is ignored if Features::allowComments_
+ * is \c false.
+ * \return \c true if the document was successfully parsed, \c false if an error occurred.
+ */
+ bool parse( const std::string &document,
+ Value &root,
+ bool collectComments = true );
+
+ /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document.
+ * \param document UTF-8 encoded string containing the document to read.
+ * \param root [out] Contains the root value of the document if it was
+ * successfully parsed.
+ * \param collectComments \c true to collect comment and allow writing them back during
+ * serialization, \c false to discard comments.
+ * This parameter is ignored if Features::allowComments_
+ * is \c false.
+ * \return \c true if the document was successfully parsed, \c false if an error occurred.
+ */
+ bool parse( const char *beginDoc, const char *endDoc,
+ Value &root,
+ bool collectComments = true );
+
+ /// \brief Parse from input stream.
+ /// \see Json::operator>>(std::istream&, Json::Value&).
+ bool parse( std::istream &is,
+ Value &root,
+ bool collectComments = true );
+
+ /** \brief Returns a user friendly string that list errors in the parsed document.
+ * \return Formatted error message with the list of errors with their location in
+ * the parsed document. An empty string is returned if no error occurred
+ * during parsing.
+ */
+ std::string getFormatedErrorMessages() const;
+
+ private:
+ enum TokenType
+ {
+ tokenEndOfStream = 0,
+ tokenObjectBegin,
+ tokenObjectEnd,
+ tokenArrayBegin,
+ tokenArrayEnd,
+ tokenString,
+ tokenNumber,
+ tokenTrue,
+ tokenFalse,
+ tokenNull,
+ tokenArraySeparator,
+ tokenMemberSeparator,
+ tokenComment,
+ tokenError
+ };
+
+ class Token
+ {
+ public:
+ TokenType type_;
+ Location start_;
+ Location end_;
+ };
+
+ class ErrorInfo
+ {
+ public:
+ Token token_;
+ std::string message_;
+ Location extra_;
+ };
+
+ typedef std::deque<ErrorInfo> Errors;
+
+ bool expectToken( TokenType type, Token &token, const char *message );
+ bool readToken( Token &token );
+ void skipSpaces();
+ bool match( Location pattern,
+ int patternLength );
+ bool readComment();
+ bool readCStyleComment();
+ bool readCppStyleComment();
+ bool readString();
+ void readNumber();
+ bool readValue();
+ bool readObject( Token &token );
+ bool readArray( Token &token );
+ bool decodeNumber( Token &token );
+ bool decodeString( Token &token );
+ bool decodeString( Token &token, std::string &decoded );
+ bool decodeDouble( Token &token );
+ bool decodeUnicodeCodePoint( Token &token,
+ Location ¤t,
+ Location end,
+ unsigned int &unicode );
+ bool decodeUnicodeEscapeSequence( Token &token,
+ Location ¤t,
+ Location end,
+ unsigned int &unicode );
+ bool addError( const std::string &message,
+ Token &token,
+ Location extra = 0 );
+ bool recoverFromError( TokenType skipUntilToken );
+ bool addErrorAndRecover( const std::string &message,
+ Token &token,
+ TokenType skipUntilToken );
+ void skipUntilSpace();
+ Value ¤tValue();
+ Char getNextChar();
+ void getLocationLineAndColumn( Location location,
+ int &line,
+ int &column ) const;
+ std::string getLocationLineAndColumn( Location location ) const;
+ void addComment( Location begin,
+ Location end,
+ CommentPlacement placement );
+ void skipCommentTokens( Token &token );
+
+ typedef std::stack<Value *> Nodes;
+ Nodes nodes_;
+ Errors errors_;
+ std::string document_;
+ Location begin_;
+ Location end_;
+ Location current_;
+ Location lastValueEnd_;
+ Value *lastValue_;
+ std::string commentsBefore_;
+ Features features_;
+ bool collectComments_;
+ };
+
+ /** \brief Read from 'sin' into 'root'.
+
+ Always keep comments from the input JSON.
+
+ This can be used to read a file into a particular sub-object.
+ For example:
+ \code
+ Json::Value root;
+ cin >> root["dir"]["file"];
+ cout << root;
+ \endcode
+ Result:
+ \verbatim
+ {
+ "dir": {
+ "file": {
+ // The input stream JSON would be nested here.
+ }
+ }
+ }
+ \endverbatim
+ \throw std::exception on parse error.
+ \see Json::operator<<()
+ */
+ std::istream& operator>>( std::istream&, Value& );
+
+} // namespace Json
+
+#endif // CPPTL_JSON_READER_H_INCLUDED
--- /dev/null
+#ifndef CPPTL_JSON_H_INCLUDED
+# define CPPTL_JSON_H_INCLUDED
+
+# include "forwards.h"
+# include <string>
+# include <vector>
+
+# ifndef JSON_USE_CPPTL_SMALLMAP
+# include <map>
+# else
+# include <cpptl/smallmap.h>
+# endif
+# ifdef JSON_USE_CPPTL
+# include <cpptl/forwards.h>
+# endif
+
+/** \brief JSON (JavaScript Object Notation).
+ */
+namespace Json {
+
+ /** \brief Type of the value held by a Value object.
+ */
+ enum ValueType
+ {
+ nullValue = 0, ///< 'null' value
+ intValue, ///< signed integer value
+ uintValue, ///< unsigned integer value
+ realValue, ///< double value
+ stringValue, ///< UTF-8 string value
+ booleanValue, ///< bool value
+ arrayValue, ///< array value (ordered list)
+ objectValue ///< object value (collection of name/value pairs).
+ };
+
+ enum CommentPlacement
+ {
+ commentBefore = 0, ///< a comment placed on the line before a value
+ commentAfterOnSameLine, ///< a comment just after a value on the same line
+ commentAfter, ///< a comment on the line after a value (only make sense for root value)
+ numberOfCommentPlacement
+ };
+
+//# ifdef JSON_USE_CPPTL
+// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
+// typedef CppTL::AnyEnumerator<const Value &> EnumValues;
+//# endif
+
+ /** \brief Lightweight wrapper to tag static string.
+ *
+ * Value constructor and objectValue member assignement takes advantage of the
+ * StaticString and avoid the cost of string duplication when storing the
+ * string or the member name.
+ *
+ * Example of usage:
+ * \code
+ * Json::Value aValue( StaticString("some text") );
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+ class JSON_API StaticString
+ {
+ public:
+ explicit StaticString( const char *czstring )
+ : str_( czstring )
+ {
+ }
+
+ operator const char *() const
+ {
+ return str_;
+ }
+
+ const char *c_str() const
+ {
+ return str_;
+ }
+
+ private:
+ const char *str_;
+ };
+
+ /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
+ *
+ * This class is a discriminated union wrapper that can represents a:
+ * - signed integer [range: Value::minInt - Value::maxInt]
+ * - unsigned integer (range: 0 - Value::maxUInt)
+ * - double
+ * - UTF-8 string
+ * - boolean
+ * - 'null'
+ * - an ordered list of Value
+ * - collection of name/value pairs (javascript object)
+ *
+ * The type of the held value is represented by a #ValueType and
+ * can be obtained using type().
+ *
+ * values of an #objectValue or #arrayValue can be accessed using operator[]() methods.
+ * Non const methods will automatically create the a #nullValue element
+ * if it does not exist.
+ * The sequence of an #arrayValue will be automatically resize and initialized
+ * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
+ *
+ * The get() methods can be used to obtanis default value in the case the required element
+ * does not exist.
+ *
+ * It is possible to iterate over the list of a #objectValue values using
+ * the getMemberNames() method.
+ */
+ class JSON_API Value
+ {
+ friend class ValueIteratorBase;
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ friend class ValueInternalLink;
+ friend class ValueInternalMap;
+# endif
+ public:
+ typedef std::vector<std::string> Members;
+ typedef ValueIterator iterator;
+ typedef ValueConstIterator const_iterator;
+ typedef Json::UInt UInt;
+ typedef Json::Int Int;
+ typedef UInt ArrayIndex;
+
+ static const Value null;
+ static const Int minInt;
+ static const Int maxInt;
+ static const UInt maxUInt;
+
+ private:
+#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+# ifndef JSON_VALUE_USE_INTERNAL_MAP
+ class CZString
+ {
+ public:
+ enum DuplicationPolicy
+ {
+ noDuplication = 0,
+ duplicate,
+ duplicateOnCopy
+ };
+ CZString( int index );
+ CZString( const char *cstr, DuplicationPolicy allocate );
+ CZString( const CZString &other );
+ ~CZString();
+ CZString &operator =( const CZString &other );
+ bool operator<( const CZString &other ) const;
+ bool operator==( const CZString &other ) const;
+ int index() const;
+ const char *c_str() const;
+ bool isStaticString() const;
+ private:
+ void swap( CZString &other );
+ const char *cstr_;
+ int index_;
+ };
+
+ public:
+# ifndef JSON_USE_CPPTL_SMALLMAP
+ typedef std::map<CZString, Value> ObjectValues;
+# else
+ typedef CppTL::SmallMap<CZString, Value> ObjectValues;
+# endif // ifndef JSON_USE_CPPTL_SMALLMAP
+# endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
+#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+ public:
+ /** \brief Create a default Value of the given type.
+
+ This is a very useful constructor.
+ To create an empty array, pass arrayValue.
+ To create an empty object, pass objectValue.
+ Another Value can then be set to this one by assignment.
+ This is useful since clear() and resize() will not alter types.
+
+ Examples:
+ \code
+ Json::Value null_value; // null
+ Json::Value arr_value(Json::arrayValue); // []
+ Json::Value obj_value(Json::objectValue); // {}
+ \endcode
+ */
+ Value( ValueType type = nullValue );
+ Value( Int value );
+ Value( UInt value );
+ Value( double value );
+ Value( const char *value );
+ Value( const char *beginValue, const char *endValue );
+ /** \brief Constructs a value from a static string.
+
+ * Like other value string constructor but do not duplicate the string for
+ * internal storage. The given string must remain alive after the call to this
+ * constructor.
+ * Example of usage:
+ * \code
+ * Json::Value aValue( StaticString("some text") );
+ * \endcode
+ */
+ Value( const StaticString &value );
+ Value( const std::string &value );
+# ifdef JSON_USE_CPPTL
+ Value( const CppTL::ConstString &value );
+# endif
+ Value( bool value );
+ Value( const Value &other );
+ ~Value();
+
+ Value &operator=( const Value &other );
+ /// Swap values.
+ /// \note Currently, comments are intentionally not swapped, for
+ /// both logic and efficiency.
+ void swap( Value &other );
+
+ ValueType type() const;
+
+ bool operator <( const Value &other ) const;
+ bool operator <=( const Value &other ) const;
+ bool operator >=( const Value &other ) const;
+ bool operator >( const Value &other ) const;
+
+ bool operator ==( const Value &other ) const;
+ bool operator !=( const Value &other ) const;
+
+ int compare( const Value &other );
+
+ const char *asCString() const;
+ std::string asString() const;
+# ifdef JSON_USE_CPPTL
+ CppTL::ConstString asConstString() const;
+# endif
+ Int asInt() const;
+ UInt asUInt() const;
+ double asDouble() const;
+ bool asBool() const;
+
+ bool isNull() const;
+ bool isBool() const;
+ bool isInt() const;
+ bool isUInt() const;
+ bool isIntegral() const;
+ bool isDouble() const;
+ bool isNumeric() const;
+ bool isString() const;
+ bool isArray() const;
+ bool isObject() const;
+
+ bool isConvertibleTo( ValueType other ) const;
+
+ /// Number of values in array or object
+ UInt size() const;
+
+ /// \brief Return true if empty array, empty object, or null;
+ /// otherwise, false.
+ bool empty() const;
+
+ /// Return isNull()
+ bool operator!() const;
+
+ /// Remove all object members and array elements.
+ /// \pre type() is arrayValue, objectValue, or nullValue
+ /// \post type() is unchanged
+ void clear();
+
+ /// Resize the array to size elements.
+ /// New elements are initialized to null.
+ /// May only be called on nullValue or arrayValue.
+ /// \pre type() is arrayValue or nullValue
+ /// \post type() is arrayValue
+ void resize( UInt size );
+
+ /// Access an array element (zero based index ).
+ /// If the array contains less than index element, then null value are inserted
+ /// in the array so that its size is index+1.
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ Value &operator[]( UInt index );
+ /// Access an array element (zero based index )
+ /// (You may need to say 'value[0u]' to get your compiler to distinguish
+ /// this from the operator[] which takes a string.)
+ const Value &operator[]( UInt index ) const;
+ /// If the array contains at least index+1 elements, returns the element value,
+ /// otherwise returns defaultValue.
+ Value get( UInt index,
+ const Value &defaultValue ) const;
+ /// Return true if index < size().
+ bool isValidIndex( UInt index ) const;
+ /// \brief Append value to array at the end.
+ ///
+ /// Equivalent to jsonvalue[jsonvalue.size()] = value;
+ Value &append( const Value &value );
+
+ /// Access an object value by name, create a null member if it does not exist.
+ Value &operator[]( const char *key );
+ /// Access an object value by name, returns null if there is no member with that name.
+ const Value &operator[]( const char *key ) const;
+ /// Access an object value by name, create a null member if it does not exist.
+ Value &operator[]( const std::string &key );
+ /// Access an object value by name, returns null if there is no member with that name.
+ const Value &operator[]( const std::string &key ) const;
+ /** \brief Access an object value by name, create a null member if it does not exist.
+
+ * If the object as no entry for that name, then the member name used to store
+ * the new entry is not duplicated.
+ * Example of use:
+ * \code
+ * Json::Value object;
+ * static const StaticString code("code");
+ * object[code] = 1234;
+ * \endcode
+ */
+ Value &operator[]( const StaticString &key );
+# ifdef JSON_USE_CPPTL
+ /// Access an object value by name, create a null member if it does not exist.
+ Value &operator[]( const CppTL::ConstString &key );
+ /// Access an object value by name, returns null if there is no member with that name.
+ const Value &operator[]( const CppTL::ConstString &key ) const;
+# endif
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get( const char *key,
+ const Value &defaultValue ) const;
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get( const std::string &key,
+ const Value &defaultValue ) const;
+# ifdef JSON_USE_CPPTL
+ /// Return the member named key if it exist, defaultValue otherwise.
+ Value get( const CppTL::ConstString &key,
+ const Value &defaultValue ) const;
+# endif
+ /// \brief Remove and return the named member.
+ ///
+ /// Do nothing if it did not exist.
+ /// \return the removed Value, or null.
+ /// \pre type() is objectValue or nullValue
+ /// \post type() is unchanged
+ Value removeMember( const char* key );
+ /// Same as removeMember(const char*)
+ Value removeMember( const std::string &key );
+
+ /// Return true if the object has a member named key.
+ bool isMember( const char *key ) const;
+ /// Return true if the object has a member named key.
+ bool isMember( const std::string &key ) const;
+# ifdef JSON_USE_CPPTL
+ /// Return true if the object has a member named key.
+ bool isMember( const CppTL::ConstString &key ) const;
+# endif
+
+ /// \brief Return a list of the member names.
+ ///
+ /// If null, return an empty list.
+ /// \pre type() is objectValue or nullValue
+ /// \post if type() was nullValue, it remains nullValue
+ Members getMemberNames() const;
+
+//# ifdef JSON_USE_CPPTL
+// EnumMemberNames enumMemberNames() const;
+// EnumValues enumValues() const;
+//# endif
+
+ /// Comments must be //... or /* ... */
+ void setComment( const char *comment,
+ CommentPlacement placement );
+ /// Comments must be //... or /* ... */
+ void setComment( const std::string &comment,
+ CommentPlacement placement );
+ bool hasComment( CommentPlacement placement ) const;
+ /// Include delimiters and embedded newlines.
+ std::string getComment( CommentPlacement placement ) const;
+
+ std::string toStyledString() const;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ iterator begin();
+ iterator end();
+
+ private:
+ Value &resolveReference( const char *key,
+ bool isStatic );
+
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ inline bool isItemAvailable() const
+ {
+ return itemIsUsed_ == 0;
+ }
+
+ inline void setItemUsed( bool isUsed = true )
+ {
+ itemIsUsed_ = isUsed ? 1 : 0;
+ }
+
+ inline bool isMemberNameStatic() const
+ {
+ return memberNameIsStatic_ == 0;
+ }
+
+ inline void setMemberNameIsStatic( bool isStatic )
+ {
+ memberNameIsStatic_ = isStatic ? 1 : 0;
+ }
+# endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+ private:
+ struct CommentInfo
+ {
+ CommentInfo();
+ ~CommentInfo();
+
+ void setComment( const char *text );
+
+ char *comment_;
+ };
+
+ //struct MemberNamesTransform
+ //{
+ // typedef const char *result_type;
+ // const char *operator()( const CZString &name ) const
+ // {
+ // return name.c_str();
+ // }
+ //};
+
+ union ValueHolder
+ {
+ Int int_;
+ UInt uint_;
+ double real_;
+ bool bool_;
+ char *string_;
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ ValueInternalArray *array_;
+ ValueInternalMap *map_;
+#else
+ ObjectValues *map_;
+# endif
+ } value_;
+ ValueType type_ : 8;
+ int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container.
+ int memberNameIsStatic_ : 1; // used by the ValueInternalMap container.
+# endif
+ CommentInfo *comments_;
+ };
+
+
+ /** \brief Experimental and untested: represents an element of the "path" to access a node.
+ */
+ class PathArgument
+ {
+ public:
+ friend class Path;
+
+ PathArgument();
+ PathArgument( UInt index );
+ PathArgument( const char *key );
+ PathArgument( const std::string &key );
+
+ private:
+ enum Kind
+ {
+ kindNone = 0,
+ kindIndex,
+ kindKey
+ };
+ std::string key_;
+ UInt index_;
+ Kind kind_;
+ };
+
+ /** \brief Experimental and untested: represents a "path" to access a node.
+ *
+ * Syntax:
+ * - "." => root node
+ * - ".[n]" => elements at index 'n' of root node (an array value)
+ * - ".name" => member named 'name' of root node (an object value)
+ * - ".name1.name2.name3"
+ * - ".[0][1][2].name1[3]"
+ * - ".%" => member name is provided as parameter
+ * - ".[%]" => index is provied as parameter
+ */
+ class Path
+ {
+ public:
+ Path( const std::string &path,
+ const PathArgument &a1 = PathArgument(),
+ const PathArgument &a2 = PathArgument(),
+ const PathArgument &a3 = PathArgument(),
+ const PathArgument &a4 = PathArgument(),
+ const PathArgument &a5 = PathArgument() );
+
+ const Value &resolve( const Value &root ) const;
+ Value resolve( const Value &root,
+ const Value &defaultValue ) const;
+ /// Creates the "path" to access the specified node and returns a reference on the node.
+ Value &make( Value &root ) const;
+
+ private:
+ typedef std::vector<const PathArgument *> InArgs;
+ typedef std::vector<PathArgument> Args;
+
+ void makePath( const std::string &path,
+ const InArgs &in );
+ void addPathInArg( const std::string &path,
+ const InArgs &in,
+ InArgs::const_iterator &itInArg,
+ PathArgument::Kind kind );
+ void invalidPath( const std::string &path,
+ int location );
+
+ Args args_;
+ };
+
+ /** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value.
+ *
+ * - makeMemberName() and releaseMemberName() are called to respectively duplicate and
+ * free an Json::objectValue member name.
+ * - duplicateStringValue() and releaseStringValue() are called similarly to
+ * duplicate and free a Json::stringValue value.
+ */
+ class ValueAllocator
+ {
+ public:
+ enum { unknown = (unsigned)-1 };
+
+ virtual ~ValueAllocator();
+
+ virtual char *makeMemberName( const char *memberName ) = 0;
+ virtual void releaseMemberName( char *memberName ) = 0;
+ virtual char *duplicateStringValue( const char *value,
+ unsigned int length = unknown ) = 0;
+ virtual void releaseStringValue( char *value ) = 0;
+ };
+
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ /** \brief Allocator to customize Value internal map.
+ * Below is an example of a simple implementation (default implementation actually
+ * use memory pool for speed).
+ * \code
+ class DefaultValueMapAllocator : public ValueMapAllocator
+ {
+ public: // overridden from ValueMapAllocator
+ virtual ValueInternalMap *newMap()
+ {
+ return new ValueInternalMap();
+ }
+
+ virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
+ {
+ return new ValueInternalMap( other );
+ }
+
+ virtual void destructMap( ValueInternalMap *map )
+ {
+ delete map;
+ }
+
+ virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
+ {
+ return new ValueInternalLink[size];
+ }
+
+ virtual void releaseMapBuckets( ValueInternalLink *links )
+ {
+ delete [] links;
+ }
+
+ virtual ValueInternalLink *allocateMapLink()
+ {
+ return new ValueInternalLink();
+ }
+
+ virtual void releaseMapLink( ValueInternalLink *link )
+ {
+ delete link;
+ }
+ };
+ * \endcode
+ */
+ class JSON_API ValueMapAllocator
+ {
+ public:
+ virtual ~ValueMapAllocator();
+ virtual ValueInternalMap *newMap() = 0;
+ virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0;
+ virtual void destructMap( ValueInternalMap *map ) = 0;
+ virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0;
+ virtual void releaseMapBuckets( ValueInternalLink *links ) = 0;
+ virtual ValueInternalLink *allocateMapLink() = 0;
+ virtual void releaseMapLink( ValueInternalLink *link ) = 0;
+ };
+
+ /** \brief ValueInternalMap hash-map bucket chain link (for internal use only).
+ * \internal previous_ & next_ allows for bidirectional traversal.
+ */
+ class JSON_API ValueInternalLink
+ {
+ public:
+ enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture.
+ enum InternalFlags {
+ flagAvailable = 0,
+ flagUsed = 1
+ };
+
+ ValueInternalLink();
+
+ ~ValueInternalLink();
+
+ Value items_[itemPerLink];
+ char *keys_[itemPerLink];
+ ValueInternalLink *previous_;
+ ValueInternalLink *next_;
+ };
+
+
+ /** \brief A linked page based hash-table implementation used internally by Value.
+ * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked
+ * list in each bucket to handle collision. There is an addional twist in that
+ * each node of the collision linked list is a page containing a fixed amount of
+ * value. This provides a better compromise between memory usage and speed.
+ *
+ * Each bucket is made up of a chained list of ValueInternalLink. The last
+ * link of a given bucket can be found in the 'previous_' field of the following bucket.
+ * The last link of the last bucket is stored in tailLink_ as it has no following bucket.
+ * Only the last link of a bucket may contains 'available' item. The last link always
+ * contains at least one element unless is it the bucket one very first link.
+ */
+ class JSON_API ValueInternalMap
+ {
+ friend class ValueIteratorBase;
+ friend class Value;
+ public:
+ typedef unsigned int HashKey;
+ typedef unsigned int BucketIndex;
+
+# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ struct IteratorState
+ {
+ IteratorState()
+ : map_(0)
+ , link_(0)
+ , itemIndex_(0)
+ , bucketIndex_(0)
+ {
+ }
+ ValueInternalMap *map_;
+ ValueInternalLink *link_;
+ BucketIndex itemIndex_;
+ BucketIndex bucketIndex_;
+ };
+# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+ ValueInternalMap();
+ ValueInternalMap( const ValueInternalMap &other );
+ ValueInternalMap &operator =( const ValueInternalMap &other );
+ ~ValueInternalMap();
+
+ void swap( ValueInternalMap &other );
+
+ BucketIndex size() const;
+
+ void clear();
+
+ bool reserveDelta( BucketIndex growth );
+
+ bool reserve( BucketIndex newItemCount );
+
+ const Value *find( const char *key ) const;
+
+ Value *find( const char *key );
+
+ Value &resolveReference( const char *key,
+ bool isStatic );
+
+ void remove( const char *key );
+
+ void doActualRemove( ValueInternalLink *link,
+ BucketIndex index,
+ BucketIndex bucketIndex );
+
+ ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex );
+
+ Value &setNewItem( const char *key,
+ bool isStatic,
+ ValueInternalLink *link,
+ BucketIndex index );
+
+ Value &unsafeAdd( const char *key,
+ bool isStatic,
+ HashKey hashedKey );
+
+ HashKey hash( const char *key ) const;
+
+ int compare( const ValueInternalMap &other ) const;
+
+ private:
+ void makeBeginIterator( IteratorState &it ) const;
+ void makeEndIterator( IteratorState &it ) const;
+ static bool equals( const IteratorState &x, const IteratorState &other );
+ static void increment( IteratorState &iterator );
+ static void incrementBucket( IteratorState &iterator );
+ static void decrement( IteratorState &iterator );
+ static const char *key( const IteratorState &iterator );
+ static const char *key( const IteratorState &iterator, bool &isStatic );
+ static Value &value( const IteratorState &iterator );
+ static int distance( const IteratorState &x, const IteratorState &y );
+
+ private:
+ ValueInternalLink *buckets_;
+ ValueInternalLink *tailLink_;
+ BucketIndex bucketsSize_;
+ BucketIndex itemCount_;
+ };
+
+ /** \brief A simplified deque implementation used internally by Value.
+ * \internal
+ * It is based on a list of fixed "page", each page contains a fixed number of items.
+ * Instead of using a linked-list, a array of pointer is used for fast item look-up.
+ * Look-up for an element is as follow:
+ * - compute page index: pageIndex = itemIndex / itemsPerPage
+ * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage]
+ *
+ * Insertion is amortized constant time (only the array containing the index of pointers
+ * need to be reallocated when items are appended).
+ */
+ class JSON_API ValueInternalArray
+ {
+ friend class Value;
+ friend class ValueIteratorBase;
+ public:
+ enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo.
+ typedef Value::ArrayIndex ArrayIndex;
+ typedef unsigned int PageIndex;
+
+# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+ struct IteratorState // Must be a POD
+ {
+ IteratorState()
+ : array_(0)
+ , currentPageIndex_(0)
+ , currentItemIndex_(0)
+ {
+ }
+ ValueInternalArray *array_;
+ Value **currentPageIndex_;
+ unsigned int currentItemIndex_;
+ };
+# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+ ValueInternalArray();
+ ValueInternalArray( const ValueInternalArray &other );
+ ValueInternalArray &operator =( const ValueInternalArray &other );
+ ~ValueInternalArray();
+ void swap( ValueInternalArray &other );
+
+ void clear();
+ void resize( ArrayIndex newSize );
+
+ Value &resolveReference( ArrayIndex index );
+
+ Value *find( ArrayIndex index ) const;
+
+ ArrayIndex size() const;
+
+ int compare( const ValueInternalArray &other ) const;
+
+ private:
+ static bool equals( const IteratorState &x, const IteratorState &other );
+ static void increment( IteratorState &iterator );
+ static void decrement( IteratorState &iterator );
+ static Value &dereference( const IteratorState &iterator );
+ static Value &unsafeDereference( const IteratorState &iterator );
+ static int distance( const IteratorState &x, const IteratorState &y );
+ static ArrayIndex indexOf( const IteratorState &iterator );
+ void makeBeginIterator( IteratorState &it ) const;
+ void makeEndIterator( IteratorState &it ) const;
+ void makeIterator( IteratorState &it, ArrayIndex index ) const;
+
+ void makeIndexValid( ArrayIndex index );
+
+ Value **pages_;
+ ArrayIndex size_;
+ PageIndex pageCount_;
+ };
+
+ /** \brief Experimental: do not use. Allocator to customize Value internal array.
+ * Below is an example of a simple implementation (actual implementation use
+ * memory pool).
+ \code
+class DefaultValueArrayAllocator : public ValueArrayAllocator
+{
+public: // overridden from ValueArrayAllocator
+ virtual ~DefaultValueArrayAllocator()
+ {
+ }
+
+ virtual ValueInternalArray *newArray()
+ {
+ return new ValueInternalArray();
+ }
+
+ virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
+ {
+ return new ValueInternalArray( other );
+ }
+
+ virtual void destruct( ValueInternalArray *array )
+ {
+ delete array;
+ }
+
+ virtual void reallocateArrayPageIndex( Value **&indexes,
+ ValueInternalArray::PageIndex &indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount )
+ {
+ ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
+ if ( minNewIndexCount > newIndexCount )
+ newIndexCount = minNewIndexCount;
+ void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
+ if ( !newIndexes )
+ throw std::bad_alloc();
+ indexCount = newIndexCount;
+ indexes = static_cast<Value **>( newIndexes );
+ }
+ virtual void releaseArrayPageIndex( Value **indexes,
+ ValueInternalArray::PageIndex indexCount )
+ {
+ if ( indexes )
+ free( indexes );
+ }
+
+ virtual Value *allocateArrayPage()
+ {
+ return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
+ }
+
+ virtual void releaseArrayPage( Value *value )
+ {
+ if ( value )
+ free( value );
+ }
+};
+ \endcode
+ */
+ class JSON_API ValueArrayAllocator
+ {
+ public:
+ virtual ~ValueArrayAllocator();
+ virtual ValueInternalArray *newArray() = 0;
+ virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0;
+ virtual void destructArray( ValueInternalArray *array ) = 0;
+ /** \brief Reallocate array page index.
+ * Reallocates an array of pointer on each page.
+ * \param indexes [input] pointer on the current index. May be \c NULL.
+ * [output] pointer on the new index of at least
+ * \a minNewIndexCount pages.
+ * \param indexCount [input] current number of pages in the index.
+ * [output] number of page the reallocated index can handle.
+ * \b MUST be >= \a minNewIndexCount.
+ * \param minNewIndexCount Minimum number of page the new index must be able to
+ * handle.
+ */
+ virtual void reallocateArrayPageIndex( Value **&indexes,
+ ValueInternalArray::PageIndex &indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount ) = 0;
+ virtual void releaseArrayPageIndex( Value **indexes,
+ ValueInternalArray::PageIndex indexCount ) = 0;
+ virtual Value *allocateArrayPage() = 0;
+ virtual void releaseArrayPage( Value *value ) = 0;
+ };
+#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+
+ /** \brief base class for Value iterators.
+ *
+ */
+ class ValueIteratorBase
+ {
+ public:
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef ValueIteratorBase SelfType;
+
+ ValueIteratorBase();
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ explicit ValueIteratorBase( const Value::ObjectValues::iterator ¤t );
+#else
+ ValueIteratorBase( const ValueInternalArray::IteratorState &state );
+ ValueIteratorBase( const ValueInternalMap::IteratorState &state );
+#endif
+
+ bool operator ==( const SelfType &other ) const
+ {
+ return isEqual( other );
+ }
+
+ bool operator !=( const SelfType &other ) const
+ {
+ return !isEqual( other );
+ }
+
+ difference_type operator -( const SelfType &other ) const
+ {
+ return computeDistance( other );
+ }
+
+ /// Return either the index or the member name of the referenced value as a Value.
+ Value key() const;
+
+ /// Return the index of the referenced Value. -1 if it is not an arrayValue.
+ UInt index() const;
+
+ /// Return the member name of the referenced Value. "" if it is not an objectValue.
+ const char *memberName() const;
+
+ protected:
+ Value &deref() const;
+
+ void increment();
+
+ void decrement();
+
+ difference_type computeDistance( const SelfType &other ) const;
+
+ bool isEqual( const SelfType &other ) const;
+
+ void copy( const SelfType &other );
+
+ private:
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ Value::ObjectValues::iterator current_;
+ // Indicates that iterator is for a null value.
+ bool isNull_;
+#else
+ union
+ {
+ ValueInternalArray::IteratorState array_;
+ ValueInternalMap::IteratorState map_;
+ } iterator_;
+ bool isArray_;
+#endif
+ };
+
+ /** \brief const iterator for object and array value.
+ *
+ */
+ class ValueConstIterator : public ValueIteratorBase
+ {
+ friend class Value;
+ public:
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef const Value &reference;
+ typedef const Value *pointer;
+ typedef ValueConstIterator SelfType;
+
+ ValueConstIterator();
+ private:
+ /*! \internal Use by Value to create an iterator.
+ */
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ explicit ValueConstIterator( const Value::ObjectValues::iterator ¤t );
+#else
+ ValueConstIterator( const ValueInternalArray::IteratorState &state );
+ ValueConstIterator( const ValueInternalMap::IteratorState &state );
+#endif
+ public:
+ SelfType &operator =( const ValueIteratorBase &other );
+
+ SelfType operator++( int )
+ {
+ SelfType temp( *this );
+ ++*this;
+ return temp;
+ }
+
+ SelfType operator--( int )
+ {
+ SelfType temp( *this );
+ --*this;
+ return temp;
+ }
+
+ SelfType &operator--()
+ {
+ decrement();
+ return *this;
+ }
+
+ SelfType &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ reference operator *() const
+ {
+ return deref();
+ }
+ };
+
+
+ /** \brief Iterator for object and array value.
+ */
+ class ValueIterator : public ValueIteratorBase
+ {
+ friend class Value;
+ public:
+ typedef unsigned int size_t;
+ typedef int difference_type;
+ typedef Value &reference;
+ typedef Value *pointer;
+ typedef ValueIterator SelfType;
+
+ ValueIterator();
+ ValueIterator( const ValueConstIterator &other );
+ ValueIterator( const ValueIterator &other );
+ private:
+ /*! \internal Use by Value to create an iterator.
+ */
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ explicit ValueIterator( const Value::ObjectValues::iterator ¤t );
+#else
+ ValueIterator( const ValueInternalArray::IteratorState &state );
+ ValueIterator( const ValueInternalMap::IteratorState &state );
+#endif
+ public:
+
+ SelfType &operator =( const SelfType &other );
+
+ SelfType operator++( int )
+ {
+ SelfType temp( *this );
+ ++*this;
+ return temp;
+ }
+
+ SelfType operator--( int )
+ {
+ SelfType temp( *this );
+ --*this;
+ return temp;
+ }
+
+ SelfType &operator--()
+ {
+ decrement();
+ return *this;
+ }
+
+ SelfType &operator++()
+ {
+ increment();
+ return *this;
+ }
+
+ reference operator *() const
+ {
+ return deref();
+ }
+ };
+
+
+} // namespace Json
+
+
+#endif // CPPTL_JSON_H_INCLUDED
--- /dev/null
+#ifndef JSON_WRITER_H_INCLUDED
+# define JSON_WRITER_H_INCLUDED
+
+# include "value.h"
+# include <vector>
+# include <string>
+# include <iostream>
+
+namespace Json {
+
+ class Value;
+
+ /** \brief Abstract class for writers.
+ */
+ class JSON_API Writer
+ {
+ public:
+ virtual ~Writer();
+
+ virtual std::string write( const Value &root ) = 0;
+ };
+
+ /** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format without formatting (not human friendly).
+ *
+ * The JSON document is written in a single line. It is not intended for 'human' consumption,
+ * but may be usefull to support feature such as RPC where bandwith is limited.
+ * \sa Reader, Value
+ */
+ class JSON_API FastWriter : public Writer
+ {
+ public:
+ FastWriter();
+ virtual ~FastWriter(){}
+
+ void enableYAMLCompatibility();
+
+ public: // overridden from Writer
+ virtual std::string write( const Value &root );
+
+ private:
+ void writeValue( const Value &value );
+
+ std::string document_;
+ bool yamlCompatiblityEnabled_;
+ };
+
+ /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way.
+ *
+ * The rules for line break and indent are as follow:
+ * - Object value:
+ * - if empty then print {} without indent and line break
+ * - if not empty the print '{', line break & indent, print one value per line
+ * and then unindent and line break and print '}'.
+ * - Array value:
+ * - if empty then print [] without indent and line break
+ * - if the array contains no object value, empty array or some other value types,
+ * and all the values fit on one lines, then print the array on a single line.
+ * - otherwise, it the values do not fit on one line, or the array contains
+ * object or non empty array, then print one value per line.
+ *
+ * If the Value have comments then they are outputed according to their #CommentPlacement.
+ *
+ * \sa Reader, Value, Value::setComment()
+ */
+ class JSON_API StyledWriter: public Writer
+ {
+ public:
+ StyledWriter();
+ virtual ~StyledWriter(){}
+
+ public: // overridden from Writer
+ /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
+ * \param root Value to serialize.
+ * \return String containing the JSON document that represents the root value.
+ */
+ virtual std::string write( const Value &root );
+
+ private:
+ void writeValue( const Value &value );
+ void writeArrayValue( const Value &value );
+ bool isMultineArray( const Value &value );
+ void pushValue( const std::string &value );
+ void writeIndent();
+ void writeWithIndent( const std::string &value );
+ void indent();
+ void unindent();
+ void writeCommentBeforeValue( const Value &root );
+ void writeCommentAfterValueOnSameLine( const Value &root );
+ bool hasCommentForValue( const Value &value );
+ static std::string normalizeEOL( const std::string &text );
+
+ typedef std::vector<std::string> ChildValues;
+
+ ChildValues childValues_;
+ std::string document_;
+ std::string indentString_;
+ int rightMargin_;
+ int indentSize_;
+ bool addChildValues_;
+ };
+
+ /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way,
+ to a stream rather than to a string.
+ *
+ * The rules for line break and indent are as follow:
+ * - Object value:
+ * - if empty then print {} without indent and line break
+ * - if not empty the print '{', line break & indent, print one value per line
+ * and then unindent and line break and print '}'.
+ * - Array value:
+ * - if empty then print [] without indent and line break
+ * - if the array contains no object value, empty array or some other value types,
+ * and all the values fit on one lines, then print the array on a single line.
+ * - otherwise, it the values do not fit on one line, or the array contains
+ * object or non empty array, then print one value per line.
+ *
+ * If the Value have comments then they are outputed according to their #CommentPlacement.
+ *
+ * \param indentation Each level will be indented by this amount extra.
+ * \sa Reader, Value, Value::setComment()
+ */
+ class JSON_API StyledStreamWriter
+ {
+ public:
+ StyledStreamWriter( std::string indentation="\t" );
+ ~StyledStreamWriter(){}
+
+ public:
+ /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
+ * \param out Stream to write to. (Can be ostringstream, e.g.)
+ * \param root Value to serialize.
+ * \note There is no point in deriving from Writer, since write() should not return a value.
+ */
+ void write( std::ostream &out, const Value &root );
+
+ private:
+ void writeValue( const Value &value );
+ void writeArrayValue( const Value &value );
+ bool isMultineArray( const Value &value );
+ void pushValue( const std::string &value );
+ void writeIndent();
+ void writeWithIndent( const std::string &value );
+ void indent();
+ void unindent();
+ void writeCommentBeforeValue( const Value &root );
+ void writeCommentAfterValueOnSameLine( const Value &root );
+ bool hasCommentForValue( const Value &value );
+ static std::string normalizeEOL( const std::string &text );
+
+ typedef std::vector<std::string> ChildValues;
+
+ ChildValues childValues_;
+ std::ostream* document_;
+ std::string indentString_;
+ int rightMargin_;
+ std::string indentation_;
+ bool addChildValues_;
+ };
+
+ std::string JSON_API valueToString( Int value );
+ std::string JSON_API valueToString( UInt value );
+ std::string JSON_API valueToString( double value );
+ std::string JSON_API valueToString( bool value );
+ std::string JSON_API valueToQuotedString( const char *value );
+
+ /// \brief Output using the StyledStreamWriter.
+ /// \see Json::operator>>()
+ std::ostream& operator<<( std::ostream&, const Value &root );
+
+} // namespace Json
+
+
+
+#endif // JSON_WRITER_H_INCLUDED
--- /dev/null
+#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
+# define JSONCPP_BATCHALLOCATOR_H_INCLUDED
+
+# include <stdlib.h>
+# include <assert.h>
+
+# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
+
+namespace Json {
+
+/* Fast memory allocator.
+ *
+ * This memory allocator allocates memory for a batch of object (specified by
+ * the page size, the number of object in each page).
+ *
+ * It does not allow the destruction of a single object. All the allocated objects
+ * can be destroyed at once. The memory can be either released or reused for future
+ * allocation.
+ *
+ * The in-place new operator must be used to construct the object using the pointer
+ * returned by allocate.
+ */
+template<typename AllocatedType
+ ,const unsigned int objectPerAllocation>
+class BatchAllocator
+{
+public:
+ typedef AllocatedType Type;
+
+ BatchAllocator( unsigned int objectsPerPage = 255 )
+ : freeHead_( 0 )
+ , objectsPerPage_( objectsPerPage )
+ {
+// printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
+ assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
+ assert( objectsPerPage >= 16 );
+ batches_ = allocateBatch( 0 ); // allocated a dummy page
+ currentBatch_ = batches_;
+ }
+
+ ~BatchAllocator()
+ {
+ for ( BatchInfo *batch = batches_; batch; )
+ {
+ BatchInfo *nextBatch = batch->next_;
+ free( batch );
+ batch = nextBatch;
+ }
+ }
+
+ /// allocate space for an array of objectPerAllocation object.
+ /// @warning it is the responsability of the caller to call objects constructors.
+ AllocatedType *allocate()
+ {
+ if ( freeHead_ ) // returns node from free list.
+ {
+ AllocatedType *object = freeHead_;
+ freeHead_ = *(AllocatedType **)object;
+ return object;
+ }
+ if ( currentBatch_->used_ == currentBatch_->end_ )
+ {
+ currentBatch_ = currentBatch_->next_;
+ while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
+ currentBatch_ = currentBatch_->next_;
+
+ if ( !currentBatch_ ) // no free batch found, allocate a new one
+ {
+ currentBatch_ = allocateBatch( objectsPerPage_ );
+ currentBatch_->next_ = batches_; // insert at the head of the list
+ batches_ = currentBatch_;
+ }
+ }
+ AllocatedType *allocated = currentBatch_->used_;
+ currentBatch_->used_ += objectPerAllocation;
+ return allocated;
+ }
+
+ /// Release the object.
+ /// @warning it is the responsability of the caller to actually destruct the object.
+ void release( AllocatedType *object )
+ {
+ assert( object != 0 );
+ *(AllocatedType **)object = freeHead_;
+ freeHead_ = object;
+ }
+
+private:
+ struct BatchInfo
+ {
+ BatchInfo *next_;
+ AllocatedType *used_;
+ AllocatedType *end_;
+ AllocatedType buffer_[objectPerAllocation];
+ };
+
+ // disabled copy constructor and assignement operator.
+ BatchAllocator( const BatchAllocator & );
+ void operator =( const BatchAllocator &);
+
+ static BatchInfo *allocateBatch( unsigned int objectsPerPage )
+ {
+ const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
+ + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
+ BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
+ batch->next_ = 0;
+ batch->used_ = batch->buffer_;
+ batch->end_ = batch->buffer_ + objectsPerPage;
+ return batch;
+ }
+
+ BatchInfo *batches_;
+ BatchInfo *currentBatch_;
+ /// Head of a single linked list within the allocated space of freeed object
+ AllocatedType *freeHead_;
+ unsigned int objectsPerPage_;
+};
+
+
+} // namespace Json
+
+# endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
+
+#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
+
--- /dev/null
+// included by json_value.cpp
+// everything is within Json namespace
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalArray
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueArrayAllocator::~ValueArrayAllocator()
+{
+}
+
+// //////////////////////////////////////////////////////////////////
+// class DefaultValueArrayAllocator
+// //////////////////////////////////////////////////////////////////
+#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+class DefaultValueArrayAllocator : public ValueArrayAllocator
+{
+public: // overridden from ValueArrayAllocator
+ virtual ~DefaultValueArrayAllocator()
+ {
+ }
+
+ virtual ValueInternalArray *newArray()
+ {
+ return new ValueInternalArray();
+ }
+
+ virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
+ {
+ return new ValueInternalArray( other );
+ }
+
+ virtual void destructArray( ValueInternalArray *array )
+ {
+ delete array;
+ }
+
+ virtual void reallocateArrayPageIndex( Value **&indexes,
+ ValueInternalArray::PageIndex &indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount )
+ {
+ ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
+ if ( minNewIndexCount > newIndexCount )
+ newIndexCount = minNewIndexCount;
+ void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
+ if ( !newIndexes )
+ throw std::bad_alloc();
+ indexCount = newIndexCount;
+ indexes = static_cast<Value **>( newIndexes );
+ }
+ virtual void releaseArrayPageIndex( Value **indexes,
+ ValueInternalArray::PageIndex indexCount )
+ {
+ if ( indexes )
+ free( indexes );
+ }
+
+ virtual Value *allocateArrayPage()
+ {
+ return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) );
+ }
+
+ virtual void releaseArrayPage( Value *value )
+ {
+ if ( value )
+ free( value );
+ }
+};
+
+#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+/// @todo make this thread-safe (lock when accessign batch allocator)
+class DefaultValueArrayAllocator : public ValueArrayAllocator
+{
+public: // overridden from ValueArrayAllocator
+ virtual ~DefaultValueArrayAllocator()
+ {
+ }
+
+ virtual ValueInternalArray *newArray()
+ {
+ ValueInternalArray *array = arraysAllocator_.allocate();
+ new (array) ValueInternalArray(); // placement new
+ return array;
+ }
+
+ virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
+ {
+ ValueInternalArray *array = arraysAllocator_.allocate();
+ new (array) ValueInternalArray( other ); // placement new
+ return array;
+ }
+
+ virtual void destructArray( ValueInternalArray *array )
+ {
+ if ( array )
+ {
+ array->~ValueInternalArray();
+ arraysAllocator_.release( array );
+ }
+ }
+
+ virtual void reallocateArrayPageIndex( Value **&indexes,
+ ValueInternalArray::PageIndex &indexCount,
+ ValueInternalArray::PageIndex minNewIndexCount )
+ {
+ ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
+ if ( minNewIndexCount > newIndexCount )
+ newIndexCount = minNewIndexCount;
+ void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
+ if ( !newIndexes )
+ throw std::bad_alloc();
+ indexCount = newIndexCount;
+ indexes = static_cast<Value **>( newIndexes );
+ }
+ virtual void releaseArrayPageIndex( Value **indexes,
+ ValueInternalArray::PageIndex indexCount )
+ {
+ if ( indexes )
+ free( indexes );
+ }
+
+ virtual Value *allocateArrayPage()
+ {
+ return static_cast<Value *>( pagesAllocator_.allocate() );
+ }
+
+ virtual void releaseArrayPage( Value *value )
+ {
+ if ( value )
+ pagesAllocator_.release( value );
+ }
+private:
+ BatchAllocator<ValueInternalArray,1> arraysAllocator_;
+ BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_;
+};
+#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+
+static ValueArrayAllocator *&arrayAllocator()
+{
+ static DefaultValueArrayAllocator defaultAllocator;
+ static ValueArrayAllocator *arrayAllocator = &defaultAllocator;
+ return arrayAllocator;
+}
+
+static struct DummyArrayAllocatorInitializer {
+ DummyArrayAllocatorInitializer()
+ {
+ arrayAllocator(); // ensure arrayAllocator() statics are initialized before main().
+ }
+} dummyArrayAllocatorInitializer;
+
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalArray
+// //////////////////////////////////////////////////////////////////
+bool
+ValueInternalArray::equals( const IteratorState &x,
+ const IteratorState &other )
+{
+ return x.array_ == other.array_
+ && x.currentItemIndex_ == other.currentItemIndex_
+ && x.currentPageIndex_ == other.currentPageIndex_;
+}
+
+
+void
+ValueInternalArray::increment( IteratorState &it )
+{
+ JSON_ASSERT_MESSAGE( it.array_ &&
+ (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
+ != it.array_->size_,
+ "ValueInternalArray::increment(): moving iterator beyond end" );
+ ++(it.currentItemIndex_);
+ if ( it.currentItemIndex_ == itemsPerPage )
+ {
+ it.currentItemIndex_ = 0;
+ ++(it.currentPageIndex_);
+ }
+}
+
+
+void
+ValueInternalArray::decrement( IteratorState &it )
+{
+ JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_
+ && it.currentItemIndex_ == 0,
+ "ValueInternalArray::decrement(): moving iterator beyond end" );
+ if ( it.currentItemIndex_ == 0 )
+ {
+ it.currentItemIndex_ = itemsPerPage-1;
+ --(it.currentPageIndex_);
+ }
+ else
+ {
+ --(it.currentItemIndex_);
+ }
+}
+
+
+Value &
+ValueInternalArray::unsafeDereference( const IteratorState &it )
+{
+ return (*(it.currentPageIndex_))[it.currentItemIndex_];
+}
+
+
+Value &
+ValueInternalArray::dereference( const IteratorState &it )
+{
+ JSON_ASSERT_MESSAGE( it.array_ &&
+ (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_
+ < it.array_->size_,
+ "ValueInternalArray::dereference(): dereferencing invalid iterator" );
+ return unsafeDereference( it );
+}
+
+void
+ValueInternalArray::makeBeginIterator( IteratorState &it ) const
+{
+ it.array_ = const_cast<ValueInternalArray *>( this );
+ it.currentItemIndex_ = 0;
+ it.currentPageIndex_ = pages_;
+}
+
+
+void
+ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const
+{
+ it.array_ = const_cast<ValueInternalArray *>( this );
+ it.currentItemIndex_ = index % itemsPerPage;
+ it.currentPageIndex_ = pages_ + index / itemsPerPage;
+}
+
+
+void
+ValueInternalArray::makeEndIterator( IteratorState &it ) const
+{
+ makeIterator( it, size_ );
+}
+
+
+ValueInternalArray::ValueInternalArray()
+ : pages_( 0 )
+ , size_( 0 )
+ , pageCount_( 0 )
+{
+}
+
+
+ValueInternalArray::ValueInternalArray( const ValueInternalArray &other )
+ : pages_( 0 )
+ , pageCount_( 0 )
+ , size_( other.size_ )
+{
+ PageIndex minNewPages = other.size_ / itemsPerPage;
+ arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
+ JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages,
+ "ValueInternalArray::reserve(): bad reallocation" );
+ IteratorState itOther;
+ other.makeBeginIterator( itOther );
+ Value *value;
+ for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) )
+ {
+ if ( index % itemsPerPage == 0 )
+ {
+ PageIndex pageIndex = index / itemsPerPage;
+ value = arrayAllocator()->allocateArrayPage();
+ pages_[pageIndex] = value;
+ }
+ new (value) Value( dereference( itOther ) );
+ }
+}
+
+
+ValueInternalArray &
+ValueInternalArray::operator =( const ValueInternalArray &other )
+{
+ ValueInternalArray temp( other );
+ swap( temp );
+ return *this;
+}
+
+
+ValueInternalArray::~ValueInternalArray()
+{
+ // destroy all constructed items
+ IteratorState it;
+ IteratorState itEnd;
+ makeBeginIterator( it);
+ makeEndIterator( itEnd );
+ for ( ; !equals(it,itEnd); increment(it) )
+ {
+ Value *value = &dereference(it);
+ value->~Value();
+ }
+ // release all pages
+ PageIndex lastPageIndex = size_ / itemsPerPage;
+ for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex )
+ arrayAllocator()->releaseArrayPage( pages_[pageIndex] );
+ // release pages index
+ arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ );
+}
+
+
+void
+ValueInternalArray::swap( ValueInternalArray &other )
+{
+ Value **tempPages = pages_;
+ pages_ = other.pages_;
+ other.pages_ = tempPages;
+ ArrayIndex tempSize = size_;
+ size_ = other.size_;
+ other.size_ = tempSize;
+ PageIndex tempPageCount = pageCount_;
+ pageCount_ = other.pageCount_;
+ other.pageCount_ = tempPageCount;
+}
+
+void
+ValueInternalArray::clear()
+{
+ ValueInternalArray dummy;
+ swap( dummy );
+}
+
+
+void
+ValueInternalArray::resize( ArrayIndex newSize )
+{
+ if ( newSize == 0 )
+ clear();
+ else if ( newSize < size_ )
+ {
+ IteratorState it;
+ IteratorState itEnd;
+ makeIterator( it, newSize );
+ makeIterator( itEnd, size_ );
+ for ( ; !equals(it,itEnd); increment(it) )
+ {
+ Value *value = &dereference(it);
+ value->~Value();
+ }
+ PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage;
+ PageIndex lastPageIndex = size_ / itemsPerPage;
+ for ( ; pageIndex < lastPageIndex; ++pageIndex )
+ arrayAllocator()->releaseArrayPage( pages_[pageIndex] );
+ size_ = newSize;
+ }
+ else if ( newSize > size_ )
+ resolveReference( newSize );
+}
+
+
+void
+ValueInternalArray::makeIndexValid( ArrayIndex index )
+{
+ // Need to enlarge page index ?
+ if ( index >= pageCount_ * itemsPerPage )
+ {
+ PageIndex minNewPages = (index + 1) / itemsPerPage;
+ arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages );
+ JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" );
+ }
+
+ // Need to allocate new pages ?
+ ArrayIndex nextPageIndex =
+ (size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage
+ : size_;
+ if ( nextPageIndex <= index )
+ {
+ PageIndex pageIndex = nextPageIndex / itemsPerPage;
+ PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1;
+ for ( ; pageToAllocate-- > 0; ++pageIndex )
+ pages_[pageIndex] = arrayAllocator()->allocateArrayPage();
+ }
+
+ // Initialize all new entries
+ IteratorState it;
+ IteratorState itEnd;
+ makeIterator( it, size_ );
+ size_ = index + 1;
+ makeIterator( itEnd, size_ );
+ for ( ; !equals(it,itEnd); increment(it) )
+ {
+ Value *value = &dereference(it);
+ new (value) Value(); // Construct a default value using placement new
+ }
+}
+
+Value &
+ValueInternalArray::resolveReference( ArrayIndex index )
+{
+ if ( index >= size_ )
+ makeIndexValid( index );
+ return pages_[index/itemsPerPage][index%itemsPerPage];
+}
+
+Value *
+ValueInternalArray::find( ArrayIndex index ) const
+{
+ if ( index >= size_ )
+ return 0;
+ return &(pages_[index/itemsPerPage][index%itemsPerPage]);
+}
+
+ValueInternalArray::ArrayIndex
+ValueInternalArray::size() const
+{
+ return size_;
+}
+
+int
+ValueInternalArray::distance( const IteratorState &x, const IteratorState &y )
+{
+ return indexOf(y) - indexOf(x);
+}
+
+
+ValueInternalArray::ArrayIndex
+ValueInternalArray::indexOf( const IteratorState &iterator )
+{
+ if ( !iterator.array_ )
+ return ArrayIndex(-1);
+ return ArrayIndex(
+ (iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage
+ + iterator.currentItemIndex_ );
+}
+
+
+int
+ValueInternalArray::compare( const ValueInternalArray &other ) const
+{
+ int sizeDiff( size_ - other.size_ );
+ if ( sizeDiff != 0 )
+ return sizeDiff;
+
+ for ( ArrayIndex index =0; index < size_; ++index )
+ {
+ int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare(
+ other.pages_[index/itemsPerPage][index%itemsPerPage] );
+ if ( diff != 0 )
+ return diff;
+ }
+ return 0;
+}
--- /dev/null
+// included by json_value.cpp
+// everything is within Json namespace
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalMap
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+/** \internal MUST be safely initialized using memset( this, 0, sizeof(ValueInternalLink) );
+ * This optimization is used by the fast allocator.
+ */
+ValueInternalLink::ValueInternalLink()
+ : previous_( 0 )
+ , next_( 0 )
+{
+}
+
+ValueInternalLink::~ValueInternalLink()
+{
+ for ( int index =0; index < itemPerLink; ++index )
+ {
+ if ( !items_[index].isItemAvailable() )
+ {
+ if ( !items_[index].isMemberNameStatic() )
+ free( keys_[index] );
+ }
+ else
+ break;
+ }
+}
+
+
+
+ValueMapAllocator::~ValueMapAllocator()
+{
+}
+
+#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+class DefaultValueMapAllocator : public ValueMapAllocator
+{
+public: // overridden from ValueMapAllocator
+ virtual ValueInternalMap *newMap()
+ {
+ return new ValueInternalMap();
+ }
+
+ virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
+ {
+ return new ValueInternalMap( other );
+ }
+
+ virtual void destructMap( ValueInternalMap *map )
+ {
+ delete map;
+ }
+
+ virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
+ {
+ return new ValueInternalLink[size];
+ }
+
+ virtual void releaseMapBuckets( ValueInternalLink *links )
+ {
+ delete [] links;
+ }
+
+ virtual ValueInternalLink *allocateMapLink()
+ {
+ return new ValueInternalLink();
+ }
+
+ virtual void releaseMapLink( ValueInternalLink *link )
+ {
+ delete link;
+ }
+};
+#else
+/// @todo make this thread-safe (lock when accessign batch allocator)
+class DefaultValueMapAllocator : public ValueMapAllocator
+{
+public: // overridden from ValueMapAllocator
+ virtual ValueInternalMap *newMap()
+ {
+ ValueInternalMap *map = mapsAllocator_.allocate();
+ new (map) ValueInternalMap(); // placement new
+ return map;
+ }
+
+ virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
+ {
+ ValueInternalMap *map = mapsAllocator_.allocate();
+ new (map) ValueInternalMap( other ); // placement new
+ return map;
+ }
+
+ virtual void destructMap( ValueInternalMap *map )
+ {
+ if ( map )
+ {
+ map->~ValueInternalMap();
+ mapsAllocator_.release( map );
+ }
+ }
+
+ virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
+ {
+ return new ValueInternalLink[size];
+ }
+
+ virtual void releaseMapBuckets( ValueInternalLink *links )
+ {
+ delete [] links;
+ }
+
+ virtual ValueInternalLink *allocateMapLink()
+ {
+ ValueInternalLink *link = linksAllocator_.allocate();
+ memset( link, 0, sizeof(ValueInternalLink) );
+ return link;
+ }
+
+ virtual void releaseMapLink( ValueInternalLink *link )
+ {
+ link->~ValueInternalLink();
+ linksAllocator_.release( link );
+ }
+private:
+ BatchAllocator<ValueInternalMap,1> mapsAllocator_;
+ BatchAllocator<ValueInternalLink,1> linksAllocator_;
+};
+#endif
+
+static ValueMapAllocator *&mapAllocator()
+{
+ static DefaultValueMapAllocator defaultAllocator;
+ static ValueMapAllocator *mapAllocator = &defaultAllocator;
+ return mapAllocator;
+}
+
+static struct DummyMapAllocatorInitializer {
+ DummyMapAllocatorInitializer()
+ {
+ mapAllocator(); // ensure mapAllocator() statics are initialized before main().
+ }
+} dummyMapAllocatorInitializer;
+
+
+
+// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32.
+
+/*
+use linked list hash map.
+buckets array is a container.
+linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124)
+value have extra state: valid, available, deleted
+*/
+
+
+ValueInternalMap::ValueInternalMap()
+ : buckets_( 0 )
+ , tailLink_( 0 )
+ , bucketsSize_( 0 )
+ , itemCount_( 0 )
+{
+}
+
+
+ValueInternalMap::ValueInternalMap( const ValueInternalMap &other )
+ : buckets_( 0 )
+ , tailLink_( 0 )
+ , bucketsSize_( 0 )
+ , itemCount_( 0 )
+{
+ reserve( other.itemCount_ );
+ IteratorState it;
+ IteratorState itEnd;
+ other.makeBeginIterator( it );
+ other.makeEndIterator( itEnd );
+ for ( ; !equals(it,itEnd); increment(it) )
+ {
+ bool isStatic;
+ const char *memberName = key( it, isStatic );
+ const Value &aValue = value( it );
+ resolveReference(memberName, isStatic) = aValue;
+ }
+}
+
+
+ValueInternalMap &
+ValueInternalMap::operator =( const ValueInternalMap &other )
+{
+ ValueInternalMap dummy( other );
+ swap( dummy );
+ return *this;
+}
+
+
+ValueInternalMap::~ValueInternalMap()
+{
+ if ( buckets_ )
+ {
+ for ( BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex )
+ {
+ ValueInternalLink *link = buckets_[bucketIndex].next_;
+ while ( link )
+ {
+ ValueInternalLink *linkToRelease = link;
+ link = link->next_;
+ mapAllocator()->releaseMapLink( linkToRelease );
+ }
+ }
+ mapAllocator()->releaseMapBuckets( buckets_ );
+ }
+}
+
+
+void
+ValueInternalMap::swap( ValueInternalMap &other )
+{
+ ValueInternalLink *tempBuckets = buckets_;
+ buckets_ = other.buckets_;
+ other.buckets_ = tempBuckets;
+ ValueInternalLink *tempTailLink = tailLink_;
+ tailLink_ = other.tailLink_;
+ other.tailLink_ = tempTailLink;
+ BucketIndex tempBucketsSize = bucketsSize_;
+ bucketsSize_ = other.bucketsSize_;
+ other.bucketsSize_ = tempBucketsSize;
+ BucketIndex tempItemCount = itemCount_;
+ itemCount_ = other.itemCount_;
+ other.itemCount_ = tempItemCount;
+}
+
+
+void
+ValueInternalMap::clear()
+{
+ ValueInternalMap dummy;
+ swap( dummy );
+}
+
+
+ValueInternalMap::BucketIndex
+ValueInternalMap::size() const
+{
+ return itemCount_;
+}
+
+bool
+ValueInternalMap::reserveDelta( BucketIndex growth )
+{
+ return reserve( itemCount_ + growth );
+}
+
+bool
+ValueInternalMap::reserve( BucketIndex newItemCount )
+{
+ if ( !buckets_ && newItemCount > 0 )
+ {
+ buckets_ = mapAllocator()->allocateMapBuckets( 1 );
+ bucketsSize_ = 1;
+ tailLink_ = &buckets_[0];
+ }
+// BucketIndex idealBucketCount = (newItemCount + ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink;
+ return true;
+}
+
+
+const Value *
+ValueInternalMap::find( const char *key ) const
+{
+ if ( !bucketsSize_ )
+ return 0;
+ HashKey hashedKey = hash( key );
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ for ( const ValueInternalLink *current = &buckets_[bucketIndex];
+ current != 0;
+ current = current->next_ )
+ {
+ for ( BucketIndex index=0; index < ValueInternalLink::itemPerLink; ++index )
+ {
+ if ( current->items_[index].isItemAvailable() )
+ return 0;
+ if ( strcmp( key, current->keys_[index] ) == 0 )
+ return ¤t->items_[index];
+ }
+ }
+ return 0;
+}
+
+
+Value *
+ValueInternalMap::find( const char *key )
+{
+ const ValueInternalMap *constThis = this;
+ return const_cast<Value *>( constThis->find( key ) );
+}
+
+
+Value &
+ValueInternalMap::resolveReference( const char *key,
+ bool isStatic )
+{
+ HashKey hashedKey = hash( key );
+ if ( bucketsSize_ )
+ {
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ ValueInternalLink **previous = 0;
+ BucketIndex index;
+ for ( ValueInternalLink *current = &buckets_[bucketIndex];
+ current != 0;
+ previous = ¤t->next_, current = current->next_ )
+ {
+ for ( index=0; index < ValueInternalLink::itemPerLink; ++index )
+ {
+ if ( current->items_[index].isItemAvailable() )
+ return setNewItem( key, isStatic, current, index );
+ if ( strcmp( key, current->keys_[index] ) == 0 )
+ return current->items_[index];
+ }
+ }
+ }
+
+ reserveDelta( 1 );
+ return unsafeAdd( key, isStatic, hashedKey );
+}
+
+
+void
+ValueInternalMap::remove( const char *key )
+{
+ HashKey hashedKey = hash( key );
+ if ( !bucketsSize_ )
+ return;
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ for ( ValueInternalLink *link = &buckets_[bucketIndex];
+ link != 0;
+ link = link->next_ )
+ {
+ BucketIndex index;
+ for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
+ {
+ if ( link->items_[index].isItemAvailable() )
+ return;
+ if ( strcmp( key, link->keys_[index] ) == 0 )
+ {
+ doActualRemove( link, index, bucketIndex );
+ return;
+ }
+ }
+ }
+}
+
+void
+ValueInternalMap::doActualRemove( ValueInternalLink *link,
+ BucketIndex index,
+ BucketIndex bucketIndex )
+{
+ // find last item of the bucket and swap it with the 'removed' one.
+ // set removed items flags to 'available'.
+ // if last page only contains 'available' items, then desallocate it (it's empty)
+ ValueInternalLink *&lastLink = getLastLinkInBucket( index );
+ BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1
+ for ( ;
+ lastItemIndex < ValueInternalLink::itemPerLink;
+ ++lastItemIndex ) // may be optimized with dicotomic search
+ {
+ if ( lastLink->items_[lastItemIndex].isItemAvailable() )
+ break;
+ }
+
+ BucketIndex lastUsedIndex = lastItemIndex - 1;
+ Value *valueToDelete = &link->items_[index];
+ Value *valueToPreserve = &lastLink->items_[lastUsedIndex];
+ if ( valueToDelete != valueToPreserve )
+ valueToDelete->swap( *valueToPreserve );
+ if ( lastUsedIndex == 0 ) // page is now empty
+ { // remove it from bucket linked list and delete it.
+ ValueInternalLink *linkPreviousToLast = lastLink->previous_;
+ if ( linkPreviousToLast != 0 ) // can not deleted bucket link.
+ {
+ mapAllocator()->releaseMapLink( lastLink );
+ linkPreviousToLast->next_ = 0;
+ lastLink = linkPreviousToLast;
+ }
+ }
+ else
+ {
+ Value dummy;
+ valueToPreserve->swap( dummy ); // restore deleted to default Value.
+ valueToPreserve->setItemUsed( false );
+ }
+ --itemCount_;
+}
+
+
+ValueInternalLink *&
+ValueInternalMap::getLastLinkInBucket( BucketIndex bucketIndex )
+{
+ if ( bucketIndex == bucketsSize_ - 1 )
+ return tailLink_;
+ ValueInternalLink *&previous = buckets_[bucketIndex+1].previous_;
+ if ( !previous )
+ previous = &buckets_[bucketIndex];
+ return previous;
+}
+
+
+Value &
+ValueInternalMap::setNewItem( const char *key,
+ bool isStatic,
+ ValueInternalLink *link,
+ BucketIndex index )
+{
+ char *duplicatedKey = valueAllocator()->makeMemberName( key );
+ ++itemCount_;
+ link->keys_[index] = duplicatedKey;
+ link->items_[index].setItemUsed();
+ link->items_[index].setMemberNameIsStatic( isStatic );
+ return link->items_[index]; // items already default constructed.
+}
+
+
+Value &
+ValueInternalMap::unsafeAdd( const char *key,
+ bool isStatic,
+ HashKey hashedKey )
+{
+ JSON_ASSERT_MESSAGE( bucketsSize_ > 0, "ValueInternalMap::unsafeAdd(): internal logic error." );
+ BucketIndex bucketIndex = hashedKey % bucketsSize_;
+ ValueInternalLink *&previousLink = getLastLinkInBucket( bucketIndex );
+ ValueInternalLink *link = previousLink;
+ BucketIndex index;
+ for ( index =0; index < ValueInternalLink::itemPerLink; ++index )
+ {
+ if ( link->items_[index].isItemAvailable() )
+ break;
+ }
+ if ( index == ValueInternalLink::itemPerLink ) // need to add a new page
+ {
+ ValueInternalLink *newLink = mapAllocator()->allocateMapLink();
+ index = 0;
+ link->next_ = newLink;
+ previousLink = newLink;
+ link = newLink;
+ }
+ return setNewItem( key, isStatic, link, index );
+}
+
+
+ValueInternalMap::HashKey
+ValueInternalMap::hash( const char *key ) const
+{
+ HashKey hash = 0;
+ while ( *key )
+ hash += *key++ * 37;
+ return hash;
+}
+
+
+int
+ValueInternalMap::compare( const ValueInternalMap &other ) const
+{
+ int sizeDiff( itemCount_ - other.itemCount_ );
+ if ( sizeDiff != 0 )
+ return sizeDiff;
+ // Strict order guaranty is required. Compare all keys FIRST, then compare values.
+ IteratorState it;
+ IteratorState itEnd;
+ makeBeginIterator( it );
+ makeEndIterator( itEnd );
+ for ( ; !equals(it,itEnd); increment(it) )
+ {
+ if ( !other.find( key( it ) ) )
+ return 1;
+ }
+
+ // All keys are equals, let's compare values
+ makeBeginIterator( it );
+ for ( ; !equals(it,itEnd); increment(it) )
+ {
+ const Value *otherValue = other.find( key( it ) );
+ int valueDiff = value(it).compare( *otherValue );
+ if ( valueDiff != 0 )
+ return valueDiff;
+ }
+ return 0;
+}
+
+
+void
+ValueInternalMap::makeBeginIterator( IteratorState &it ) const
+{
+ it.map_ = const_cast<ValueInternalMap *>( this );
+ it.bucketIndex_ = 0;
+ it.itemIndex_ = 0;
+ it.link_ = buckets_;
+}
+
+
+void
+ValueInternalMap::makeEndIterator( IteratorState &it ) const
+{
+ it.map_ = const_cast<ValueInternalMap *>( this );
+ it.bucketIndex_ = bucketsSize_;
+ it.itemIndex_ = 0;
+ it.link_ = 0;
+}
+
+
+bool
+ValueInternalMap::equals( const IteratorState &x, const IteratorState &other )
+{
+ return x.map_ == other.map_
+ && x.bucketIndex_ == other.bucketIndex_
+ && x.link_ == other.link_
+ && x.itemIndex_ == other.itemIndex_;
+}
+
+
+void
+ValueInternalMap::incrementBucket( IteratorState &iterator )
+{
+ ++iterator.bucketIndex_;
+ JSON_ASSERT_MESSAGE( iterator.bucketIndex_ <= iterator.map_->bucketsSize_,
+ "ValueInternalMap::increment(): attempting to iterate beyond end." );
+ if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ )
+ iterator.link_ = 0;
+ else
+ iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]);
+ iterator.itemIndex_ = 0;
+}
+
+
+void
+ValueInternalMap::increment( IteratorState &iterator )
+{
+ JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterator using invalid iterator." );
+ ++iterator.itemIndex_;
+ if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink )
+ {
+ JSON_ASSERT_MESSAGE( iterator.link_ != 0,
+ "ValueInternalMap::increment(): attempting to iterate beyond end." );
+ iterator.link_ = iterator.link_->next_;
+ if ( iterator.link_ == 0 )
+ incrementBucket( iterator );
+ }
+ else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() )
+ {
+ incrementBucket( iterator );
+ }
+}
+
+
+void
+ValueInternalMap::decrement( IteratorState &iterator )
+{
+ if ( iterator.itemIndex_ == 0 )
+ {
+ JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterate using invalid iterator." );
+ if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] )
+ {
+ JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0, "Attempting to iterate beyond beginning." );
+ --(iterator.bucketIndex_);
+ }
+ iterator.link_ = iterator.link_->previous_;
+ iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1;
+ }
+}
+
+
+const char *
+ValueInternalMap::key( const IteratorState &iterator )
+{
+ JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
+ return iterator.link_->keys_[iterator.itemIndex_];
+}
+
+const char *
+ValueInternalMap::key( const IteratorState &iterator, bool &isStatic )
+{
+ JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
+ isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic();
+ return iterator.link_->keys_[iterator.itemIndex_];
+}
+
+
+Value &
+ValueInternalMap::value( const IteratorState &iterator )
+{
+ JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." );
+ return iterator.link_->items_[iterator.itemIndex_];
+}
+
+
+int
+ValueInternalMap::distance( const IteratorState &x, const IteratorState &y )
+{
+ int offset = 0;
+ IteratorState it = x;
+ while ( !equals( it, y ) )
+ increment( it );
+ return offset;
+}
--- /dev/null
+#include <json/reader.h>
+#include <json/value.h>
+#include <utility>
+#include <cstdio>
+#include <cassert>
+#include <cstring>
+#include <iostream>
+#include <stdexcept>
+
+#if _MSC_VER >= 1400 // VC++ 8.0
+#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
+#endif
+
+namespace Json {
+
+// Implementation of class Features
+// ////////////////////////////////
+
+Features::Features()
+ : allowComments_( true )
+ , strictRoot_( false )
+{
+}
+
+
+Features
+Features::all()
+{
+ return Features();
+}
+
+
+Features
+Features::strictMode()
+{
+ Features features;
+ features.allowComments_ = false;
+ features.strictRoot_ = true;
+ return features;
+}
+
+// Implementation of class Reader
+// ////////////////////////////////
+
+
+static inline bool
+in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4 )
+{
+ return c == c1 || c == c2 || c == c3 || c == c4;
+}
+
+static inline bool
+in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4, Reader::Char c5 )
+{
+ return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
+}
+
+
+static bool
+containsNewLine( Reader::Location begin,
+ Reader::Location end )
+{
+ for ( ;begin < end; ++begin )
+ if ( *begin == '\n' || *begin == '\r' )
+ return true;
+ return false;
+}
+
+static std::string codePointToUTF8(unsigned int cp)
+{
+ std::string result;
+
+ // based on description from http://en.wikipedia.org/wiki/UTF-8
+
+ if (cp <= 0x7f)
+ {
+ result.resize(1);
+ result[0] = static_cast<char>(cp);
+ }
+ else if (cp <= 0x7FF)
+ {
+ result.resize(2);
+ result[1] = static_cast<char>(0x80 | (0x3f & cp));
+ result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
+ }
+ else if (cp <= 0xFFFF)
+ {
+ result.resize(3);
+ result[2] = static_cast<char>(0x80 | (0x3f & cp));
+ result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6)));
+ result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12)));
+ }
+ else if (cp <= 0x10FFFF)
+ {
+ result.resize(4);
+ result[3] = static_cast<char>(0x80 | (0x3f & cp));
+ result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
+ result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
+ result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
+ }
+
+ return result;
+}
+
+
+// Class Reader
+// //////////////////////////////////////////////////////////////////
+
+Reader::Reader()
+ : features_( Features::all() )
+{
+}
+
+
+Reader::Reader( const Features &features )
+ : features_( features )
+{
+}
+
+
+bool
+Reader::parse( const std::string &document,
+ Value &root,
+ bool collectComments )
+{
+ document_ = document;
+ const char *begin = document_.c_str();
+ const char *end = begin + document_.length();
+ return parse( begin, end, root, collectComments );
+}
+
+
+bool
+Reader::parse( std::istream& sin,
+ Value &root,
+ bool collectComments )
+{
+ //std::istream_iterator<char> begin(sin);
+ //std::istream_iterator<char> end;
+ // Those would allow streamed input from a file, if parse() were a
+ // template function.
+
+ // Since std::string is reference-counted, this at least does not
+ // create an extra copy.
+ std::string doc;
+ std::getline(sin, doc, (char)EOF);
+ return parse( doc, root, collectComments );
+}
+
+bool
+Reader::parse( const char *beginDoc, const char *endDoc,
+ Value &root,
+ bool collectComments )
+{
+ if ( !features_.allowComments_ )
+ {
+ collectComments = false;
+ }
+
+ begin_ = beginDoc;
+ end_ = endDoc;
+ collectComments_ = collectComments;
+ current_ = begin_;
+ lastValueEnd_ = 0;
+ lastValue_ = 0;
+ commentsBefore_ = "";
+ errors_.clear();
+ while ( !nodes_.empty() )
+ nodes_.pop();
+ nodes_.push( &root );
+
+ bool successful = readValue();
+ Token token;
+ skipCommentTokens( token );
+ if ( collectComments_ && !commentsBefore_.empty() )
+ root.setComment( commentsBefore_, commentAfter );
+ if ( features_.strictRoot_ )
+ {
+ if ( !root.isArray() && !root.isObject() )
+ {
+ // Set error location to start of doc, ideally should be first token found in doc
+ token.type_ = tokenError;
+ token.start_ = beginDoc;
+ token.end_ = endDoc;
+ addError( "A valid JSON document must be either an array or an object value.",
+ token );
+ return false;
+ }
+ }
+ return successful;
+}
+
+
+bool
+Reader::readValue()
+{
+ Token token;
+ skipCommentTokens( token );
+ bool successful = true;
+
+ if ( collectComments_ && !commentsBefore_.empty() )
+ {
+ currentValue().setComment( commentsBefore_, commentBefore );
+ commentsBefore_ = "";
+ }
+
+
+ switch ( token.type_ )
+ {
+ case tokenObjectBegin:
+ successful = readObject( token );
+ break;
+ case tokenArrayBegin:
+ successful = readArray( token );
+ break;
+ case tokenNumber:
+ successful = decodeNumber( token );
+ break;
+ case tokenString:
+ successful = decodeString( token );
+ break;
+ case tokenTrue:
+ currentValue() = true;
+ break;
+ case tokenFalse:
+ currentValue() = false;
+ break;
+ case tokenNull:
+ currentValue() = Value();
+ break;
+ default:
+ return addError( "Syntax error: value, object or array expected.", token );
+ }
+
+ if ( collectComments_ )
+ {
+ lastValueEnd_ = current_;
+ lastValue_ = ¤tValue();
+ }
+
+ return successful;
+}
+
+
+void
+Reader::skipCommentTokens( Token &token )
+{
+ if ( features_.allowComments_ )
+ {
+ do
+ {
+ readToken( token );
+ }
+ while ( token.type_ == tokenComment );
+ }
+ else
+ {
+ readToken( token );
+ }
+}
+
+
+bool
+Reader::expectToken( TokenType type, Token &token, const char *message )
+{
+ readToken( token );
+ if ( token.type_ != type )
+ return addError( message, token );
+ return true;
+}
+
+
+bool
+Reader::readToken( Token &token )
+{
+ skipSpaces();
+ token.start_ = current_;
+ Char c = getNextChar();
+ bool ok = true;
+ switch ( c )
+ {
+ case '{':
+ token.type_ = tokenObjectBegin;
+ break;
+ case '}':
+ token.type_ = tokenObjectEnd;
+ break;
+ case '[':
+ token.type_ = tokenArrayBegin;
+ break;
+ case ']':
+ token.type_ = tokenArrayEnd;
+ break;
+ case '"':
+ token.type_ = tokenString;
+ ok = readString();
+ break;
+ case '/':
+ token.type_ = tokenComment;
+ ok = readComment();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ token.type_ = tokenNumber;
+ readNumber();
+ break;
+ case 't':
+ token.type_ = tokenTrue;
+ ok = match( "rue", 3 );
+ break;
+ case 'f':
+ token.type_ = tokenFalse;
+ ok = match( "alse", 4 );
+ break;
+ case 'n':
+ token.type_ = tokenNull;
+ ok = match( "ull", 3 );
+ break;
+ case ',':
+ token.type_ = tokenArraySeparator;
+ break;
+ case ':':
+ token.type_ = tokenMemberSeparator;
+ break;
+ case 0:
+ token.type_ = tokenEndOfStream;
+ break;
+ default:
+ ok = false;
+ break;
+ }
+ if ( !ok )
+ token.type_ = tokenError;
+ token.end_ = current_;
+ return true;
+}
+
+
+void
+Reader::skipSpaces()
+{
+ while ( current_ != end_ )
+ {
+ Char c = *current_;
+ if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' )
+ ++current_;
+ else
+ break;
+ }
+}
+
+
+bool
+Reader::match( Location pattern,
+ int patternLength )
+{
+ if ( end_ - current_ < patternLength )
+ return false;
+ int index = patternLength;
+ while ( index-- )
+ if ( current_[index] != pattern[index] )
+ return false;
+ current_ += patternLength;
+ return true;
+}
+
+
+bool
+Reader::readComment()
+{
+ Location commentBegin = current_ - 1;
+ Char c = getNextChar();
+ bool successful = false;
+ if ( c == '*' )
+ successful = readCStyleComment();
+ else if ( c == '/' )
+ successful = readCppStyleComment();
+ if ( !successful )
+ return false;
+
+ if ( collectComments_ )
+ {
+ CommentPlacement placement = commentBefore;
+ if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) )
+ {
+ if ( c != '*' || !containsNewLine( commentBegin, current_ ) )
+ placement = commentAfterOnSameLine;
+ }
+
+ addComment( commentBegin, current_, placement );
+ }
+ return true;
+}
+
+
+void
+Reader::addComment( Location begin,
+ Location end,
+ CommentPlacement placement )
+{
+ assert( collectComments_ );
+ if ( placement == commentAfterOnSameLine )
+ {
+ assert( lastValue_ != 0 );
+ lastValue_->setComment( std::string( begin, end ), placement );
+ }
+ else
+ {
+ if ( !commentsBefore_.empty() )
+ commentsBefore_ += "\n";
+ commentsBefore_ += std::string( begin, end );
+ }
+}
+
+
+bool
+Reader::readCStyleComment()
+{
+ while ( current_ != end_ )
+ {
+ Char c = getNextChar();
+ if ( c == '*' && *current_ == '/' )
+ break;
+ }
+ return getNextChar() == '/';
+}
+
+
+bool
+Reader::readCppStyleComment()
+{
+ while ( current_ != end_ )
+ {
+ Char c = getNextChar();
+ if ( c == '\r' || c == '\n' )
+ break;
+ }
+ return true;
+}
+
+
+void
+Reader::readNumber()
+{
+ while ( current_ != end_ )
+ {
+ if ( !(*current_ >= '0' && *current_ <= '9') &&
+ !in( *current_, '.', 'e', 'E', '+', '-' ) )
+ break;
+ ++current_;
+ }
+}
+
+bool
+Reader::readString()
+{
+ Char c = 0;
+ while ( current_ != end_ )
+ {
+ c = getNextChar();
+ if ( c == '\\' )
+ getNextChar();
+ else if ( c == '"' )
+ break;
+ }
+ return c == '"';
+}
+
+
+bool
+Reader::readObject( Token &tokenStart )
+{
+ Token tokenName;
+ std::string name;
+ currentValue() = Value( objectValue );
+ while ( readToken( tokenName ) )
+ {
+ bool initialTokenOk = true;
+ while ( tokenName.type_ == tokenComment && initialTokenOk )
+ initialTokenOk = readToken( tokenName );
+ if ( !initialTokenOk )
+ break;
+ if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object
+ return true;
+ if ( tokenName.type_ != tokenString )
+ break;
+
+ name = "";
+ if ( !decodeString( tokenName, name ) )
+ return recoverFromError( tokenObjectEnd );
+
+ Token colon;
+ if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator )
+ {
+ return addErrorAndRecover( "Missing ':' after object member name",
+ colon,
+ tokenObjectEnd );
+ }
+ Value &value = currentValue()[ name ];
+ nodes_.push( &value );
+ bool ok = readValue();
+ nodes_.pop();
+ if ( !ok ) // error already set
+ return recoverFromError( tokenObjectEnd );
+
+ Token comma;
+ if ( !readToken( comma )
+ || ( comma.type_ != tokenObjectEnd &&
+ comma.type_ != tokenArraySeparator &&
+ comma.type_ != tokenComment ) )
+ {
+ return addErrorAndRecover( "Missing ',' or '}' in object declaration",
+ comma,
+ tokenObjectEnd );
+ }
+ bool finalizeTokenOk = true;
+ while ( comma.type_ == tokenComment &&
+ finalizeTokenOk )
+ finalizeTokenOk = readToken( comma );
+ if ( comma.type_ == tokenObjectEnd )
+ return true;
+ }
+ return addErrorAndRecover( "Missing '}' or object member name",
+ tokenName,
+ tokenObjectEnd );
+}
+
+
+bool
+Reader::readArray( Token &tokenStart )
+{
+ currentValue() = Value( arrayValue );
+ skipSpaces();
+ if ( *current_ == ']' ) // empty array
+ {
+ Token endArray;
+ readToken( endArray );
+ return true;
+ }
+ int index = 0;
+ while ( true )
+ {
+ Value &value = currentValue()[ index++ ];
+ nodes_.push( &value );
+ bool ok = readValue();
+ nodes_.pop();
+ if ( !ok ) // error already set
+ return recoverFromError( tokenArrayEnd );
+
+ Token token;
+ // Accept Comment after last item in the array.
+ ok = readToken( token );
+ while ( token.type_ == tokenComment && ok )
+ {
+ ok = readToken( token );
+ }
+ bool badTokenType = ( token.type_ == tokenArraySeparator &&
+ token.type_ == tokenArrayEnd );
+ if ( !ok || badTokenType )
+ {
+ return addErrorAndRecover( "Missing ',' or ']' in array declaration",
+ token,
+ tokenArrayEnd );
+ }
+ if ( token.type_ == tokenArrayEnd )
+ break;
+ }
+ return true;
+}
+
+
+bool
+Reader::decodeNumber( Token &token )
+{
+ bool isDouble = false;
+ for ( Location inspect = token.start_; inspect != token.end_; ++inspect )
+ {
+ isDouble = isDouble
+ || in( *inspect, '.', 'e', 'E', '+' )
+ || ( *inspect == '-' && inspect != token.start_ );
+ }
+ if ( isDouble )
+ return decodeDouble( token );
+ Location current = token.start_;
+ bool isNegative = *current == '-';
+ if ( isNegative )
+ ++current;
+ Value::UInt threshold = (isNegative ? Value::UInt(-Value::minInt)
+ : Value::maxUInt) / 10;
+ Value::UInt value = 0;
+ while ( current < token.end_ )
+ {
+ Char c = *current++;
+ if ( c < '0' || c > '9' )
+ return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
+ if ( value >= threshold )
+ return decodeDouble( token );
+ value = value * 10 + Value::UInt(c - '0');
+ }
+ if ( isNegative )
+ currentValue() = -Value::Int( value );
+ else if ( value <= Value::UInt(Value::maxInt) )
+ currentValue() = Value::Int( value );
+ else
+ currentValue() = value;
+ return true;
+}
+
+
+bool
+Reader::decodeDouble( Token &token )
+{
+ double value = 0;
+ const int bufferSize = 32;
+ int count;
+ int length = int(token.end_ - token.start_);
+ if ( length <= bufferSize )
+ {
+ Char buffer[bufferSize];
+ memcpy( buffer, token.start_, length );
+ buffer[length] = 0;
+ count = sscanf( buffer, "%lf", &value );
+ }
+ else
+ {
+ std::string buffer( token.start_, token.end_ );
+ count = sscanf( buffer.c_str(), "%lf", &value );
+ }
+
+ if ( count != 1 )
+ return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token );
+ currentValue() = value;
+ return true;
+}
+
+
+bool
+Reader::decodeString( Token &token )
+{
+ std::string decoded;
+ if ( !decodeString( token, decoded ) )
+ return false;
+ currentValue() = decoded;
+ return true;
+}
+
+
+bool
+Reader::decodeString( Token &token, std::string &decoded )
+{
+ decoded.reserve( token.end_ - token.start_ - 2 );
+ Location current = token.start_ + 1; // skip '"'
+ Location end = token.end_ - 1; // do not include '"'
+ while ( current != end )
+ {
+ Char c = *current++;
+ if ( c == '"' )
+ break;
+ else if ( c == '\\' )
+ {
+ if ( current == end )
+ return addError( "Empty escape sequence in string", token, current );
+ Char escape = *current++;
+ switch ( escape )
+ {
+ case '"': decoded += '"'; break;
+ case '/': decoded += '/'; break;
+ case '\\': decoded += '\\'; break;
+ case 'b': decoded += '\b'; break;
+ case 'f': decoded += '\f'; break;
+ case 'n': decoded += '\n'; break;
+ case 'r': decoded += '\r'; break;
+ case 't': decoded += '\t'; break;
+ case 'u':
+ {
+ unsigned int unicode;
+ if ( !decodeUnicodeCodePoint( token, current, end, unicode ) )
+ return false;
+ decoded += codePointToUTF8(unicode);
+ }
+ break;
+ default:
+ return addError( "Bad escape sequence in string", token, current );
+ }
+ }
+ else
+ {
+ decoded += c;
+ }
+ }
+ return true;
+}
+
+bool
+Reader::decodeUnicodeCodePoint( Token &token,
+ Location ¤t,
+ Location end,
+ unsigned int &unicode )
+{
+
+ if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) )
+ return false;
+ if (unicode >= 0xD800 && unicode <= 0xDBFF)
+ {
+ // surrogate pairs
+ if (end - current < 6)
+ return addError( "additional six characters expected to parse unicode surrogate pair.", token, current );
+ unsigned int surrogatePair;
+ if (*(current++) == '\\' && *(current++)== 'u')
+ {
+ if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair ))
+ {
+ unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
+ }
+ else
+ return false;
+ }
+ else
+ return addError( "expecting another \\u token to begin the second half of a unicode surrogate pair", token, current );
+ }
+ return true;
+}
+
+bool
+Reader::decodeUnicodeEscapeSequence( Token &token,
+ Location ¤t,
+ Location end,
+ unsigned int &unicode )
+{
+ if ( end - current < 4 )
+ return addError( "Bad unicode escape sequence in string: four digits expected.", token, current );
+ unicode = 0;
+ for ( int index =0; index < 4; ++index )
+ {
+ Char c = *current++;
+ unicode *= 16;
+ if ( c >= '0' && c <= '9' )
+ unicode += c - '0';
+ else if ( c >= 'a' && c <= 'f' )
+ unicode += c - 'a' + 10;
+ else if ( c >= 'A' && c <= 'F' )
+ unicode += c - 'A' + 10;
+ else
+ return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current );
+ }
+ return true;
+}
+
+
+bool
+Reader::addError( const std::string &message,
+ Token &token,
+ Location extra )
+{
+ ErrorInfo info;
+ info.token_ = token;
+ info.message_ = message;
+ info.extra_ = extra;
+ errors_.push_back( info );
+ return false;
+}
+
+
+bool
+Reader::recoverFromError( TokenType skipUntilToken )
+{
+ int errorCount = int(errors_.size());
+ Token skip;
+ while ( true )
+ {
+ if ( !readToken(skip) )
+ errors_.resize( errorCount ); // discard errors caused by recovery
+ if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream )
+ break;
+ }
+ errors_.resize( errorCount );
+ return false;
+}
+
+
+bool
+Reader::addErrorAndRecover( const std::string &message,
+ Token &token,
+ TokenType skipUntilToken )
+{
+ addError( message, token );
+ return recoverFromError( skipUntilToken );
+}
+
+
+Value &
+Reader::currentValue()
+{
+ return *(nodes_.top());
+}
+
+
+Reader::Char
+Reader::getNextChar()
+{
+ if ( current_ == end_ )
+ return 0;
+ return *current_++;
+}
+
+
+void
+Reader::getLocationLineAndColumn( Location location,
+ int &line,
+ int &column ) const
+{
+ Location current = begin_;
+ Location lastLineStart = current;
+ line = 0;
+ while ( current < location && current != end_ )
+ {
+ Char c = *current++;
+ if ( c == '\r' )
+ {
+ if ( *current == '\n' )
+ ++current;
+ lastLineStart = current;
+ ++line;
+ }
+ else if ( c == '\n' )
+ {
+ lastLineStart = current;
+ ++line;
+ }
+ }
+ // column & line start at 1
+ column = int(location - lastLineStart) + 1;
+ ++line;
+}
+
+
+std::string
+Reader::getLocationLineAndColumn( Location location ) const
+{
+ int line, column;
+ getLocationLineAndColumn( location, line, column );
+ char buffer[18+16+16+1];
+ sprintf( buffer, "Line %d, Column %d", line, column );
+ return buffer;
+}
+
+
+std::string
+Reader::getFormatedErrorMessages() const
+{
+ std::string formattedMessage;
+ for ( Errors::const_iterator itError = errors_.begin();
+ itError != errors_.end();
+ ++itError )
+ {
+ const ErrorInfo &error = *itError;
+ formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n";
+ formattedMessage += " " + error.message_ + "\n";
+ if ( error.extra_ )
+ formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n";
+ }
+ return formattedMessage;
+}
+
+
+std::istream& operator>>( std::istream &sin, Value &root )
+{
+ Json::Reader reader;
+ bool ok = reader.parse(sin, root, true);
+ //JSON_ASSERT( ok );
+ if (!ok) throw std::runtime_error(reader.getFormatedErrorMessages());
+ return sin;
+}
+
+
+} // namespace Json
--- /dev/null
+#include <iostream>
+#include <json/value.h>
+#include <json/writer.h>
+#include <utility>
+#include <stdexcept>
+#include <cstring>
+#include <cassert>
+#ifdef JSON_USE_CPPTL
+# include <cpptl/conststring.h>
+#endif
+#include <cstddef> // size_t
+#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+# include "json_batchallocator.h"
+#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+
+#define JSON_ASSERT_UNREACHABLE assert( false )
+#define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw
+#define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message );
+
+namespace Json {
+
+const Value Value::null;
+const Int Value::minInt = Int( ~(UInt(-1)/2) );
+const Int Value::maxInt = Int( UInt(-1)/2 );
+const UInt Value::maxUInt = UInt(-1);
+
+// A "safe" implementation of strdup. Allow null pointer to be passed.
+// Also avoid warning on msvc80.
+//
+//inline char *safeStringDup( const char *czstring )
+//{
+// if ( czstring )
+// {
+// const size_t length = (unsigned int)( strlen(czstring) + 1 );
+// char *newString = static_cast<char *>( malloc( length ) );
+// memcpy( newString, czstring, length );
+// return newString;
+// }
+// return 0;
+//}
+//
+//inline char *safeStringDup( const std::string &str )
+//{
+// if ( !str.empty() )
+// {
+// const size_t length = str.length();
+// char *newString = static_cast<char *>( malloc( length + 1 ) );
+// memcpy( newString, str.c_str(), length );
+// newString[length] = 0;
+// return newString;
+// }
+// return 0;
+//}
+
+ValueAllocator::~ValueAllocator()
+{
+}
+
+class DefaultValueAllocator : public ValueAllocator
+{
+public:
+ virtual ~DefaultValueAllocator()
+ {
+ }
+
+ virtual char *makeMemberName( const char *memberName )
+ {
+ return duplicateStringValue( memberName );
+ }
+
+ virtual void releaseMemberName( char *memberName )
+ {
+ releaseStringValue( memberName );
+ }
+
+ virtual char *duplicateStringValue( const char *value,
+ unsigned int length = unknown )
+ {
+ //@todo invesgate this old optimization
+ //if ( !value || value[0] == 0 )
+ // return 0;
+
+ if ( length == unknown )
+ length = (unsigned int)strlen(value);
+ char *newString = static_cast<char *>( malloc( length + 1 ) );
+ memcpy( newString, value, length );
+ newString[length] = 0;
+ return newString;
+ }
+
+ virtual void releaseStringValue( char *value )
+ {
+ if ( value )
+ free( value );
+ }
+};
+
+static ValueAllocator *&valueAllocator()
+{
+ static DefaultValueAllocator defaultAllocator;
+ static ValueAllocator *valueAllocator = &defaultAllocator;
+ return valueAllocator;
+}
+
+static struct DummyValueAllocatorInitializer {
+ DummyValueAllocatorInitializer()
+ {
+ valueAllocator(); // ensure valueAllocator() statics are initialized before main().
+ }
+} dummyValueAllocatorInitializer;
+
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// ValueInternals...
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+# include "json_internalarray.inl"
+# include "json_internalmap.inl"
+#endif // JSON_VALUE_USE_INTERNAL_MAP
+
+# include "json_valueiterator.inl"
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::CommentInfo
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+
+Value::CommentInfo::CommentInfo()
+ : comment_( 0 )
+{
+}
+
+Value::CommentInfo::~CommentInfo()
+{
+ if ( comment_ )
+ valueAllocator()->releaseStringValue( comment_ );
+}
+
+
+void
+Value::CommentInfo::setComment( const char *text )
+{
+ if ( comment_ )
+ valueAllocator()->releaseStringValue( comment_ );
+ JSON_ASSERT( text );
+ JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /");
+ // It seems that /**/ style comments are acceptable as well.
+ comment_ = valueAllocator()->duplicateStringValue( text );
+}
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::CZString
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+# ifndef JSON_VALUE_USE_INTERNAL_MAP
+
+// Notes: index_ indicates if the string was allocated when
+// a string is stored.
+
+Value::CZString::CZString( int index )
+ : cstr_( 0 )
+ , index_( index )
+{
+}
+
+Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate )
+ : cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr)
+ : cstr )
+ , index_( allocate )
+{
+}
+
+Value::CZString::CZString( const CZString &other )
+: cstr_( other.index_ != noDuplication && other.cstr_ != 0
+ ? valueAllocator()->makeMemberName( other.cstr_ )
+ : other.cstr_ )
+ , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
+ : other.index_ )
+{
+}
+
+Value::CZString::~CZString()
+{
+ if ( cstr_ && index_ == duplicate )
+ valueAllocator()->releaseMemberName( const_cast<char *>( cstr_ ) );
+}
+
+void
+Value::CZString::swap( CZString &other )
+{
+ std::swap( cstr_, other.cstr_ );
+ std::swap( index_, other.index_ );
+}
+
+Value::CZString &
+Value::CZString::operator =( const CZString &other )
+{
+ CZString temp( other );
+ swap( temp );
+ return *this;
+}
+
+bool
+Value::CZString::operator<( const CZString &other ) const
+{
+ if ( cstr_ )
+ return strcmp( cstr_, other.cstr_ ) < 0;
+ return index_ < other.index_;
+}
+
+bool
+Value::CZString::operator==( const CZString &other ) const
+{
+ if ( cstr_ )
+ return strcmp( cstr_, other.cstr_ ) == 0;
+ return index_ == other.index_;
+}
+
+
+int
+Value::CZString::index() const
+{
+ return index_;
+}
+
+
+const char *
+Value::CZString::c_str() const
+{
+ return cstr_;
+}
+
+bool
+Value::CZString::isStaticString() const
+{
+ return index_ == noDuplication;
+}
+
+#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class Value::Value
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+/*! \internal Default constructor initialization must be equivalent to:
+ * memset( this, 0, sizeof(Value) )
+ * This optimization is used in ValueInternalMap fast allocator.
+ */
+Value::Value( ValueType type )
+ : type_( type )
+ , allocated_( 0 )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ switch ( type )
+ {
+ case nullValue:
+ break;
+ case intValue:
+ case uintValue:
+ value_.int_ = 0;
+ break;
+ case realValue:
+ value_.real_ = 0.0;
+ break;
+ case stringValue:
+ value_.string_ = 0;
+ break;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ value_.map_ = new ObjectValues();
+ break;
+#else
+ case arrayValue:
+ value_.array_ = arrayAllocator()->newArray();
+ break;
+ case objectValue:
+ value_.map_ = mapAllocator()->newMap();
+ break;
+#endif
+ case booleanValue:
+ value_.bool_ = false;
+ break;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+}
+
+
+Value::Value( Int value )
+ : type_( intValue )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.int_ = value;
+}
+
+
+Value::Value( UInt value )
+ : type_( uintValue )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.uint_ = value;
+}
+
+Value::Value( double value )
+ : type_( realValue )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.real_ = value;
+}
+
+Value::Value( const char *value )
+ : type_( stringValue )
+ , allocated_( true )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.string_ = valueAllocator()->duplicateStringValue( value );
+}
+
+
+Value::Value( const char *beginValue,
+ const char *endValue )
+ : type_( stringValue )
+ , allocated_( true )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.string_ = valueAllocator()->duplicateStringValue( beginValue,
+ UInt(endValue - beginValue) );
+}
+
+
+Value::Value( const std::string &value )
+ : type_( stringValue )
+ , allocated_( true )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(),
+ (unsigned int)value.length() );
+
+}
+
+Value::Value( const StaticString &value )
+ : type_( stringValue )
+ , allocated_( false )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.string_ = const_cast<char *>( value.c_str() );
+}
+
+
+# ifdef JSON_USE_CPPTL
+Value::Value( const CppTL::ConstString &value )
+ : type_( stringValue )
+ , allocated_( true )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() );
+}
+# endif
+
+Value::Value( bool value )
+ : type_( booleanValue )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ value_.bool_ = value;
+}
+
+
+Value::Value( const Value &other )
+ : type_( other.type_ )
+ , comments_( 0 )
+# ifdef JSON_VALUE_USE_INTERNAL_MAP
+ , itemIsUsed_( 0 )
+#endif
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ value_ = other.value_;
+ break;
+ case stringValue:
+ if ( other.value_.string_ )
+ {
+ value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ );
+ allocated_ = true;
+ }
+ else
+ value_.string_ = 0;
+ break;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ value_.map_ = new ObjectValues( *other.value_.map_ );
+ break;
+#else
+ case arrayValue:
+ value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ );
+ break;
+ case objectValue:
+ value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ );
+ break;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ if ( other.comments_ )
+ {
+ comments_ = new CommentInfo[numberOfCommentPlacement];
+ for ( int comment =0; comment < numberOfCommentPlacement; ++comment )
+ {
+ const CommentInfo &otherComment = other.comments_[comment];
+ if ( otherComment.comment_ )
+ comments_[comment].setComment( otherComment.comment_ );
+ }
+ }
+}
+
+
+Value::~Value()
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ break;
+ case stringValue:
+ if ( allocated_ )
+ valueAllocator()->releaseStringValue( value_.string_ );
+ break;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ delete value_.map_;
+ break;
+#else
+ case arrayValue:
+ arrayAllocator()->destructArray( value_.array_ );
+ break;
+ case objectValue:
+ mapAllocator()->destructMap( value_.map_ );
+ break;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+
+ if ( comments_ )
+ delete[] comments_;
+}
+
+Value &
+Value::operator=( const Value &other )
+{
+ Value temp( other );
+ swap( temp );
+ return *this;
+}
+
+void
+Value::swap( Value &other )
+{
+ ValueType temp = type_;
+ type_ = other.type_;
+ other.type_ = temp;
+ std::swap( value_, other.value_ );
+ int temp2 = allocated_;
+ allocated_ = other.allocated_;
+ other.allocated_ = temp2;
+}
+
+ValueType
+Value::type() const
+{
+ return type_;
+}
+
+
+int
+Value::compare( const Value &other )
+{
+ /*
+ int typeDelta = other.type_ - type_;
+ switch ( type_ )
+ {
+ case nullValue:
+
+ return other.type_ == type_;
+ case intValue:
+ if ( other.type_.isNumeric()
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ break;
+ case stringValue,
+ break;
+ case arrayValue:
+ delete value_.array_;
+ break;
+ case objectValue:
+ delete value_.map_;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ */
+ return 0; // unreachable
+}
+
+bool
+Value::operator <( const Value &other ) const
+{
+ int typeDelta = type_ - other.type_;
+ if ( typeDelta )
+ return typeDelta < 0 ? true : false;
+ switch ( type_ )
+ {
+ case nullValue:
+ return false;
+ case intValue:
+ return value_.int_ < other.value_.int_;
+ case uintValue:
+ return value_.uint_ < other.value_.uint_;
+ case realValue:
+ return value_.real_ < other.value_.real_;
+ case booleanValue:
+ return value_.bool_ < other.value_.bool_;
+ case stringValue:
+ return ( value_.string_ == 0 && other.value_.string_ )
+ || ( other.value_.string_
+ && value_.string_
+ && strcmp( value_.string_, other.value_.string_ ) < 0 );
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ {
+ int delta = int( value_.map_->size() - other.value_.map_->size() );
+ if ( delta )
+ return delta < 0;
+ return (*value_.map_) < (*other.value_.map_);
+ }
+#else
+ case arrayValue:
+ return value_.array_->compare( *(other.value_.array_) ) < 0;
+ case objectValue:
+ return value_.map_->compare( *(other.value_.map_) ) < 0;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return 0; // unreachable
+}
+
+bool
+Value::operator <=( const Value &other ) const
+{
+ return !(other > *this);
+}
+
+bool
+Value::operator >=( const Value &other ) const
+{
+ return !(*this < other);
+}
+
+bool
+Value::operator >( const Value &other ) const
+{
+ return other < *this;
+}
+
+bool
+Value::operator ==( const Value &other ) const
+{
+ //if ( type_ != other.type_ )
+ // GCC 2.95.3 says:
+ // attempt to take address of bit-field structure member `Json::Value::type_'
+ // Beats me, but a temp solves the problem.
+ int temp = other.type_;
+ if ( type_ != temp )
+ return false;
+ switch ( type_ )
+ {
+ case nullValue:
+ return true;
+ case intValue:
+ return value_.int_ == other.value_.int_;
+ case uintValue:
+ return value_.uint_ == other.value_.uint_;
+ case realValue:
+ return value_.real_ == other.value_.real_;
+ case booleanValue:
+ return value_.bool_ == other.value_.bool_;
+ case stringValue:
+ return ( value_.string_ == other.value_.string_ )
+ || ( other.value_.string_
+ && value_.string_
+ && strcmp( value_.string_, other.value_.string_ ) == 0 );
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ return value_.map_->size() == other.value_.map_->size()
+ && (*value_.map_) == (*other.value_.map_);
+#else
+ case arrayValue:
+ return value_.array_->compare( *(other.value_.array_) ) == 0;
+ case objectValue:
+ return value_.map_->compare( *(other.value_.map_) ) == 0;
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return 0; // unreachable
+}
+
+bool
+Value::operator !=( const Value &other ) const
+{
+ return !( *this == other );
+}
+
+const char *
+Value::asCString() const
+{
+ JSON_ASSERT( type_ == stringValue );
+ return value_.string_;
+}
+
+
+std::string
+Value::asString() const
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ return "";
+ case stringValue:
+ return value_.string_ ? value_.string_ : "";
+ case booleanValue:
+ return value_.bool_ ? "true" : "false";
+ case intValue:
+ case uintValue:
+ case realValue:
+ case arrayValue:
+ case objectValue:
+ JSON_ASSERT_MESSAGE( false, "Type is not convertible to string" );
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return ""; // unreachable
+}
+
+# ifdef JSON_USE_CPPTL
+CppTL::ConstString
+Value::asConstString() const
+{
+ return CppTL::ConstString( asString().c_str() );
+}
+# endif
+
+Value::Int
+Value::asInt() const
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ return 0;
+ case intValue:
+ return value_.int_;
+ case uintValue:
+ JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" );
+ return value_.uint_;
+ case realValue:
+ JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" );
+ return Int( value_.real_ );
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ case stringValue:
+ case arrayValue:
+ case objectValue:
+ JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" );
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return 0; // unreachable;
+}
+
+Value::UInt
+Value::asUInt() const
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ return 0;
+ case intValue:
+ JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" );
+ return value_.int_;
+ case uintValue:
+ return value_.uint_;
+ case realValue:
+ JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" );
+ return UInt( value_.real_ );
+ case booleanValue:
+ return value_.bool_ ? 1 : 0;
+ case stringValue:
+ case arrayValue:
+ case objectValue:
+ JSON_ASSERT_MESSAGE( false, "Type is not convertible to uint" );
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return 0; // unreachable;
+}
+
+double
+Value::asDouble() const
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ return 0.0;
+ case intValue:
+ return value_.int_;
+ case uintValue:
+ return value_.uint_;
+ case realValue:
+ return value_.real_;
+ case booleanValue:
+ return value_.bool_ ? 1.0 : 0.0;
+ case stringValue:
+ case arrayValue:
+ case objectValue:
+ JSON_ASSERT_MESSAGE( false, "Type is not convertible to double" );
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return 0; // unreachable;
+}
+
+bool
+Value::asBool() const
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ return false;
+ case intValue:
+ case uintValue:
+ return value_.int_ != 0;
+ case realValue:
+ return value_.real_ != 0.0;
+ case booleanValue:
+ return value_.bool_;
+ case stringValue:
+ return value_.string_ && value_.string_[0] != 0;
+ case arrayValue:
+ case objectValue:
+ return value_.map_->size() != 0;
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return false; // unreachable;
+}
+
+
+bool
+Value::isConvertibleTo( ValueType other ) const
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ return true;
+ case intValue:
+ return ( other == nullValue && value_.int_ == 0 )
+ || other == intValue
+ || ( other == uintValue && value_.int_ >= 0 )
+ || other == realValue
+ || other == stringValue
+ || other == booleanValue;
+ case uintValue:
+ return ( other == nullValue && value_.uint_ == 0 )
+ || ( other == intValue && value_.uint_ <= (unsigned)maxInt )
+ || other == uintValue
+ || other == realValue
+ || other == stringValue
+ || other == booleanValue;
+ case realValue:
+ return ( other == nullValue && value_.real_ == 0.0 )
+ || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt )
+ || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt )
+ || other == realValue
+ || other == stringValue
+ || other == booleanValue;
+ case booleanValue:
+ return ( other == nullValue && value_.bool_ == false )
+ || other == intValue
+ || other == uintValue
+ || other == realValue
+ || other == stringValue
+ || other == booleanValue;
+ case stringValue:
+ return other == stringValue
+ || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) );
+ case arrayValue:
+ return other == arrayValue
+ || ( other == nullValue && value_.map_->size() == 0 );
+ case objectValue:
+ return other == objectValue
+ || ( other == nullValue && value_.map_->size() == 0 );
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return false; // unreachable;
+}
+
+
+/// Number of values in array or object
+Value::UInt
+Value::size() const
+{
+ switch ( type_ )
+ {
+ case nullValue:
+ case intValue:
+ case uintValue:
+ case realValue:
+ case booleanValue:
+ case stringValue:
+ return 0;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue: // size of the array is highest index + 1
+ if ( !value_.map_->empty() )
+ {
+ ObjectValues::const_iterator itLast = value_.map_->end();
+ --itLast;
+ return (*itLast).first.index()+1;
+ }
+ return 0;
+ case objectValue:
+ return Int( value_.map_->size() );
+#else
+ case arrayValue:
+ return Int( value_.array_->size() );
+ case objectValue:
+ return Int( value_.map_->size() );
+#endif
+ default:
+ JSON_ASSERT_UNREACHABLE;
+ }
+ return 0; // unreachable;
+}
+
+
+bool
+Value::empty() const
+{
+ if ( isNull() || isArray() || isObject() )
+ return size() == 0u;
+ else
+ return false;
+}
+
+
+bool
+Value::operator!() const
+{
+ return isNull();
+}
+
+
+void
+Value::clear()
+{
+ JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue );
+
+ switch ( type_ )
+ {
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ case objectValue:
+ value_.map_->clear();
+ break;
+#else
+ case arrayValue:
+ value_.array_->clear();
+ break;
+ case objectValue:
+ value_.map_->clear();
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+void
+Value::resize( UInt newSize )
+{
+ JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
+ if ( type_ == nullValue )
+ *this = Value( arrayValue );
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ UInt oldSize = size();
+ if ( newSize == 0 )
+ clear();
+ else if ( newSize > oldSize )
+ (*this)[ newSize - 1 ];
+ else
+ {
+ for ( UInt index = newSize; index < oldSize; ++index )
+ value_.map_->erase( index );
+ assert( size() == newSize );
+ }
+#else
+ value_.array_->resize( newSize );
+#endif
+}
+
+
+Value &
+Value::operator[]( UInt index )
+{
+ JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
+ if ( type_ == nullValue )
+ *this = Value( arrayValue );
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString key( index );
+ ObjectValues::iterator it = value_.map_->lower_bound( key );
+ if ( it != value_.map_->end() && (*it).first == key )
+ return (*it).second;
+
+ ObjectValues::value_type defaultValue( key, null );
+ it = value_.map_->insert( it, defaultValue );
+ return (*it).second;
+#else
+ return value_.array_->resolveReference( index );
+#endif
+}
+
+
+const Value &
+Value::operator[]( UInt index ) const
+{
+ JSON_ASSERT( type_ == nullValue || type_ == arrayValue );
+ if ( type_ == nullValue )
+ return null;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString key( index );
+ ObjectValues::const_iterator it = value_.map_->find( key );
+ if ( it == value_.map_->end() )
+ return null;
+ return (*it).second;
+#else
+ Value *value = value_.array_->find( index );
+ return value ? *value : null;
+#endif
+}
+
+
+Value &
+Value::operator[]( const char *key )
+{
+ return resolveReference( key, false );
+}
+
+
+Value &
+Value::resolveReference( const char *key,
+ bool isStatic )
+{
+ JSON_ASSERT( type_ == nullValue || type_ == objectValue );
+ if ( type_ == nullValue )
+ *this = Value( objectValue );
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString actualKey( key, isStatic ? CZString::noDuplication
+ : CZString::duplicateOnCopy );
+ ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
+ if ( it != value_.map_->end() && (*it).first == actualKey )
+ return (*it).second;
+
+ ObjectValues::value_type defaultValue( actualKey, null );
+ it = value_.map_->insert( it, defaultValue );
+ Value &value = (*it).second;
+ return value;
+#else
+ return value_.map_->resolveReference( key, isStatic );
+#endif
+}
+
+
+Value
+Value::get( UInt index,
+ const Value &defaultValue ) const
+{
+ const Value *value = &((*this)[index]);
+ return value == &null ? defaultValue : *value;
+}
+
+
+bool
+Value::isValidIndex( UInt index ) const
+{
+ return index < size();
+}
+
+
+
+const Value &
+Value::operator[]( const char *key ) const
+{
+ JSON_ASSERT( type_ == nullValue || type_ == objectValue );
+ if ( type_ == nullValue )
+ return null;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString actualKey( key, CZString::noDuplication );
+ ObjectValues::const_iterator it = value_.map_->find( actualKey );
+ if ( it == value_.map_->end() )
+ return null;
+ return (*it).second;
+#else
+ const Value *value = value_.map_->find( key );
+ return value ? *value : null;
+#endif
+}
+
+
+Value &
+Value::operator[]( const std::string &key )
+{
+ return (*this)[ key.c_str() ];
+}
+
+
+const Value &
+Value::operator[]( const std::string &key ) const
+{
+ return (*this)[ key.c_str() ];
+}
+
+Value &
+Value::operator[]( const StaticString &key )
+{
+ return resolveReference( key, true );
+}
+
+
+# ifdef JSON_USE_CPPTL
+Value &
+Value::operator[]( const CppTL::ConstString &key )
+{
+ return (*this)[ key.c_str() ];
+}
+
+
+const Value &
+Value::operator[]( const CppTL::ConstString &key ) const
+{
+ return (*this)[ key.c_str() ];
+}
+# endif
+
+
+Value &
+Value::append( const Value &value )
+{
+ return (*this)[size()] = value;
+}
+
+
+Value
+Value::get( const char *key,
+ const Value &defaultValue ) const
+{
+ const Value *value = &((*this)[key]);
+ return value == &null ? defaultValue : *value;
+}
+
+
+Value
+Value::get( const std::string &key,
+ const Value &defaultValue ) const
+{
+ return get( key.c_str(), defaultValue );
+}
+
+Value
+Value::removeMember( const char* key )
+{
+ JSON_ASSERT( type_ == nullValue || type_ == objectValue );
+ if ( type_ == nullValue )
+ return null;
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ CZString actualKey( key, CZString::noDuplication );
+ ObjectValues::iterator it = value_.map_->find( actualKey );
+ if ( it == value_.map_->end() )
+ return null;
+ Value old(it->second);
+ value_.map_->erase(it);
+ return old;
+#else
+ Value *value = value_.map_->find( key );
+ if (value){
+ Value old(*value);
+ value_.map_.remove( key );
+ return old;
+ } else {
+ return null;
+ }
+#endif
+}
+
+Value
+Value::removeMember( const std::string &key )
+{
+ return removeMember( key.c_str() );
+}
+
+# ifdef JSON_USE_CPPTL
+Value
+Value::get( const CppTL::ConstString &key,
+ const Value &defaultValue ) const
+{
+ return get( key.c_str(), defaultValue );
+}
+# endif
+
+bool
+Value::isMember( const char *key ) const
+{
+ const Value *value = &((*this)[key]);
+ return value != &null;
+}
+
+
+bool
+Value::isMember( const std::string &key ) const
+{
+ return isMember( key.c_str() );
+}
+
+
+# ifdef JSON_USE_CPPTL
+bool
+Value::isMember( const CppTL::ConstString &key ) const
+{
+ return isMember( key.c_str() );
+}
+#endif
+
+Value::Members
+Value::getMemberNames() const
+{
+ JSON_ASSERT( type_ == nullValue || type_ == objectValue );
+ if ( type_ == nullValue )
+ return Value::Members();
+ Members members;
+ members.reserve( value_.map_->size() );
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ ObjectValues::const_iterator it = value_.map_->begin();
+ ObjectValues::const_iterator itEnd = value_.map_->end();
+ for ( ; it != itEnd; ++it )
+ members.push_back( std::string( (*it).first.c_str() ) );
+#else
+ ValueInternalMap::IteratorState it;
+ ValueInternalMap::IteratorState itEnd;
+ value_.map_->makeBeginIterator( it );
+ value_.map_->makeEndIterator( itEnd );
+ for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) )
+ members.push_back( std::string( ValueInternalMap::key( it ) ) );
+#endif
+ return members;
+}
+//
+//# ifdef JSON_USE_CPPTL
+//EnumMemberNames
+//Value::enumMemberNames() const
+//{
+// if ( type_ == objectValue )
+// {
+// return CppTL::Enum::any( CppTL::Enum::transform(
+// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
+// MemberNamesTransform() ) );
+// }
+// return EnumMemberNames();
+//}
+//
+//
+//EnumValues
+//Value::enumValues() const
+//{
+// if ( type_ == objectValue || type_ == arrayValue )
+// return CppTL::Enum::anyValues( *(value_.map_),
+// CppTL::Type<const Value &>() );
+// return EnumValues();
+//}
+//
+//# endif
+
+
+bool
+Value::isNull() const
+{
+ return type_ == nullValue;
+}
+
+
+bool
+Value::isBool() const
+{
+ return type_ == booleanValue;
+}
+
+
+bool
+Value::isInt() const
+{
+ return type_ == intValue;
+}
+
+
+bool
+Value::isUInt() const
+{
+ return type_ == uintValue;
+}
+
+
+bool
+Value::isIntegral() const
+{
+ return type_ == intValue
+ || type_ == uintValue
+ || type_ == booleanValue;
+}
+
+
+bool
+Value::isDouble() const
+{
+ return type_ == realValue;
+}
+
+
+bool
+Value::isNumeric() const
+{
+ return isIntegral() || isDouble();
+}
+
+
+bool
+Value::isString() const
+{
+ return type_ == stringValue;
+}
+
+
+bool
+Value::isArray() const
+{
+ return type_ == nullValue || type_ == arrayValue;
+}
+
+
+bool
+Value::isObject() const
+{
+ return type_ == nullValue || type_ == objectValue;
+}
+
+
+void
+Value::setComment( const char *comment,
+ CommentPlacement placement )
+{
+ if ( !comments_ )
+ comments_ = new CommentInfo[numberOfCommentPlacement];
+ comments_[placement].setComment( comment );
+}
+
+
+void
+Value::setComment( const std::string &comment,
+ CommentPlacement placement )
+{
+ setComment( comment.c_str(), placement );
+}
+
+
+bool
+Value::hasComment( CommentPlacement placement ) const
+{
+ return comments_ != 0 && comments_[placement].comment_ != 0;
+}
+
+std::string
+Value::getComment( CommentPlacement placement ) const
+{
+ if ( hasComment(placement) )
+ return comments_[placement].comment_;
+ return "";
+}
+
+
+std::string
+Value::toStyledString() const
+{
+ StyledWriter writer;
+ return writer.write( *this );
+}
+
+
+Value::const_iterator
+Value::begin() const
+{
+ switch ( type_ )
+ {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if ( value_.array_ )
+ {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeBeginIterator( it );
+ return const_iterator( it );
+ }
+ break;
+ case objectValue:
+ if ( value_.map_ )
+ {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeBeginIterator( it );
+ return const_iterator( it );
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if ( value_.map_ )
+ return const_iterator( value_.map_->begin() );
+ break;
+#endif
+ default:
+ break;
+ }
+ return const_iterator();
+}
+
+Value::const_iterator
+Value::end() const
+{
+ switch ( type_ )
+ {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if ( value_.array_ )
+ {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeEndIterator( it );
+ return const_iterator( it );
+ }
+ break;
+ case objectValue:
+ if ( value_.map_ )
+ {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeEndIterator( it );
+ return const_iterator( it );
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if ( value_.map_ )
+ return const_iterator( value_.map_->end() );
+ break;
+#endif
+ default:
+ break;
+ }
+ return const_iterator();
+}
+
+
+Value::iterator
+Value::begin()
+{
+ switch ( type_ )
+ {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if ( value_.array_ )
+ {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeBeginIterator( it );
+ return iterator( it );
+ }
+ break;
+ case objectValue:
+ if ( value_.map_ )
+ {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeBeginIterator( it );
+ return iterator( it );
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if ( value_.map_ )
+ return iterator( value_.map_->begin() );
+ break;
+#endif
+ default:
+ break;
+ }
+ return iterator();
+}
+
+Value::iterator
+Value::end()
+{
+ switch ( type_ )
+ {
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+ case arrayValue:
+ if ( value_.array_ )
+ {
+ ValueInternalArray::IteratorState it;
+ value_.array_->makeEndIterator( it );
+ return iterator( it );
+ }
+ break;
+ case objectValue:
+ if ( value_.map_ )
+ {
+ ValueInternalMap::IteratorState it;
+ value_.map_->makeEndIterator( it );
+ return iterator( it );
+ }
+ break;
+#else
+ case arrayValue:
+ case objectValue:
+ if ( value_.map_ )
+ return iterator( value_.map_->end() );
+ break;
+#endif
+ default:
+ break;
+ }
+ return iterator();
+}
+
+
+// class PathArgument
+// //////////////////////////////////////////////////////////////////
+
+PathArgument::PathArgument()
+ : kind_( kindNone )
+{
+}
+
+
+PathArgument::PathArgument( Value::UInt index )
+ : index_( index )
+ , kind_( kindIndex )
+{
+}
+
+
+PathArgument::PathArgument( const char *key )
+ : key_( key )
+ , kind_( kindKey )
+{
+}
+
+
+PathArgument::PathArgument( const std::string &key )
+ : key_( key.c_str() )
+ , kind_( kindKey )
+{
+}
+
+// class Path
+// //////////////////////////////////////////////////////////////////
+
+Path::Path( const std::string &path,
+ const PathArgument &a1,
+ const PathArgument &a2,
+ const PathArgument &a3,
+ const PathArgument &a4,
+ const PathArgument &a5 )
+{
+ InArgs in;
+ in.push_back( &a1 );
+ in.push_back( &a2 );
+ in.push_back( &a3 );
+ in.push_back( &a4 );
+ in.push_back( &a5 );
+ makePath( path, in );
+}
+
+
+void
+Path::makePath( const std::string &path,
+ const InArgs &in )
+{
+ const char *current = path.c_str();
+ const char *end = current + path.length();
+ InArgs::const_iterator itInArg = in.begin();
+ while ( current != end )
+ {
+ if ( *current == '[' )
+ {
+ ++current;
+ if ( *current == '%' )
+ addPathInArg( path, in, itInArg, PathArgument::kindIndex );
+ else
+ {
+ Value::UInt index = 0;
+ for ( ; current != end && *current >= '0' && *current <= '9'; ++current )
+ index = index * 10 + Value::UInt(*current - '0');
+ args_.push_back( index );
+ }
+ if ( current == end || *current++ != ']' )
+ invalidPath( path, int(current - path.c_str()) );
+ }
+ else if ( *current == '%' )
+ {
+ addPathInArg( path, in, itInArg, PathArgument::kindKey );
+ ++current;
+ }
+ else if ( *current == '.' )
+ {
+ ++current;
+ }
+ else
+ {
+ const char *beginName = current;
+ while ( current != end && !strchr( "[.", *current ) )
+ ++current;
+ args_.push_back( std::string( beginName, current ) );
+ }
+ }
+}
+
+
+void
+Path::addPathInArg( const std::string &path,
+ const InArgs &in,
+ InArgs::const_iterator &itInArg,
+ PathArgument::Kind kind )
+{
+ if ( itInArg == in.end() )
+ {
+ // Error: missing argument %d
+ }
+ else if ( (*itInArg)->kind_ != kind )
+ {
+ // Error: bad argument type
+ }
+ else
+ {
+ args_.push_back( **itInArg );
+ }
+}
+
+
+void
+Path::invalidPath( const std::string &path,
+ int location )
+{
+ // Error: invalid path.
+}
+
+
+const Value &
+Path::resolve( const Value &root ) const
+{
+ const Value *node = &root;
+ for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
+ {
+ const PathArgument &arg = *it;
+ if ( arg.kind_ == PathArgument::kindIndex )
+ {
+ if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
+ {
+ // Error: unable to resolve path (array value expected at position...
+ }
+ node = &((*node)[arg.index_]);
+ }
+ else if ( arg.kind_ == PathArgument::kindKey )
+ {
+ if ( !node->isObject() )
+ {
+ // Error: unable to resolve path (object value expected at position...)
+ }
+ node = &((*node)[arg.key_]);
+ if ( node == &Value::null )
+ {
+ // Error: unable to resolve path (object has no member named '' at position...)
+ }
+ }
+ }
+ return *node;
+}
+
+
+Value
+Path::resolve( const Value &root,
+ const Value &defaultValue ) const
+{
+ const Value *node = &root;
+ for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
+ {
+ const PathArgument &arg = *it;
+ if ( arg.kind_ == PathArgument::kindIndex )
+ {
+ if ( !node->isArray() || node->isValidIndex( arg.index_ ) )
+ return defaultValue;
+ node = &((*node)[arg.index_]);
+ }
+ else if ( arg.kind_ == PathArgument::kindKey )
+ {
+ if ( !node->isObject() )
+ return defaultValue;
+ node = &((*node)[arg.key_]);
+ if ( node == &Value::null )
+ return defaultValue;
+ }
+ }
+ return *node;
+}
+
+
+Value &
+Path::make( Value &root ) const
+{
+ Value *node = &root;
+ for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it )
+ {
+ const PathArgument &arg = *it;
+ if ( arg.kind_ == PathArgument::kindIndex )
+ {
+ if ( !node->isArray() )
+ {
+ // Error: node is not an array at position ...
+ }
+ node = &((*node)[arg.index_]);
+ }
+ else if ( arg.kind_ == PathArgument::kindKey )
+ {
+ if ( !node->isObject() )
+ {
+ // Error: node is not an object at position...
+ }
+ node = &((*node)[arg.key_]);
+ }
+ }
+ return *node;
+}
+
+
+} // namespace Json
--- /dev/null
+// included by json_value.cpp
+// everything is within Json namespace
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueIteratorBase
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueIteratorBase::ValueIteratorBase()
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ : current_()
+ , isNull_( true )
+{
+}
+#else
+ : isArray_( true )
+ , isNull_( true )
+{
+ iterator_.array_ = ValueInternalArray::IteratorState();
+}
+#endif
+
+
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator ¤t )
+ : current_( current )
+ , isNull_( false )
+{
+}
+#else
+ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state )
+ : isArray_( true )
+{
+ iterator_.array_ = state;
+}
+
+
+ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state )
+ : isArray_( false )
+{
+ iterator_.map_ = state;
+}
+#endif
+
+Value &
+ValueIteratorBase::deref() const
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ return current_->second;
+#else
+ if ( isArray_ )
+ return ValueInternalArray::dereference( iterator_.array_ );
+ return ValueInternalMap::value( iterator_.map_ );
+#endif
+}
+
+
+void
+ValueIteratorBase::increment()
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ ++current_;
+#else
+ if ( isArray_ )
+ ValueInternalArray::increment( iterator_.array_ );
+ ValueInternalMap::increment( iterator_.map_ );
+#endif
+}
+
+
+void
+ValueIteratorBase::decrement()
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ --current_;
+#else
+ if ( isArray_ )
+ ValueInternalArray::decrement( iterator_.array_ );
+ ValueInternalMap::decrement( iterator_.map_ );
+#endif
+}
+
+
+ValueIteratorBase::difference_type
+ValueIteratorBase::computeDistance( const SelfType &other ) const
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+# ifdef JSON_USE_CPPTL_SMALLMAP
+ return current_ - other.current_;
+# else
+ // Iterator for null value are initialized using the default
+ // constructor, which initialize current_ to the default
+ // std::map::iterator. As begin() and end() are two instance
+ // of the default std::map::iterator, they can not be compared.
+ // To allow this, we handle this comparison specifically.
+ if ( isNull_ && other.isNull_ )
+ {
+ return 0;
+ }
+
+
+ // Usage of std::distance is not portable (does not compile with Sun Studio 12 RogueWave STL,
+ // which is the one used by default).
+ // Using a portable hand-made version for non random iterator instead:
+ // return difference_type( std::distance( current_, other.current_ ) );
+ difference_type myDistance = 0;
+ for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it )
+ {
+ ++myDistance;
+ }
+ return myDistance;
+# endif
+#else
+ if ( isArray_ )
+ return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ );
+ return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ );
+#endif
+}
+
+
+bool
+ValueIteratorBase::isEqual( const SelfType &other ) const
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ if ( isNull_ )
+ {
+ return other.isNull_;
+ }
+ return current_ == other.current_;
+#else
+ if ( isArray_ )
+ return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ );
+ return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ );
+#endif
+}
+
+
+void
+ValueIteratorBase::copy( const SelfType &other )
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ current_ = other.current_;
+#else
+ if ( isArray_ )
+ iterator_.array_ = other.iterator_.array_;
+ iterator_.map_ = other.iterator_.map_;
+#endif
+}
+
+
+Value
+ValueIteratorBase::key() const
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ const Value::CZString czstring = (*current_).first;
+ if ( czstring.c_str() )
+ {
+ if ( czstring.isStaticString() )
+ return Value( StaticString( czstring.c_str() ) );
+ return Value( czstring.c_str() );
+ }
+ return Value( czstring.index() );
+#else
+ if ( isArray_ )
+ return Value( ValueInternalArray::indexOf( iterator_.array_ ) );
+ bool isStatic;
+ const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic );
+ if ( isStatic )
+ return Value( StaticString( memberName ) );
+ return Value( memberName );
+#endif
+}
+
+
+UInt
+ValueIteratorBase::index() const
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ const Value::CZString czstring = (*current_).first;
+ if ( !czstring.c_str() )
+ return czstring.index();
+ return Value::UInt( -1 );
+#else
+ if ( isArray_ )
+ return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) );
+ return Value::UInt( -1 );
+#endif
+}
+
+
+const char *
+ValueIteratorBase::memberName() const
+{
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ const char *name = (*current_).first.c_str();
+ return name ? name : "";
+#else
+ if ( !isArray_ )
+ return ValueInternalMap::key( iterator_.map_ );
+ return "";
+#endif
+}
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueConstIterator
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueConstIterator::ValueConstIterator()
+{
+}
+
+
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator ¤t )
+ : ValueIteratorBase( current )
+{
+}
+#else
+ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state )
+ : ValueIteratorBase( state )
+{
+}
+
+ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state )
+ : ValueIteratorBase( state )
+{
+}
+#endif
+
+ValueConstIterator &
+ValueConstIterator::operator =( const ValueIteratorBase &other )
+{
+ copy( other );
+ return *this;
+}
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueIterator
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueIterator::ValueIterator()
+{
+}
+
+
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ValueIterator::ValueIterator( const Value::ObjectValues::iterator ¤t )
+ : ValueIteratorBase( current )
+{
+}
+#else
+ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state )
+ : ValueIteratorBase( state )
+{
+}
+
+ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state )
+ : ValueIteratorBase( state )
+{
+}
+#endif
+
+ValueIterator::ValueIterator( const ValueConstIterator &other )
+ : ValueIteratorBase( other )
+{
+}
+
+ValueIterator::ValueIterator( const ValueIterator &other )
+ : ValueIteratorBase( other )
+{
+}
+
+ValueIterator &
+ValueIterator::operator =( const SelfType &other )
+{
+ copy( other );
+ return *this;
+}
--- /dev/null
+#include <json/writer.h>
+#include <utility>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+#if _MSC_VER >= 1400 // VC++ 8.0
+#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated.
+#endif
+
+namespace Json {
+
+static bool isControlCharacter(char ch)
+{
+ return ch > 0 && ch <= 0x1F;
+}
+
+static bool containsControlCharacter( const char* str )
+{
+ while ( *str )
+ {
+ if ( isControlCharacter( *(str++) ) )
+ return true;
+ }
+ return false;
+}
+static void uintToString( unsigned int value,
+ char *¤t )
+{
+ *--current = 0;
+ do
+ {
+ *--current = (value % 10) + '0';
+ value /= 10;
+ }
+ while ( value != 0 );
+}
+
+std::string valueToString( Int value )
+{
+ char buffer[32];
+ char *current = buffer + sizeof(buffer);
+ bool isNegative = value < 0;
+ if ( isNegative )
+ value = -value;
+ uintToString( UInt(value), current );
+ if ( isNegative )
+ *--current = '-';
+ assert( current >= buffer );
+ return current;
+}
+
+
+std::string valueToString( UInt value )
+{
+ char buffer[32];
+ char *current = buffer + sizeof(buffer);
+ uintToString( value, current );
+ assert( current >= buffer );
+ return current;
+}
+
+std::string valueToString( double value )
+{
+ char buffer[32];
+#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning.
+ sprintf_s(buffer, sizeof(buffer), "%#.16g", value);
+#else
+ sprintf(buffer, "%#.16g", value);
+#endif
+ char* ch = buffer + strlen(buffer) - 1;
+ if (*ch != '0') return buffer; // nothing to truncate, so save time
+ while(ch > buffer && *ch == '0'){
+ --ch;
+ }
+ char* last_nonzero = ch;
+ while(ch >= buffer){
+ switch(*ch){
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ --ch;
+ continue;
+ case '.':
+ // Truncate zeroes to save bytes in output, but keep one.
+ *(last_nonzero+2) = '\0';
+ return buffer;
+ default:
+ return buffer;
+ }
+ }
+ return buffer;
+}
+
+
+std::string valueToString( bool value )
+{
+ return value ? "true" : "false";
+}
+
+std::string valueToQuotedString( const char *value )
+{
+ // Not sure how to handle unicode...
+ if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value ))
+ return std::string("\"") + value + "\"";
+ // We have to walk value and escape any special characters.
+ // Appending to std::string is not efficient, but this should be rare.
+ // (Note: forward slashes are *not* rare, but I am not escaping them.)
+ unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL
+ std::string result;
+ result.reserve(maxsize); // to avoid lots of mallocs
+ result += "\"";
+ for (const char* c=value; *c != 0; ++c)
+ {
+ switch(*c)
+ {
+ case '\"':
+ result += "\\\"";
+ break;
+ case '\\':
+ result += "\\\\";
+ break;
+ case '\b':
+ result += "\\b";
+ break;
+ case '\f':
+ result += "\\f";
+ break;
+ case '\n':
+ result += "\\n";
+ break;
+ case '\r':
+ result += "\\r";
+ break;
+ case '\t':
+ result += "\\t";
+ break;
+ //case '/':
+ // Even though \/ is considered a legal escape in JSON, a bare
+ // slash is also legal, so I see no reason to escape it.
+ // (I hope I am not misunderstanding something.
+ // blep notes: actually escaping \/ may be useful in javascript to avoid </
+ // sequence.
+ // Should add a flag to allow this compatibility mode and prevent this
+ // sequence from occurring.
+ default:
+ if ( isControlCharacter( *c ) )
+ {
+ std::ostringstream oss;
+ oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c);
+ result += oss.str();
+ }
+ else
+ {
+ result += *c;
+ }
+ break;
+ }
+ }
+ result += "\"";
+ return result;
+}
+
+// Class Writer
+// //////////////////////////////////////////////////////////////////
+Writer::~Writer()
+{
+}
+
+
+// Class FastWriter
+// //////////////////////////////////////////////////////////////////
+
+FastWriter::FastWriter()
+ : yamlCompatiblityEnabled_( false )
+{
+}
+
+
+void
+FastWriter::enableYAMLCompatibility()
+{
+ yamlCompatiblityEnabled_ = true;
+}
+
+
+std::string
+FastWriter::write( const Value &root )
+{
+ document_ = "";
+ writeValue( root );
+ document_ += "\n";
+ return document_;
+}
+
+
+void
+FastWriter::writeValue( const Value &value )
+{
+ switch ( value.type() )
+ {
+ case nullValue:
+ document_ += "null";
+ break;
+ case intValue:
+ document_ += valueToString( value.asInt() );
+ break;
+ case uintValue:
+ document_ += valueToString( value.asUInt() );
+ break;
+ case realValue:
+ document_ += valueToString( value.asDouble() );
+ break;
+ case stringValue:
+ document_ += valueToQuotedString( value.asCString() );
+ break;
+ case booleanValue:
+ document_ += valueToString( value.asBool() );
+ break;
+ case arrayValue:
+ {
+ document_ += "[";
+ int size = value.size();
+ for ( int index =0; index < size; ++index )
+ {
+ if ( index > 0 )
+ document_ += ",";
+ writeValue( value[index] );
+ }
+ document_ += "]";
+ }
+ break;
+ case objectValue:
+ {
+ Value::Members members( value.getMemberNames() );
+ document_ += "{";
+ for ( Value::Members::iterator it = members.begin();
+ it != members.end();
+ ++it )
+ {
+ const std::string &name = *it;
+ if ( it != members.begin() )
+ document_ += ",";
+ document_ += valueToQuotedString( name.c_str() );
+ document_ += yamlCompatiblityEnabled_ ? ": "
+ : ":";
+ writeValue( value[name] );
+ }
+ document_ += "}";
+ }
+ break;
+ }
+}
+
+
+// Class StyledWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledWriter::StyledWriter()
+ : rightMargin_( 74 )
+ , indentSize_( 3 )
+{
+}
+
+
+std::string
+StyledWriter::write( const Value &root )
+{
+ document_ = "";
+ addChildValues_ = false;
+ indentString_ = "";
+ writeCommentBeforeValue( root );
+ writeValue( root );
+ writeCommentAfterValueOnSameLine( root );
+ document_ += "\n";
+ return document_;
+}
+
+
+void
+StyledWriter::writeValue( const Value &value )
+{
+ switch ( value.type() )
+ {
+ case nullValue:
+ pushValue( "null" );
+ break;
+ case intValue:
+ pushValue( valueToString( value.asInt() ) );
+ break;
+ case uintValue:
+ pushValue( valueToString( value.asUInt() ) );
+ break;
+ case realValue:
+ pushValue( valueToString( value.asDouble() ) );
+ break;
+ case stringValue:
+ pushValue( valueToQuotedString( value.asCString() ) );
+ break;
+ case booleanValue:
+ pushValue( valueToString( value.asBool() ) );
+ break;
+ case arrayValue:
+ writeArrayValue( value);
+ break;
+ case objectValue:
+ {
+ Value::Members members( value.getMemberNames() );
+ if ( members.empty() )
+ pushValue( "{}" );
+ else
+ {
+ writeWithIndent( "{" );
+ indent();
+ Value::Members::iterator it = members.begin();
+ while ( true )
+ {
+ const std::string &name = *it;
+ const Value &childValue = value[name];
+ writeCommentBeforeValue( childValue );
+ writeWithIndent( valueToQuotedString( name.c_str() ) );
+ document_ += " : ";
+ writeValue( childValue );
+ if ( ++it == members.end() )
+ {
+ writeCommentAfterValueOnSameLine( childValue );
+ break;
+ }
+ document_ += ",";
+ writeCommentAfterValueOnSameLine( childValue );
+ }
+ unindent();
+ writeWithIndent( "}" );
+ }
+ }
+ break;
+ }
+}
+
+
+void
+StyledWriter::writeArrayValue( const Value &value )
+{
+ unsigned size = value.size();
+ if ( size == 0 )
+ pushValue( "[]" );
+ else
+ {
+ bool isArrayMultiLine = isMultineArray( value );
+ if ( isArrayMultiLine )
+ {
+ writeWithIndent( "[" );
+ indent();
+ bool hasChildValue = !childValues_.empty();
+ unsigned index =0;
+ while ( true )
+ {
+ const Value &childValue = value[index];
+ writeCommentBeforeValue( childValue );
+ if ( hasChildValue )
+ writeWithIndent( childValues_[index] );
+ else
+ {
+ writeIndent();
+ writeValue( childValue );
+ }
+ if ( ++index == size )
+ {
+ writeCommentAfterValueOnSameLine( childValue );
+ break;
+ }
+ document_ += ",";
+ writeCommentAfterValueOnSameLine( childValue );
+ }
+ unindent();
+ writeWithIndent( "]" );
+ }
+ else // output on a single line
+ {
+ assert( childValues_.size() == size );
+ document_ += "[ ";
+ for ( unsigned index =0; index < size; ++index )
+ {
+ if ( index > 0 )
+ document_ += ", ";
+ document_ += childValues_[index];
+ }
+ document_ += " ]";
+ }
+ }
+}
+
+
+bool
+StyledWriter::isMultineArray( const Value &value )
+{
+ int size = value.size();
+ bool isMultiLine = size*3 >= rightMargin_ ;
+ childValues_.clear();
+ for ( int index =0; index < size && !isMultiLine; ++index )
+ {
+ const Value &childValue = value[index];
+ isMultiLine = isMultiLine ||
+ ( (childValue.isArray() || childValue.isObject()) &&
+ childValue.size() > 0 );
+ }
+ if ( !isMultiLine ) // check if line length > max line length
+ {
+ childValues_.reserve( size );
+ addChildValues_ = true;
+ int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
+ for ( int index =0; index < size && !isMultiLine; ++index )
+ {
+ writeValue( value[index] );
+ lineLength += int( childValues_[index].length() );
+ isMultiLine = isMultiLine && hasCommentForValue( value[index] );
+ }
+ addChildValues_ = false;
+ isMultiLine = isMultiLine || lineLength >= rightMargin_;
+ }
+ return isMultiLine;
+}
+
+
+void
+StyledWriter::pushValue( const std::string &value )
+{
+ if ( addChildValues_ )
+ childValues_.push_back( value );
+ else
+ document_ += value;
+}
+
+
+void
+StyledWriter::writeIndent()
+{
+ if ( !document_.empty() )
+ {
+ char last = document_[document_.length()-1];
+ if ( last == ' ' ) // already indented
+ return;
+ if ( last != '\n' ) // Comments may add new-line
+ document_ += '\n';
+ }
+ document_ += indentString_;
+}
+
+
+void
+StyledWriter::writeWithIndent( const std::string &value )
+{
+ writeIndent();
+ document_ += value;
+}
+
+
+void
+StyledWriter::indent()
+{
+ indentString_ += std::string( indentSize_, ' ' );
+}
+
+
+void
+StyledWriter::unindent()
+{
+ assert( int(indentString_.size()) >= indentSize_ );
+ indentString_.resize( indentString_.size() - indentSize_ );
+}
+
+
+void
+StyledWriter::writeCommentBeforeValue( const Value &root )
+{
+ if ( !root.hasComment( commentBefore ) )
+ return;
+ document_ += normalizeEOL( root.getComment( commentBefore ) );
+ document_ += "\n";
+}
+
+
+void
+StyledWriter::writeCommentAfterValueOnSameLine( const Value &root )
+{
+ if ( root.hasComment( commentAfterOnSameLine ) )
+ document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
+
+ if ( root.hasComment( commentAfter ) )
+ {
+ document_ += "\n";
+ document_ += normalizeEOL( root.getComment( commentAfter ) );
+ document_ += "\n";
+ }
+}
+
+
+bool
+StyledWriter::hasCommentForValue( const Value &value )
+{
+ return value.hasComment( commentBefore )
+ || value.hasComment( commentAfterOnSameLine )
+ || value.hasComment( commentAfter );
+}
+
+
+std::string
+StyledWriter::normalizeEOL( const std::string &text )
+{
+ std::string normalized;
+ normalized.reserve( text.length() );
+ const char *begin = text.c_str();
+ const char *end = begin + text.length();
+ const char *current = begin;
+ while ( current != end )
+ {
+ char c = *current++;
+ if ( c == '\r' ) // mac or dos EOL
+ {
+ if ( *current == '\n' ) // convert dos EOL
+ ++current;
+ normalized += '\n';
+ }
+ else // handle unix EOL & other char
+ normalized += c;
+ }
+ return normalized;
+}
+
+
+// Class StyledStreamWriter
+// //////////////////////////////////////////////////////////////////
+
+StyledStreamWriter::StyledStreamWriter( std::string indentation )
+ : document_(NULL)
+ , rightMargin_( 74 )
+ , indentation_( indentation )
+{
+}
+
+
+void
+StyledStreamWriter::write( std::ostream &out, const Value &root )
+{
+ document_ = &out;
+ addChildValues_ = false;
+ indentString_ = "";
+ writeCommentBeforeValue( root );
+ writeValue( root );
+ writeCommentAfterValueOnSameLine( root );
+ *document_ << "\n";
+ document_ = NULL; // Forget the stream, for safety.
+}
+
+
+void
+StyledStreamWriter::writeValue( const Value &value )
+{
+ switch ( value.type() )
+ {
+ case nullValue:
+ pushValue( "null" );
+ break;
+ case intValue:
+ pushValue( valueToString( value.asInt() ) );
+ break;
+ case uintValue:
+ pushValue( valueToString( value.asUInt() ) );
+ break;
+ case realValue:
+ pushValue( valueToString( value.asDouble() ) );
+ break;
+ case stringValue:
+ pushValue( valueToQuotedString( value.asCString() ) );
+ break;
+ case booleanValue:
+ pushValue( valueToString( value.asBool() ) );
+ break;
+ case arrayValue:
+ writeArrayValue( value);
+ break;
+ case objectValue:
+ {
+ Value::Members members( value.getMemberNames() );
+ if ( members.empty() )
+ pushValue( "{}" );
+ else
+ {
+ writeWithIndent( "{" );
+ indent();
+ Value::Members::iterator it = members.begin();
+ while ( true )
+ {
+ const std::string &name = *it;
+ const Value &childValue = value[name];
+ writeCommentBeforeValue( childValue );
+ writeWithIndent( valueToQuotedString( name.c_str() ) );
+ *document_ << " : ";
+ writeValue( childValue );
+ if ( ++it == members.end() )
+ {
+ writeCommentAfterValueOnSameLine( childValue );
+ break;
+ }
+ *document_ << ",";
+ writeCommentAfterValueOnSameLine( childValue );
+ }
+ unindent();
+ writeWithIndent( "}" );
+ }
+ }
+ break;
+ }
+}
+
+
+void
+StyledStreamWriter::writeArrayValue( const Value &value )
+{
+ unsigned size = value.size();
+ if ( size == 0 )
+ pushValue( "[]" );
+ else
+ {
+ bool isArrayMultiLine = isMultineArray( value );
+ if ( isArrayMultiLine )
+ {
+ writeWithIndent( "[" );
+ indent();
+ bool hasChildValue = !childValues_.empty();
+ unsigned index =0;
+ while ( true )
+ {
+ const Value &childValue = value[index];
+ writeCommentBeforeValue( childValue );
+ if ( hasChildValue )
+ writeWithIndent( childValues_[index] );
+ else
+ {
+ writeIndent();
+ writeValue( childValue );
+ }
+ if ( ++index == size )
+ {
+ writeCommentAfterValueOnSameLine( childValue );
+ break;
+ }
+ *document_ << ",";
+ writeCommentAfterValueOnSameLine( childValue );
+ }
+ unindent();
+ writeWithIndent( "]" );
+ }
+ else // output on a single line
+ {
+ assert( childValues_.size() == size );
+ *document_ << "[ ";
+ for ( unsigned index =0; index < size; ++index )
+ {
+ if ( index > 0 )
+ *document_ << ", ";
+ *document_ << childValues_[index];
+ }
+ *document_ << " ]";
+ }
+ }
+}
+
+
+bool
+StyledStreamWriter::isMultineArray( const Value &value )
+{
+ int size = value.size();
+ bool isMultiLine = size*3 >= rightMargin_ ;
+ childValues_.clear();
+ for ( int index =0; index < size && !isMultiLine; ++index )
+ {
+ const Value &childValue = value[index];
+ isMultiLine = isMultiLine ||
+ ( (childValue.isArray() || childValue.isObject()) &&
+ childValue.size() > 0 );
+ }
+ if ( !isMultiLine ) // check if line length > max line length
+ {
+ childValues_.reserve( size );
+ addChildValues_ = true;
+ int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
+ for ( int index =0; index < size && !isMultiLine; ++index )
+ {
+ writeValue( value[index] );
+ lineLength += int( childValues_[index].length() );
+ isMultiLine = isMultiLine && hasCommentForValue( value[index] );
+ }
+ addChildValues_ = false;
+ isMultiLine = isMultiLine || lineLength >= rightMargin_;
+ }
+ return isMultiLine;
+}
+
+
+void
+StyledStreamWriter::pushValue( const std::string &value )
+{
+ if ( addChildValues_ )
+ childValues_.push_back( value );
+ else
+ *document_ << value;
+}
+
+
+void
+StyledStreamWriter::writeIndent()
+{
+ /*
+ Some comments in this method would have been nice. ;-)
+
+ if ( !document_.empty() )
+ {
+ char last = document_[document_.length()-1];
+ if ( last == ' ' ) // already indented
+ return;
+ if ( last != '\n' ) // Comments may add new-line
+ *document_ << '\n';
+ }
+ */
+ *document_ << '\n' << indentString_;
+}
+
+
+void
+StyledStreamWriter::writeWithIndent( const std::string &value )
+{
+ writeIndent();
+ *document_ << value;
+}
+
+
+void
+StyledStreamWriter::indent()
+{
+ indentString_ += indentation_;
+}
+
+
+void
+StyledStreamWriter::unindent()
+{
+ assert( indentString_.size() >= indentation_.size() );
+ indentString_.resize( indentString_.size() - indentation_.size() );
+}
+
+
+void
+StyledStreamWriter::writeCommentBeforeValue( const Value &root )
+{
+ if ( !root.hasComment( commentBefore ) )
+ return;
+ *document_ << normalizeEOL( root.getComment( commentBefore ) );
+ *document_ << "\n";
+}
+
+
+void
+StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root )
+{
+ if ( root.hasComment( commentAfterOnSameLine ) )
+ *document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
+
+ if ( root.hasComment( commentAfter ) )
+ {
+ *document_ << "\n";
+ *document_ << normalizeEOL( root.getComment( commentAfter ) );
+ *document_ << "\n";
+ }
+}
+
+
+bool
+StyledStreamWriter::hasCommentForValue( const Value &value )
+{
+ return value.hasComment( commentBefore )
+ || value.hasComment( commentAfterOnSameLine )
+ || value.hasComment( commentAfter );
+}
+
+
+std::string
+StyledStreamWriter::normalizeEOL( const std::string &text )
+{
+ std::string normalized;
+ normalized.reserve( text.length() );
+ const char *begin = text.c_str();
+ const char *end = begin + text.length();
+ const char *current = begin;
+ while ( current != end )
+ {
+ char c = *current++;
+ if ( c == '\r' ) // mac or dos EOL
+ {
+ if ( *current == '\n' ) // convert dos EOL
+ ++current;
+ normalized += '\n';
+ }
+ else // handle unix EOL & other char
+ normalized += c;
+ }
+ return normalized;
+}
+
+
+std::ostream& operator<<( std::ostream &sout, const Value &root )
+{
+ Json::StyledStreamWriter writer;
+ writer.write(sout, root);
+ return sout;
+}
+
+
+} // namespace Json
--- /dev/null
+Import( 'env buildLibrary' )
+
+buildLibrary( env, Split( """
+ json_reader.cpp
+ json_value.cpp
+ json_writer.cpp
+ """ ),
+ 'json' )
--- /dev/null
+##===- polly/lib/Makefile -----------------------*- Makefile -*-===##
+
+#
+# Indicate where we are relative to the top of the source tree.
+#
+LEVEL :=..
+
+DIRS = Support
+USEDLIBS = pollysupport.a
+
+LIBRARYNAME=LLVMPolly
+LOADABLE_MODULE = 1
+
+include $(LEVEL)/Makefile.config
+
+CPP.Flags += $(POLLY_INC)
+
+DIRS += Exchange
+USEDLIBS += pollyexchange.a
+
+DIRS += Analysis
+USEDLIBS += pollyanalysis.a
+
+DIRS += JSON
+USEDLIBS += pollyjson.a
+
+# TODO: Export symbols for RTTI or EH?
+
+#
+# Include Makefile.common so we know what to do.
+#
+include $(LEVEL)/Makefile.common
+
+LIBS += $(POLLY_LD) $(POLLY_LIB)
+
+$(LibDir)/libpollyanalysis.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/Analysis/$(BuildMode)/.dir \
+ $(PROJ_SRC_DIR)/Analysis/*
+ $(Verb) if [ -d $(PROJ_SRC_DIR)/Analysis ]; then\
+ if ([ ! -f Analysis/Makefile ] || \
+ command test Analysis/Makefile -ot $(PROJ_SRC_DIR)/Analysis/Makefile ); then \
+ $(MKDIR) Analysis; \
+ $(CP) $(PROJ_SRC_DIR)/Analysis/Makefile Analysis/Makefile; \
+ fi; \
+ ($(MAKE) -C Analysis $@ ) || exit 1; \
+ fi
+
+$(LibDir)/libpollyexchange.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/Exchange/$(BuildMode)/.dir \
+ $(PROJ_SRC_DIR)/Exchange/*
+ $(Verb) if [ -d $(PROJ_SRC_DIR)/Exchange ]; then\
+ if ([ ! -f Exchange/Makefile ] || \
+ command test Exchange/Makefile -ot $(PROJ_SRC_DIR)/Exchange/Makefile ); then \
+ $(MKDIR) Exchange; \
+ $(CP) $(PROJ_SRC_DIR)/Exchange/Makefile Exchange/Makefile; \
+ fi; \
+ ($(MAKE) -C Exchange $@ ) || exit 1; \
+ fi
+
+$(LibDir)/libpollysupport.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/Support/$(BuildMode)/.dir \
+ $(PROJ_SRC_DIR)/Support/*
+ $(Verb) if [ -d $(PROJ_SRC_DIR)/Support ]; then\
+ if ([ ! -f Support/Makefile ] || \
+ command test Support/Makefile -ot $(PROJ_SRC_DIR)/Support/Makefile ); then \
+ $(MKDIR) Support; \
+ $(CP) $(PROJ_SRC_DIR)/Support/Makefile Support/Makefile; \
+ fi; \
+ ($(MAKE) -C Support $@ ) || exit 1; \
+ fi
+
+$(LibDir)/libpollyjson.a : $(LibDir)/.dir $(PROJ_OBJ_DIR)/JSON/$(BuildMode)/.dir \
+ $(PROJ_SRC_DIR)/JSON/*
+ $(Verb) if [ -d $(PROJ_SRC_DIR)/JSON ]; then\
+ if ([ ! -f JSON/Makefile ] || \
+ command test JSON/Makefile -ot $(PROJ_SRC_DIR)/JSON/Makefile ); then \
+ $(MKDIR) JSON; \
+ $(CP) $(PROJ_SRC_DIR)/JSON/Makefile JSON/Makefile; \
+ fi; \
+ ($(MAKE) -C JSON $@ ) || exit 1; \
+ fi
--- /dev/null
+//===---------- MayAliasSet.cpp - May-Alais Set for base pointers --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MayAliasSet class
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/TempScopInfo.h"
+#include "polly/MayAliasSet.h"
+
+#include "llvm/LLVMContext.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+using namespace polly;
+
+void MayAliasSet::print(raw_ostream &OS) const {
+ OS << "Must alias {";
+
+ for (const_iterator I = mustalias_begin(), E = mustalias_end(); I != E; ++I) {
+ WriteAsOperand(OS, *I, false);
+ OS << ", ";
+ }
+
+ OS << "} May alias {";
+ OS << '}';
+}
+
+void MayAliasSet::dump() const {
+ print(dbgs());
+}
+
+void MayAliasSetInfo::buildMayAliasSets(TempScop &Scop, AliasAnalysis &AA) {
+ AliasSetTracker AST(AA);
+ Region &MaxR = Scop.getMaxRegion();
+
+ // Find out all base pointers that appeared in Scop and build the Alias set.
+ // Note: We may build the alias sets while we are building access functions
+ // to obtain better performance.
+ for (Region::block_iterator I = MaxR.block_begin(), E = MaxR.block_end();
+ I != E; ++I) {
+ BasicBlock *BB = I->getNodeAs<BasicBlock>();
+ if (const AccFuncSetType *AFS = Scop.getAccessFunctions(BB)) {
+ for (AccFuncSetType::const_iterator AI = AFS->begin(), AE = AFS->end();
+ AI != AE; ++AI) {
+ const SCEVAffFunc &AccFunc = AI->first;
+ Instruction *Inst = AI->second;
+ Value *BaseAddr = const_cast<Value*>(AccFunc.getBaseAddr());
+
+ AST.add(BaseAddr, AliasAnalysis::UnknownSize,
+ Inst->getMetadata(LLVMContext::MD_tbaa));
+ }
+ }
+ }
+
+ // Build the may-alias set with the AliasSetTracker.
+ for (AliasSetTracker::iterator I = AST.begin(), E = AST.end(); I != E; ++I) {
+ AliasSet &AS = *I;
+
+ // Ignore the dummy alias set.
+ if (AS.isForwardingAliasSet()) continue;
+
+ // The most simple case: All pointers in the set must-alias each others.
+ if (AS.isMustAlias()) {
+ MayAliasSet *MayAS = new (MayASAllocator.Allocate()) MayAliasSet();
+
+ for (AliasSet::iterator PI = AS.begin(), PE = AS.end(); PI != PE; ++PI) {
+ Value *Ptr = PI.getPointer();
+
+ MayAS->addMustAliasPtr(Ptr);
+ BasePtrMap.insert(std::make_pair(Ptr, MayAS));
+ }
+
+ continue;
+ }
+
+ assert(0 && "SCoPDetection pass should not allow May-Alias set!");
+ }
+}
--- /dev/null
+//===- Pocc.cpp - Pocc interface ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Pocc[1] interface.
+//
+// Pocc, the polyhedral compilation collection is a collection of polyhedral
+// tools. It is used as an optimizer in polly
+//
+// [1] http://www-roc.inria.fr/~pouchet/software/pocc/
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Cloog.h"
+#include "polly/LinkAllPasses.h"
+
+#ifdef SCOPLIB_FOUND
+#include "polly/ScopInfo.h"
+#include "polly/Dependences.h"
+
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/ADT/OwningPtr.h"
+
+#include "polly/ScopLib.h"
+
+#include "isl/dim.h"
+#include "isl/map.h"
+#include "isl/constraint.h"
+
+
+using namespace llvm;
+using namespace polly;
+
+static cl::opt<bool>
+PlutoTile("enable-pluto-tile",
+ cl::desc("Enable pluto tiling for polly"), cl::Hidden,
+ cl::value_desc("Pluto tiling enabled if true"),
+ cl::init(false));
+static cl::opt<bool>
+PlutoPrevector("enable-pluto-prevector",
+ cl::desc("Enable pluto prevectorization for polly"), cl::Hidden,
+ cl::value_desc("Pluto prevectorization enabled if true"),
+ cl::init(false));
+static cl::opt<std::string>
+PlutoFuse("pluto-fuse",
+ cl::desc(""), cl::Hidden,
+ cl::value_desc("Set fuse mode of Pluto"),
+ cl::init("maxfuse"));
+
+namespace {
+
+ class Pocc : public ScopPass {
+ sys::Path plutoStderr;
+ sys::Path plutoStdout;
+ std::vector<const char*> arguments;
+
+ public:
+ static char ID;
+ explicit Pocc() : ScopPass(ID) {}
+
+ std::string getFileName(Region *R) const;
+ virtual bool runOnScop(Scop &S);
+ void printScop(llvm::raw_ostream &OS) const;
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ };
+
+}
+
+char Pocc::ID = 0;
+bool Pocc::runOnScop(Scop &S) {
+ Dependences *D = &getAnalysis<Dependences>();
+
+ // Only the final read statement in the SCoP. No need to optimize anything.
+ // (In case we would try, Pocc complains that there is no statement in the
+ // SCoP).
+ if (S.begin() + 1 == S.end())
+ return false;
+
+ // Create the scop file.
+ sys::Path tempDir = sys::Path::GetTemporaryDirectory();
+ sys::Path scopFile = tempDir;
+ scopFile.appendComponent("polly.scop");
+ scopFile.createFileOnDisk();
+
+ FILE *F = fopen(scopFile.c_str(), "w");
+
+ arguments.clear();
+
+ if (!F) {
+ errs() << "Cannot open file: " << tempDir.c_str() << "\n";
+ errs() << "Skipping export.\n";
+ return false;
+ }
+
+ ScopLib scoplib(&S);
+ scoplib.print(F);
+ fclose(F);
+
+ // Execute pocc
+ sys::Program program;
+
+ sys::Path pocc = sys::Program::FindProgramByName("pocc");
+
+ arguments.push_back("pocc");
+ arguments.push_back("--read-scop");
+ arguments.push_back(scopFile.c_str());
+ arguments.push_back("--pluto-tile-scat");
+ arguments.push_back("--candl-dep-isl-simp");
+ arguments.push_back("--cloogify-scheds");
+ arguments.push_back("--output-scop");
+ arguments.push_back("--pluto");
+ arguments.push_back("--pluto-bounds");
+ arguments.push_back("10");
+ arguments.push_back("--pluto-fuse");
+
+ arguments.push_back(PlutoFuse.c_str());
+
+ if (PlutoTile)
+ arguments.push_back("--pluto-tile");
+
+ if (PlutoPrevector)
+ arguments.push_back("--pluto-prevector");
+
+ arguments.push_back(0);
+
+ plutoStdout = tempDir;
+ plutoStdout.appendComponent("pluto.stdout");
+ plutoStderr = tempDir;
+ plutoStderr.appendComponent("pluto.stderr");
+
+ std::vector<sys::Path*> redirect;
+ redirect.push_back(0);
+ redirect.push_back(&plutoStdout);
+ redirect.push_back(&plutoStderr);
+
+ program.ExecuteAndWait(pocc, &arguments[0], 0,
+ (sys::Path const **) &redirect[0]);
+
+ // Read the created scop file
+ sys::Path newScopFile = tempDir;
+ newScopFile.appendComponent("polly.pocc.c.scop");
+
+ FILE *poccFile = fopen(newScopFile.c_str(), "r");
+ ScopLib newScoplib(&S, poccFile, D);
+
+ if (!newScoplib.updateScattering()) {
+ errs() << "Failure when calculating the optimization with "
+ "the following command: ";
+ for (std::vector<const char*>::const_iterator AI = arguments.begin(),
+ AE = arguments.end(); AI != AE; ++AI)
+ if (*AI)
+ errs() << " " << *AI;
+ errs() << "\n";
+ return false;
+ } else
+ fclose(poccFile);
+
+ if (!PlutoPrevector)
+ return false;
+
+ // Find the innermost dimension that is not a constant dimension. This
+ // dimension will be vectorized.
+ unsigned scatterDims = S.getScatterDim();
+ int lastLoop = scatterDims - 1;
+
+ while (lastLoop) {
+ bool isSingleValued = true;
+
+ for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
+ if ((*SI)->isFinalRead())
+ continue;
+
+ isl_map *scat = isl_map_copy((*SI)->getScattering());
+ isl_map *projected = isl_map_project_out(scat, isl_dim_out, lastLoop,
+ scatterDims - lastLoop);
+
+ if (!isl_map_is_bijective(projected)) {
+ isSingleValued = false;
+ break;
+ }
+ }
+
+ if (!isSingleValued)
+ break;
+
+ lastLoop--;
+ }
+
+ // Strip mine the innermost loop.
+ for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI) {
+ if ((*SI)->isFinalRead())
+ continue;
+ isl_map *scat = (*SI)->getScattering();
+
+ int scatDims = isl_map_n_out(scat);
+ isl_dim *dim = isl_dim_alloc(S.getCtx(), S.getNumParams(), scatDims,
+ scatDims + 1);
+ isl_basic_map *map = isl_basic_map_universe(isl_dim_copy(dim));
+
+ for (int i = 0; i <= lastLoop - 1; i++) {
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+
+ isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1);
+
+ map = isl_basic_map_add_constraint(map, c);
+ }
+
+ for (int i = lastLoop; i < scatDims; i++) {
+ isl_constraint *c = isl_equality_alloc(isl_dim_copy(dim));
+
+ isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, i + 1, -1);
+
+ map = isl_basic_map_add_constraint(map, c);
+ }
+
+ isl_constraint *c;
+
+ int vectorWidth = 4;
+ c = isl_inequality_alloc(isl_dim_copy(dim));
+ isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, -vectorWidth);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, 1);
+ map = isl_basic_map_add_constraint(map, c);
+
+ c = isl_inequality_alloc(isl_dim_copy(dim));
+ isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, vectorWidth);
+ isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, -1);
+ isl_constraint_set_constant_si(c, vectorWidth - 1);
+ map = isl_basic_map_add_constraint(map, c);
+
+ isl_map *transform = isl_map_from_basic_map(map);
+ transform = isl_map_set_tuple_name(transform, isl_dim_out, "scattering");
+ transform = isl_map_set_tuple_name(transform, isl_dim_in, "scattering");
+
+ scat = isl_map_apply_range(scat, isl_map_copy(transform));
+ (*SI)->setScattering(scat);
+ }
+
+ return false;
+}
+
+void Pocc::printScop(raw_ostream &OS) const {
+ OwningPtr<MemoryBuffer> stdoutBuffer;
+ OwningPtr<MemoryBuffer> stderrBuffer;
+
+ OS << "Command line: ";
+
+ for (std::vector<const char*>::const_iterator AI = arguments.begin(),
+ AE = arguments.end(); AI != AE; ++AI)
+ if (*AI)
+ OS << " " << *AI;
+
+ OS << "\n";
+
+ if (error_code ec = MemoryBuffer::getFile(plutoStdout.c_str(), stdoutBuffer))
+ OS << "Could not open pocc stdout file: " + ec.message();
+ else {
+ OS << "pocc stdout: " << stdoutBuffer->getBufferIdentifier() << "\n";
+ OS << stdoutBuffer->getBuffer() << "\n";
+ }
+
+ if (error_code ec = MemoryBuffer::getFile(plutoStderr.c_str(), stderrBuffer))
+ OS << "Could not open pocc stderr file: " + ec.message();
+ else {
+ OS << "pocc stderr: " << plutoStderr.c_str() << "\n";
+ OS << stderrBuffer->getBuffer() << "\n";
+ }
+}
+
+void Pocc::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+ AU.addRequired<Dependences>();
+}
+
+static RegisterPass<Pocc> A("polly-optimize",
+ "Polly - Optimize the scop using pocc");
+
+Pass* polly::createPoccPass() {
+ return new Pocc();
+}
+#endif /* SCOPLIB_FOUND */
--- /dev/null
+//===- RegionSimplify.cpp -------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file converts refined regions detected by the RegionInfo analysis
+// into simple regions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+
+#include "llvm/Instructions.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionPass.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+#define DEBUG_TYPE "region-simplify"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+STATISTIC(NumEntries, "The # of created entry edges");
+STATISTIC(NumExits, "The # of created exit edges");
+
+namespace {
+class RegionSimplify: public RegionPass {
+ // Remember the modified region.
+ Region *r;
+ void createSingleEntryEdge(Region *R);
+ void createSingleExitEdge(Region *R);
+public:
+ static char ID;
+ explicit RegionSimplify() : RegionPass(ID), r(0) {}
+
+ virtual void print(raw_ostream &O, const Module *M) const;
+
+ virtual bool runOnRegion(Region *R, RGPassManager &RGM);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+}
+
+static RegisterPass<RegionSimplify>
+X("polly-region-simplify", "Transform refined regions into simple regions");
+
+char RegionSimplify::ID = 0;
+namespace polly {
+ Pass *createRegionSimplifyPass() {
+ return new RegionSimplify();
+ }
+}
+
+void RegionSimplify::print(raw_ostream &O, const Module *M) const {
+ if (r == 0) return;
+
+ BasicBlock *enteringBlock = r->getEnteringBlock();
+ BasicBlock *exitingBlock = r->getExitingBlock();
+
+ O << "Region: " << r->getNameStr() << " Edges:\t";
+
+ if (enteringBlock)
+ O << "Entering: [" << enteringBlock->getNameStr() << " -> "
+ << r->getEntry()->getName() << "], ";
+
+ if (exitingBlock) {
+ O << "Exiting: [" << exitingBlock->getNameStr() << " -> ";
+ if (r->getExit())
+ O << r->getExit()->getName();
+ else
+ O << "<return>";
+ O << "]";
+ }
+
+ O << "\n";
+}
+
+void RegionSimplify::getAnalysisUsage(AnalysisUsage &AU) const {
+ // Function SplitBlockPredecessors currently updates/preserves AliasAnalysis,
+ /// DominatorTree, LoopInfo, and LCCSA but no other analyses.
+ //AU.addPreserved<AliasAnalysis>(); Break SCEV-AA
+ AU.addPreserved<DominatorTree> ();
+ AU.addPreserved<LoopInfo>();
+ AU.addPreservedID(LCSSAID);
+
+ AU.addPreserved<RegionInfo> ();
+ AU.addRequired<RegionInfo> ();
+}
+
+// createSingleEntryEdge - Split the entry basic block of the given
+// region after the last PHINode to form a single entry edge.
+void RegionSimplify::createSingleEntryEdge(Region *R) {
+ BasicBlock *oldEntry = R->getEntry();
+ SmallVector<BasicBlock*, 4> Preds;
+ for (pred_iterator PI = pred_begin(oldEntry), PE = pred_end(oldEntry);
+ PI != PE; ++PI)
+ if (!R->contains(*PI))
+ Preds.push_back(*PI);
+
+ assert(Preds.size() && "This region has already a single entry edge");
+
+ BasicBlock *newEntry = SplitBlockPredecessors(oldEntry,
+ Preds.data(), Preds.size(),
+ ".single_entry", this);
+
+ RegionInfo *RI = &getAnalysis<RegionInfo> ();
+ // We do not update entry node for children of this region.
+ // This make it easier to extract children regions because they do not share
+ // the entry node with their parents.
+ // all parent regions whose entry is oldEntry are updated with newEntry
+ Region *r = R->getParent();
+
+ // Put the new entry to R's parent.
+ RI->setRegionFor(newEntry,r);
+
+ while (r->getEntry() == oldEntry && !r->isTopLevelRegion()) {
+ r->replaceEntry(newEntry);
+ r = r->getParent();
+ }
+
+ // We do not update exit node for children of this region for the same reason
+ // of not updating entry node.
+ // All other regions whose exit is oldEntry are updated with new exit node
+ r = RI->getTopLevelRegion();
+ std::vector<Region *> RQ;
+ RQ.push_back(r);
+
+ while (!RQ.empty()){
+ r = RQ.back();
+ RQ.pop_back();
+
+ for (Region::const_iterator RI = r->begin(), RE = r->end(); RI!=RE; ++RI)
+ RQ.push_back(*RI);
+
+ if (r->getExit() == oldEntry && !R->contains(r))
+ r->replaceExit(newEntry);
+ }
+
+}
+
+// createSingleExitEdge - Split the exit basic of the given region
+// to form a single exit edge.
+void RegionSimplify::createSingleExitEdge(Region *R) {
+ BasicBlock *oldExit = R->getExit();
+
+ SmallVector<BasicBlock*, 4> Preds;
+ for (pred_iterator PI = pred_begin(oldExit), PE = pred_end(oldExit);
+ PI != PE; ++PI)
+ if (R->contains(*PI))
+ Preds.push_back(*PI);
+
+ DEBUG(dbgs() << "Going to create single exit for:\n");
+ DEBUG(R->print(dbgs(), true, 0, Region::PrintRN));
+ BasicBlock *newExit = SplitBlockPredecessors(oldExit,
+ Preds.data(), Preds.size(),
+ ".single_exit", this);
+ RegionInfo *RI = &getAnalysis<RegionInfo>();
+
+ // We do not need to update entry nodes because this split happens inside
+ // this region and it affects only this region and all of its children.
+ // The new split node belongs to this region
+ RI->setRegionFor(newExit,R);
+ DEBUG(dbgs() << "Adding new exiting block: " << newExit->getName() << '\n');
+
+ // all children of this region whose exit is oldExit is changed to newExit
+ std::vector<Region *> RQ;
+ for (Region::const_iterator RI = R->begin(), RE = R->end(); RI!=RE; ++RI)
+ RQ.push_back(*RI);
+
+ while (!RQ.empty()){
+ R = RQ.back();
+ RQ.pop_back();
+
+ if (R->getExit() != oldExit)
+ continue;
+
+ for (Region::const_iterator RI = R->begin(), RE = R->end(); RI!=RE; ++RI)
+ RQ.push_back(*RI);
+
+ R->replaceExit(newExit);
+ DEBUG(dbgs() << "Replacing exit for:\n");
+ DEBUG(R->print(dbgs(), true, 0, Region::PrintRN));
+ }
+
+ DEBUG(dbgs() << "After split exit:\n");
+ DEBUG(R->print(dbgs(), true, 0, Region::PrintRN));
+}
+
+bool RegionSimplify::runOnRegion(Region *R, RGPassManager &RGM) {
+ r = 0;
+
+ if (!R->isTopLevelRegion()) {
+
+ // split entry node if the region has multiple entry edges
+ if (!(R->getEnteringBlock())
+ && (pred_begin(R->getEntry()) != pred_end(R->getEntry()))) {
+ createSingleEntryEdge(R);
+ r = R;
+ ++NumEntries;
+ }
+
+ // split exit node if the region has multiple exit edges
+ if (!(R->getExitingBlock())) {
+ createSingleExitEdge(R);
+ r = R;
+ ++NumExits;
+ }
+ }
+
+ return r != 0;
+}
--- /dev/null
+//===- AffSCEVItTester.cpp - Test the affine scev itertor. ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Test the affine scev itertor.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "polly/Support/AffineSCEVIterator.h"
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <map>
+
+using namespace llvm;
+using namespace polly;
+
+static void printSCEVAffine(raw_ostream &OS, const SCEV* S,
+ ScalarEvolution *SE) {
+
+ for (AffineSCEVIterator I = affine_begin(S, SE), E = affine_end();
+ I != E; ++I) {
+ OS << *I->second << " * " << *I->first;
+
+ // The constant part of the SCEV will always be the last one.
+ if (!isa<SCEVConstant>(S))
+ OS << " + ";
+ }
+}
+
+namespace {
+struct AffSCEVItTester : public FunctionPass {
+ static char ID;
+
+ ScalarEvolution *SE;
+ LoopInfo *LI;
+ Function *F;
+
+ explicit AffSCEVItTester() : FunctionPass(ID), SE(0), LI(0), F(0) {}
+
+ virtual bool runOnFunction(Function &F) {
+ SE = &getAnalysis<ScalarEvolution>();
+ LI = &getAnalysis<LoopInfo>();
+ this->F = &F;
+ return false;
+ }
+
+ virtual void print(raw_ostream &OS, const Module *M) const {
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
+ if (SE->isSCEVable(I->getType())) {
+ OS << *I << '\n';
+ OS << " --> ";
+ const SCEV *SV = SE->getSCEV(&*I);
+
+ if (Loop *L = LI->getLoopFor(I->getParent()))
+ SV = SE->getSCEVAtScope(SV, L);
+ SV->print(OS);
+ OS << "\n";
+ OS << "affine function --> ";
+ printSCEVAffine(OS, SV, SE);
+ OS << "\n";
+ }
+
+ for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
+ PrintLoopInfo(OS, *I);
+ }
+
+ void PrintLoopInfo(raw_ostream &OS, const Loop *L) const{
+ // Print all inner loops first
+ for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
+ PrintLoopInfo(OS, *I);
+
+ OS << "Loop ";
+ WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false);
+ OS << ": ";
+
+ if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
+ const SCEV *SV = SE->getBackedgeTakenCount(L);
+ OS << "backedge-taken count is ";
+ printSCEVAffine(OS, SV, SE);
+
+ OS << "\nloop count in scev ";
+ SV->print(OS);
+ OS << "\n";
+ }
+ else {
+ OS << "Unpredictable\n";
+ }
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<ScalarEvolution>();
+ AU.addRequired<LoopInfo>();
+ AU.setPreservesAll();
+ }
+};
+} // end namespace
+
+
+char AffSCEVItTester::ID = 0;
+
+RegisterPass<AffSCEVItTester> B("print-scev-affine",
+ "Print the SCEV expressions in affine form.",
+ true,
+ true);
+
+namespace polly {
+Pass *createAffSCEVItTesterPass() {
+ return new AffSCEVItTester();
+}
+}
--- /dev/null
+add_polly_library(PollySupport
+ AffSCEVItTester.cpp
+ GICHelper.cpp
+ ScopHelper.cpp
+ )
--- /dev/null
+//===- GmpConv.cpp - Recreate LLVM IR from the Scop. ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Functions for converting between gmp objects and apint.
+//
+//===----------------------------------------------------------------------===//
+#include "polly/Support/GICHelper.h"
+
+#include "isl/set.h"
+#include "isl/union_set.h"
+#include "isl/map.h"
+#include "isl/union_map.h"
+
+using namespace llvm;
+
+void polly::MPZ_from_APInt (mpz_t v, const APInt apint, bool is_signed) {
+ // There is no sign taken from the data, rop will simply be a positive
+ // integer. An application can handle any sign itself, and apply it for
+ // instance with mpz_neg.
+ APInt abs;
+ if (is_signed)
+ abs = apint.abs();
+ else
+ abs = apint;
+
+ const uint64_t *rawdata = abs.getRawData();
+ unsigned numWords = abs.getNumWords();
+
+ // TODO: Check if this is true for all platforms.
+ mpz_import(v, numWords, 1, sizeof (uint64_t), 0, 0, rawdata);
+
+ if (is_signed && apint.isNegative()) mpz_neg(v, v);
+}
+
+APInt polly::APInt_from_MPZ (const mpz_t mpz) {
+ uint64_t *p = NULL;
+ size_t sz;
+
+ p = (uint64_t*) mpz_export(p, &sz, 1, sizeof(uint64_t), 0, 0, mpz);
+
+ if (p) {
+ APInt A((unsigned)mpz_sizeinbase(mpz, 2), (unsigned)sz , p);
+ A = A.zext(A.getBitWidth() + 1);
+
+ if (mpz_sgn(mpz) == -1)
+ return -A;
+ else
+ return A;
+ } else {
+ uint64_t val = 0;
+ return APInt(1, 1, &val);
+ }
+}
+
+std::string polly::stringFromIslObj(/*__isl_keep*/ isl_map *map) {
+ isl_printer *p = isl_printer_to_str(isl_map_get_ctx(map));
+ isl_printer_print_map(p, map);
+ std::string string(isl_printer_get_str(p));
+ isl_printer_free(p);
+ return string;
+}
+
+std::string polly::stringFromIslObj(/*__isl_keep*/ isl_set *set) {
+ isl_printer *p = isl_printer_to_str(isl_set_get_ctx(set));
+ isl_printer_print_set(p, set);
+ std::string string(isl_printer_get_str(p));
+ isl_printer_free(p);
+ return string;
+}
+
+std::string polly::stringFromIslObj(/*__isl_keep*/ isl_union_map *umap) {
+ isl_printer *p = isl_printer_to_str(isl_union_map_get_ctx(umap));
+ isl_printer_print_union_map(p, umap);
+ std::string string(isl_printer_get_str(p));
+ isl_printer_free(p);
+ return string;
+}
+
+std::string polly::stringFromIslObj(/*__isl_keep*/ isl_union_set *uset) {
+ isl_printer *p = isl_printer_to_str(isl_union_set_get_ctx(uset));
+ isl_printer_print_union_set(p, uset);
+ std::string string(isl_printer_get_str(p));
+ isl_printer_free(p);
+ return string;
+}
--- /dev/null
+##===- polly/lib/Support/Makefile ----------------*- Makefile -*-===##
+
+#
+# Indicate where we are relative to the top of the source tree.
+#
+LEVEL=../..
+
+LIBRARYNAME=pollysupport
+BUILD_ARCHIVE = 1
+
+CPP.Flags += $(POLLY_INC)
+
+#
+# Include Makefile.common so we know what to do.
+#
+include $(LEVEL)/Makefile.common
--- /dev/null
+//===- ScopHelper.cpp - Some Helper Functions for Scop. ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Small functions that help with Scop and LLVM-IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Support/ScopHelper.h"
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+#define DEBUG_TYPE "polly-scop-helper"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+
+namespace {
+// Checks if a SCEV is invariant in a region. This is if all Values are
+// referenced in this SCEV are defined outside the region.
+class InvariantChecker: SCEVVisitor<InvariantChecker, bool> {
+ Region &R;
+
+public:
+ bool visitConstant(const SCEVConstant *S) {
+ return true;
+ }
+
+ bool visitUnknown(const SCEVUnknown* S) {
+ Value *V = S->getValue();
+
+ // An Instruction defined outside the region is invariant.
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ return !R.contains(I);
+
+ // A constant is invariant.
+ return true;
+ }
+
+ bool visitNAryExpr(const SCEVNAryExpr *S) {
+ for (SCEVNAryExpr::op_iterator OI = S->op_begin(), OE = S->op_end();
+ OI != OE; ++OI)
+ if (!visit(*OI))
+ return false;
+
+ return true;
+ }
+
+ bool visitMulExpr(const SCEVMulExpr* S) {
+ return visitNAryExpr(S);
+ }
+
+ bool visitCastExpr(const SCEVCastExpr *S) {
+ return visit(S->getOperand());
+ }
+
+ bool visitTruncateExpr(const SCEVTruncateExpr *S) {
+ return visit(S->getOperand());
+ }
+
+ bool visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
+ return visit(S->getOperand());
+ }
+
+ bool visitSignExtendExpr(const SCEVSignExtendExpr *S) {
+ return visit(S->getOperand());
+ }
+
+ bool visitAddExpr(const SCEVAddExpr *S) {
+ return visitNAryExpr(S);
+ }
+
+ bool visitAddRecExpr(const SCEVAddRecExpr *S) {
+ // Check if the addrec is contained in the region.
+ if (R.contains(S->getLoop()))
+ return false;
+
+ return visitNAryExpr(S);
+ }
+
+ bool visitUDivExpr(const SCEVUDivExpr *S) {
+ return visit(S->getLHS()) && visit(S->getRHS());
+ }
+
+ bool visitSMaxExpr(const SCEVSMaxExpr *S) {
+ return visitNAryExpr(S);
+ }
+
+ bool visitUMaxExpr(const SCEVUMaxExpr *S) {
+ return visitNAryExpr(S);
+ }
+
+ bool visitCouldNotCompute(const SCEVCouldNotCompute *S) {
+ llvm_unreachable("SCEV cannot be checked");
+ }
+
+ InvariantChecker(Region &RefRegion)
+ : R(RefRegion) {}
+
+ static bool isInvariantInRegion(const SCEV *S, Region &R) {
+ InvariantChecker Checker(R);
+ return Checker.visit(S);
+ }
+};
+}
+
+// Helper function for Scop
+// TODO: Add assertion to not allow parameter to be null
+//===----------------------------------------------------------------------===//
+// Temporary Hack for extended region tree.
+// Cast the region to loop if there is a loop have the same header and exit.
+Loop *polly::castToLoop(const Region &R, LoopInfo &LI) {
+ BasicBlock *entry = R.getEntry();
+
+ if (!LI.isLoopHeader(entry))
+ return 0;
+
+ Loop *L = LI.getLoopFor(entry);
+
+ BasicBlock *exit = L->getExitBlock();
+
+ // Is the loop with multiple exits?
+ if (!exit) return 0;
+
+ if (exit != R.getExit()) {
+ // SubRegion/ParentRegion with the same entry.
+ assert((R.getNode(R.getEntry())->isSubRegion()
+ || R.getParent()->getEntry() == entry)
+ && "Expect the loop is the smaller or bigger region");
+ return 0;
+ }
+
+ return L;
+}
+
+Value *polly::getPointerOperand(Instruction &Inst) {
+ if (LoadInst *load = dyn_cast<LoadInst>(&Inst))
+ return load->getPointerOperand();
+ else if (StoreInst *store = dyn_cast<StoreInst>(&Inst))
+ return store->getPointerOperand();
+ else if (GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(&Inst))
+ return gep->getPointerOperand();
+
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Helper functions
+
+bool polly::isInvariant(const SCEV *S, Region &R) {
+ return InvariantChecker::isInvariantInRegion(S, R);
+}
+
+// Helper function to check parameter
+bool polly::isParameter(const SCEV *Var, Region &RefRegion,
+ LoopInfo &LI, ScalarEvolution &SE) {
+ assert(Var && "Var can not be null!");
+
+ if (!isInvariant(Var, RefRegion))
+ return false;
+
+ if (isa<SCEVAddRecExpr>(Var))
+ return true;
+
+ if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(Var)) {
+ if (isa<PHINode>(U->getValue()))
+ return false;
+
+ if(isa<UndefValue>(U->getValue()))
+ return false;
+
+ return true;
+ }
+
+ if (const SCEVCastExpr *Cast = dyn_cast<SCEVCastExpr>(Var))
+ return isParameter(Cast->getOperand(), RefRegion, LI, SE);
+
+ return false;
+}
+
+bool polly::isIndVar(const SCEV *Var, Region &RefRegion,
+ LoopInfo &LI, ScalarEvolution &SE) {
+ const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Var);
+
+ // AddRecExprs are no induction variables.
+ if (!AddRec) return false;
+
+ Loop *L = const_cast<Loop*>(AddRec->getLoop());
+
+ // Is the addrec an induction variable of a loop contained in the current
+ // region.
+ if (!RefRegion.contains(L))
+ return false;
+
+ DEBUG(dbgs() << "Find AddRec: " << *AddRec
+ << " at region: " << RefRegion.getNameStr() << " as indvar\n");
+ return true;
+}
+
+bool polly::isIndVar(const Instruction *I, const LoopInfo *LI) {
+ Loop *L = LI->getLoopFor(I->getParent());
+
+ return L && I == L->getCanonicalInductionVariable();
+}
+
+bool polly::hasInvokeEdge(const PHINode *PN) {
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i)
+ if (InvokeInst *II = dyn_cast<InvokeInst>(PN->getIncomingValue(i)))
+ if (II->getParent() == PN->getIncomingBlock(i))
+ return true;
+
+ return false;
+}
+
+// Helper function for LLVM-IR about Scop
+BasicBlock *polly::createSingleEntryEdge(Region *R, Pass *P) {
+ BasicBlock *BB = R->getEntry();
+
+ BasicBlock::iterator SplitIt = BB->begin();
+
+ while (isa<PHINode>(SplitIt))
+ ++SplitIt;
+
+ BasicBlock *newBB = SplitBlock(BB, SplitIt, P);
+
+ for (BasicBlock::iterator PI = BB->begin(); isa<PHINode>(PI); ++PI) {
+ PHINode *PN = cast<PHINode>(PI);
+ PHINode *NPN =
+ PHINode::Create(PN->getType(), 2, PN->getName()+".ph", newBB->begin());
+
+ for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
+ if (R->contains(*PI)) {
+ Value *V = PN->removeIncomingValue(*PI, false);
+ NPN->addIncoming(V, *PI);
+ }
+ }
+ PN->replaceAllUsesWith(NPN);
+ NPN->addIncoming(PN,BB);
+ }
+
+ for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI)
+ if (R->contains(*PI))
+ (*PI)->getTerminator()->replaceUsesOfWith(BB, newBB);
+
+ return newBB;
+}
+
+BasicBlock *polly::createSingleExitEdge(Region *R, Pass *P) {
+ BasicBlock *BB = R->getExit();
+
+ SmallVector<BasicBlock*, 4> Preds;
+ for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI)
+ if (R->contains(*PI))
+ Preds.push_back(*PI);
+
+ return SplitBlockPredecessors(BB, Preds.data(), Preds.size(), ".region", P);
+}
+
+void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
+ // Find first non-alloca instruction. Every basic block has a non-alloc
+ // instruction, as every well formed basic block has a terminator.
+ BasicBlock::iterator I = EntryBlock->begin();
+ while (isa<AllocaInst>(I)) ++I;
+
+ // SplitBlock updates DT, DF and LI.
+ BasicBlock *NewEntry = SplitBlock(EntryBlock, I, P);
+ if (RegionInfo *RI = P->getAnalysisIfAvailable<RegionInfo>())
+ RI->splitBlock(NewEntry, EntryBlock);
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
+
+define void @f(i32* nocapture %a) nounwind {
+entry:
+ %0 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=2]
+; CHECK: 1 * %0 + 0 * 1
+ %1 = icmp sgt i32 %0, 0 ; <i1> [#uses=1]
+ br i1 %1, label %bb, label %return
+
+bb: ; preds = %bb, %entry
+ %i.03 = phi i32 [ 0, %entry ], [ %3, %bb ] ; <i32> [#uses=1]
+; CHECK: 1 * {0,+,1}<nuw><nsw><%bb> + 0 * 1
+ %2 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=0]
+; CHECK: 1 * %2 + 0 * 1
+ %3 = add nsw i32 %i.03, 1 ; <i32> [#uses=2]
+; CHECK: 1 * {0,+,1}<nuw><nsw><%bb> + 1 * 1
+ %exitcond = icmp eq i32 %3, %0 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb, %entry
+ ret void
+}
+
+declare i32 @rnd(...)
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
+
+define i32 @f(i64 %a, i64 %b, i64 %c, [8 x i32]* nocapture %x) nounwind readonly {
+entry:
+ %0 = shl i64 %a, 1 ; <i64> [#uses=1]
+ %1 = add nsw i64 %0, %b ; <i64> [#uses=1]
+; CHECK: 1 * %b + 2 * %a + 0 * 1
+ %2 = shl i64 %1, 1 ; <i64> [#uses=1]
+; CHECK: 2 * %b + 4 * %a + 0 * 1
+ %3 = add i64 %2, 2 ; <i64> [#uses=1]
+ %4 = mul i64 %a, 3 ; <i64> [#uses=1]
+ %5 = shl i64 %b, 2 ; <i64> [#uses=1]
+ %6 = add nsw i64 %4, 2 ; <i64> [#uses=1]
+ %7 = add nsw i64 %6, %c ; <i64> [#uses=1]
+ %8 = add nsw i64 %7, %5 ; <i64> [#uses=1]
+ %9 = getelementptr inbounds [8 x i32]* %x, i64 %3, i64 %8 ; <i32*> [#uses=1]
+; CHECK: 1 * %x + sizeof(i32) * %c + (35 * sizeof(i32)) * %a + (20 * sizeof(i32)) * %b + (18 * sizeof(i32)) * 1
+ %10 = load i32* %9, align 4 ; <i32> [#uses=1]
+ ret i32 %10
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
+
+define void @f([8 x i32]* nocapture %x) nounwind {
+entry:
+ br label %bb5.preheader
+
+bb2: ; preds = %bb3.preheader, %bb2
+ %k.09 = phi i64 [ 0, %bb3.preheader ], [ %1, %bb2 ] ; <i64> [#uses=2]
+ %tmp19 = add i64 %k.09, %tmp18 ; <i64> [#uses=1]
+ %scevgep = getelementptr [8 x i32]* %x, i64 2, i64 %tmp19 ; <i32*> [#uses=1]
+; CHECK: sizeof(i32) * {0,+,1}<nuw><nsw><%bb2> + (20 * sizeof(i32)) * {0,+,1}<%bb3.preheader> + (35 * sizeof(i32)) * {0,+,1}<%bb5.preheader> + 1 * %x + (18 * sizeof(i32)) * 1
+ %0 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=1]
+ store i32 %0, i32* %scevgep, align 4
+ %1 = add nsw i64 %k.09, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %1, 64 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb4, label %bb2
+
+bb4: ; preds = %bb2
+ %2 = add i64 %j.010, 1 ; <i64> [#uses=2]
+ %exitcond20 = icmp eq i64 %2, 64 ; <i1> [#uses=1]
+ br i1 %exitcond20, label %bb6, label %bb3.preheader
+
+bb3.preheader: ; preds = %bb5.preheader, %bb4
+ %j.010 = phi i64 [ 0, %bb5.preheader ], [ %2, %bb4 ] ; <i64> [#uses=2]
+ %tmp21 = mul i64 %j.010, 20 ; <i64> [#uses=1]
+ %tmp18 = add i64 %tmp21, %tmp23 ; <i64> [#uses=1]
+ br label %bb2
+
+bb6: ; preds = %bb4
+ %3 = add i64 %i.012, 1 ; <i64> [#uses=2]
+ %exitcond25 = icmp eq i64 %3, 64 ; <i1> [#uses=1]
+ br i1 %exitcond25, label %return, label %bb5.preheader
+
+bb5.preheader: ; preds = %bb6, %entry
+ %i.012 = phi i64 [ 0, %entry ], [ %3, %bb6 ] ; <i64> [#uses=2]
+ %tmp = mul i64 %i.012, 35 ; <i64> [#uses=1]
+ %tmp23 = add i64 %tmp, 2 ; <i64> [#uses=1]
+ br label %bb3.preheader
+
+return: ; preds = %bb6
+ ret void
+}
+
+declare i32 @rnd(...)
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
+
+define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d, i32* nocapture %x) nounwind readnone {
+entry:
+ %0 = shl i32 %a, 1 ; <i32> [#uses=1]
+; CHECK: 2 * %a + 0 * 1
+ %1 = mul i32 %b, 3 ; <i32> [#uses=1]
+; CHECK: 3 * %b + 0 * 1
+ %2 = shl i32 %d, 2 ; <i32> [#uses=1]
+; CHECK: 4 * %d + 0 * 1
+ %3 = add nsw i32 %0, 5 ; <i32> [#uses=1]
+; CHECK: 2 * %a + 5 * 1
+ %4 = add nsw i32 %3, %c ; <i32> [#uses=1]
+; CHECK: 1 * %c + 2 * %a + 5 * 1
+ %5 = add nsw i32 %4, %1 ; <i32> [#uses=1]
+; CHECK: 1 * %c + 3 * %b + 2 * %a + 5 * 1
+ %6 = add nsw i32 %5, %2 ; <i32> [#uses=1]
+; CHECK: 1 * %c + 4 * %d + 3 * %b + 2 * %a + 5 * 1
+ ret i32 %6
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @f(i32 %a, i32 %b, i32 %c, i64 %d, i8 signext %e, i32 %f, i32 %g, i32 %h) nounwind readnone {
+entry:
+ %0 = mul i32 %a, 3 ; <i32> [#uses=1]
+ %1 = mul i32 %b, 5 ; <i32> [#uses=1]
+ %2 = mul i32 %1, %c ; <i32> [#uses=1]
+; CHECK: 5 * (%b * %c) + 0 * 1
+ %3 = mul i32 %2, %f ; <i32> [#uses=1]
+; CHECK: 5 * (%b * %c * %f) + 0 * 1
+ %4 = sext i8 %e to i32 ; <i32> [#uses=1]
+ %5 = shl i32 %4, 2 ; <i32> [#uses=1]
+ %6 = trunc i64 %d to i32 ; <i32> [#uses=1]
+ %7 = mul i32 %6, %h ; <i32> [#uses=1]
+ %8 = add nsw i32 %0, %g ; <i32> [#uses=1]
+ %9 = add nsw i32 %8, %5 ; <i32> [#uses=1]
+ %10 = add nsw i32 %9, %3 ; <i32> [#uses=1]
+ %11 = add nsw i32 %10, %7 ; <i32> [#uses=1]
+; CHECK: 1 * %g + 1 * ((trunc i64 %d to i32) * %h) + 5 * (%b * %c * %f) + 4 * (sext i8 %e to i32) + 3 * %a + 0 * 1
+ ret i32 %11
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d, i32* nocapture %x) nounwind {
+entry:
+ br label %bb
+
+bb: ; preds = %bb, %entry
+ %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %bb ] ; <i64> [#uses=3]
+; CHECK: 1 * {0,+,1}<%bb> + 0 * 1
+ %scevgep = getelementptr i32* %x, i64 %indvar ; <i32*> [#uses=1]
+; CHECK: 4 * {0,+,1}<%bb> + 1 * %x + 0 * 1
+ %i.04 = trunc i64 %indvar to i32 ; <i32> [#uses=1]
+; CHECK: 1 * {0,+,1}<%bb> + 0 * 1
+ store i32 %i.04, i32* %scevgep, align 4
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+; CHECK: 1 * {0,+,1}<%bb> + 1 * 1
+ %exitcond = icmp eq i64 %indvar.next, 64 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb
+
+bb2: ; preds = %bb
+ ret i32 %a
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -print-scev-affine -analyze < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d, [4 x i32]* nocapture %x) nounwind {
+entry:
+ br label %bb2.preheader
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %indvar = phi i64 [ 0, %bb2.preheader ], [ %indvar.next, %bb1 ] ; <i64> [#uses=3]
+; CHECK: 1 * {0,+,1}<%bb1> + 0 * 1
+ %scevgep = getelementptr [4 x i32]* %x, i64 %indvar, i64 %0 ; <i32*> [#uses=1]
+; CHECK: 16 * {0,+,1}<%bb1> + 4 * {0,+,1}<%bb2.preheader> + 1 * %x + 0 * 1
+ %tmp = mul i64 %indvar, %0 ; <i64> [#uses=1]
+; CHECK: 1 * {0,+,{0,+,1}<%bb2.preheader>}<%bb1> + 0 * 1
+ %tmp13 = trunc i64 %tmp to i32 ; <i32> [#uses=1]
+; CHECK: 1 * {0,+,{0,+,1}<%bb2.preheader>}<%bb1> + 0 * 1
+ store i32 %tmp13, i32* %scevgep, align 4
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+; CHECK: 1 * {0,+,1}<%bb1> + 1 * 1
+ %exitcond = icmp eq i64 %indvar.next, 64 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %indvar.next12 = add i64 %0, 1 ; <i64> [#uses=2]
+; CHECK: 1 * {0,+,1}<%bb2.preheader> + 1 * 1
+ %exitcond14 = icmp eq i64 %indvar.next12, 64 ; <i1> [#uses=1]
+ br i1 %exitcond14, label %bb5, label %bb2.preheader
+
+bb2.preheader: ; preds = %bb3, %entry
+ %0 = phi i64 [ 0, %entry ], [ %indvar.next12, %bb3 ] ; <i64> [#uses=3]
+; CHECK: 1 * {0,+,1}<%bb2.preheader> + 0 * 1
+ br label %bb1
+
+bb5: ; preds = %bb3
+ ret i32 %a
+}
--- /dev/null
+set(POLLY_TEST_DIRECTORIES
+ "ScopInfo"
+ "AffineIterator"
+ "CodeGen"
+ "OpenMP"
+ "polybench")
+
+set(LLVM_SOURCE_DIR "${LLVM_MAIN_SRC_DIR}")
+set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}")
+set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}/")
+set(LLVM_LIBS_DIR "${LLVM_BINARY_DIR}/lib")
+set(POLLY_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
+set(POLLY_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..")
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)
+
+include(FindPythonInterp)
+if(PYTHONINTERP_FOUND)
+ set(POLLY_TEST_EXTRA_ARGS)
+ if (MSVC OR XCODE)
+ set(POLLY_TEST_EXTRA_ARGS "--no-progress-bar")
+ endif()
+
+ option(POLLY_TEST_USE_VG "Run Polly tests under Valgrind" OFF)
+ if(POLLY_TEST_USE_VG)
+ set(POLLY_TEST_EXTRA_ARGS ${POLLY_TEST_EXTRA_ARGS} "--vg")
+ endif ()
+
+ foreach(testdir ${POLLY_TEST_DIRECTORIES})
+ add_custom_target(polly-test-${testdir}
+ COMMAND ${PYTHON_EXECUTABLE}
+ ${LLVM_SOURCE_DIR}/utils/lit/lit.py
+ --param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ --param build_config=${CMAKE_CFG_INTDIR}
+ -sv ${POLLY_TEST_EXTRA_ARGS}
+ ${CMAKE_CURRENT_BINARY_DIR}/${testdir}
+ DEPENDS opt LLVMPolly
+ COMMENT "Running Polly regression tests in ${testdir}")
+ endforeach()
+
+ add_custom_target(polly-test
+ COMMAND ${PYTHON_EXECUTABLE}
+ ${LLVM_SOURCE_DIR}/utils/lit/lit.py
+ --param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+ --param build_config=${CMAKE_CFG_INTDIR}
+ -sv ${POLLY_TEST_EXTRA_ARGS}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS opt LLVMPolly
+ COMMENT "Running Polly regression tests")
+endif()
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; ModuleID = 'a'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @init_array() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.cond1, %entry
+ %indvar1 = phi i64 [ %indvar.next2, %for.cond1 ], [ 0, %entry ] ; <i64> [#uses=1]
+ br i1 false, label %for.cond1, label %for.end32
+
+for.cond1: ; preds = %for.cond
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end32: ; preds = %for.cond
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | not FileCheck %s
+
+; ModuleID = 'a'
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i386-portbld-freebsd8.0"
+
+define void @MAIN__() nounwind {
+entry:
+ br i1 undef, label %bb6.preheader, label %bb3
+
+bb3: ; preds = %bb3, %entry
+ br i1 undef, label %bb6.preheader, label %bb3
+
+bb6.preheader: ; preds = %bb3, %entry
+ br i1 undef, label %bb11, label %bb9.preheader
+
+bb9.preheader: ; preds = %bb6.preheader
+ br label %bb11
+
+bb11: ; preds = %bb9.preheader, %bb6.preheader
+ br label %bb15
+
+bb15: ; preds = %bb15, %bb11
+ br i1 undef, label %bb26.loopexit, label %bb15
+
+bb26.loopexit: ; preds = %bb15
+ br i1 undef, label %bb31, label %bb29.preheader
+
+bb29.preheader: ; preds = %bb26.loopexit
+ br label %bb29
+
+bb29: ; preds = %bb29, %bb29.preheader
+ %indvar47 = phi i32 [ 0, %bb29.preheader ], [ %indvar.next48, %bb29 ] ; <i32> [#uses=1]
+ %indvar.next48 = add i32 %indvar47, 1 ; <i32> [#uses=2]
+ %exitcond50 = icmp eq i32 %indvar.next48, undef ; <i1> [#uses=1]
+ br i1 %exitcond50, label %bb31, label %bb29
+
+bb31: ; preds = %bb29, %bb26.loopexit
+ %errtot.3 = phi float [ undef, %bb26.loopexit ], [ undef, %bb29 ] ; <float> [#uses=0]
+ ret void
+}
+
+; CHECK: SCOP:
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; ModuleID = 'a'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @clause_SetSplitField(i32 %Length) nounwind inlinehint {
+entry:
+ br i1 undef, label %bb1, label %bb6
+
+bb1: ; preds = %entry
+ unreachable
+
+bb6: ; preds = %entry
+ %tmp = zext i32 %Length to i64 ; <i64> [#uses=1]
+ br label %bb8
+
+bb7: ; preds = %bb8
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %bb8
+
+bb8: ; preds = %bb7, %bb6
+ %indvar = phi i64 [ %indvar.next, %bb7 ], [ 0, %bb6 ] ; <i64> [#uses=2]
+ %exitcond = icmp ne i64 %indvar, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb7, label %return
+
+return: ; preds = %bb8
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@win193 = external global [4 x [36 x double]], align 32 ; <[4 x [36 x double]]*> [#uses=3]
+@sb_sample = external global [2 x [2 x [18 x [32 x double]]]], align 32 ; <[2 x [2 x [18 x [32 x double]]]]*> [#uses=2]
+
+define void @mdct_sub48() nounwind {
+entry:
+ br i1 undef, label %bb, label %bb54
+
+bb: ; preds = %entry
+ br label %bb54
+
+bb3: ; preds = %bb50
+ br label %bb8
+
+bb4: ; preds = %bb8
+ br label %bb8
+
+bb8: ; preds = %bb4, %bb3
+ br i1 undef, label %bb4, label %bb9
+
+bb9: ; preds = %bb8
+ br label %bb48
+
+bb25: ; preds = %bb48
+ br i1 false, label %bb26, label %bb27
+
+bb26: ; preds = %bb48, %bb25
+ br label %bb37
+
+bb27: ; preds = %bb25
+ br i1 undef, label %bb32, label %bb35
+
+bb32: ; preds = %bb27
+ br label %bb37
+
+bb34: ; preds = %bb35
+ %0 = getelementptr inbounds [36 x double]* undef, i64 0, i64 0 ; <double*> [#uses=0]
+ %1 = getelementptr inbounds [18 x [32 x double]]* undef, i64 0, i64 0 ; <[32 x double]*> [#uses=1]
+ %2 = getelementptr inbounds [32 x double]* %1, i64 0, i64 0 ; <double*> [#uses=0]
+ %3 = getelementptr inbounds [36 x double]* undef, i64 0, i64 0 ; <double*> [#uses=0]
+ %4 = sub nsw i32 17, %k.4 ; <i32> [#uses=1]
+ %5 = getelementptr inbounds [2 x [2 x [18 x [32 x double]]]]* @sb_sample, i64 0, i64 0 ; <[2 x [18 x [32 x double]]]*> [#uses=1]
+ %6 = getelementptr inbounds [2 x [18 x [32 x double]]]* %5, i64 0, i64 0 ; <[18 x [32 x double]]*> [#uses=1]
+ %7 = sext i32 %4 to i64 ; <i64> [#uses=1]
+ %8 = getelementptr inbounds [18 x [32 x double]]* %6, i64 0, i64 %7 ; <[32 x double]*> [#uses=1]
+ %9 = getelementptr inbounds [32 x double]* %8, i64 0, i64 0 ; <double*> [#uses=1]
+ %10 = load double* %9, align 8 ; <double> [#uses=0]
+ %11 = fsub double 0.000000e+00, undef ; <double> [#uses=1]
+ %12 = getelementptr inbounds double* getelementptr inbounds ([4 x [36 x double]]* @win193, i64 0, i64 2, i64 4), i64 0 ; <double*> [#uses=1]
+ store double %11, double* %12, align 8
+ %13 = add nsw i32 %k.4, 9 ; <i32> [#uses=1]
+ %14 = add nsw i32 %k.4, 18 ; <i32> [#uses=1]
+ %15 = getelementptr inbounds [4 x [36 x double]]* @win193, i64 0, i64 0 ; <[36 x double]*> [#uses=1]
+ %16 = sext i32 %14 to i64 ; <i64> [#uses=1]
+ %17 = getelementptr inbounds [36 x double]* %15, i64 0, i64 %16 ; <double*> [#uses=1]
+ %18 = load double* %17, align 8 ; <double> [#uses=0]
+ %19 = sext i32 %k.4 to i64 ; <i64> [#uses=1]
+ %20 = getelementptr inbounds [18 x [32 x double]]* undef, i64 0, i64 %19 ; <[32 x double]*> [#uses=1]
+ %21 = sext i32 %band.2 to i64 ; <i64> [#uses=1]
+ %22 = getelementptr inbounds [32 x double]* %20, i64 0, i64 %21 ; <double*> [#uses=1]
+ %23 = load double* %22, align 8 ; <double> [#uses=0]
+ %24 = sext i32 %39 to i64 ; <i64> [#uses=1]
+ %25 = getelementptr inbounds [4 x [36 x double]]* @win193, i64 0, i64 %24 ; <[36 x double]*> [#uses=1]
+ %26 = getelementptr inbounds [36 x double]* %25, i64 0, i64 0 ; <double*> [#uses=1]
+ %27 = load double* %26, align 8 ; <double> [#uses=0]
+ %28 = sub nsw i32 17, %k.4 ; <i32> [#uses=1]
+ %29 = getelementptr inbounds [2 x [2 x [18 x [32 x double]]]]* @sb_sample, i64 0, i64 0 ; <[2 x [18 x [32 x double]]]*> [#uses=1]
+ %30 = getelementptr inbounds [2 x [18 x [32 x double]]]* %29, i64 0, i64 0 ; <[18 x [32 x double]]*> [#uses=1]
+ %31 = sext i32 %28 to i64 ; <i64> [#uses=1]
+ %32 = getelementptr inbounds [18 x [32 x double]]* %30, i64 0, i64 %31 ; <[32 x double]*> [#uses=1]
+ %33 = getelementptr inbounds [32 x double]* %32, i64 0, i64 0 ; <double*> [#uses=1]
+ %34 = load double* %33, align 8 ; <double> [#uses=0]
+ %35 = sext i32 %13 to i64 ; <i64> [#uses=1]
+ %36 = getelementptr inbounds double* getelementptr inbounds ([4 x [36 x double]]* @win193, i64 0, i64 2, i64 4), i64 %35 ; <double*> [#uses=1]
+ store double 0.000000e+00, double* %36, align 8
+ %37 = sub nsw i32 %k.4, 1 ; <i32> [#uses=1]
+ br label %bb35
+
+bb35: ; preds = %bb34, %bb27
+ %k.4 = phi i32 [ %37, %bb34 ], [ 8, %bb27 ] ; <i32> [#uses=6]
+ br i1 undef, label %bb34, label %bb36
+
+bb36: ; preds = %bb35
+ unreachable
+
+bb37: ; preds = %bb32, %bb26
+ %38 = add nsw i32 %band.2, 1 ; <i32> [#uses=1]
+ br label %bb48
+
+bb48: ; preds = %bb37, %bb9
+ %band.2 = phi i32 [ %38, %bb37 ], [ 0, %bb9 ] ; <i32> [#uses=2]
+ %39 = load i32* null, align 8 ; <i32> [#uses=1]
+ br i1 undef, label %bb26, label %bb25
+
+bb50: ; preds = %bb54
+ br i1 undef, label %bb3, label %bb51
+
+bb51: ; preds = %bb50
+ br i1 undef, label %bb52, label %bb53
+
+bb52: ; preds = %bb51
+ unreachable
+
+bb53: ; preds = %bb51
+ br label %bb54
+
+bb54: ; preds = %bb53, %bb, %entry
+ br i1 undef, label %bb50, label %return
+
+return: ; preds = %bb54
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect < %s
+; ModuleID = '/tmp/bug.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define fastcc void @execute() nounwind {
+entry:
+ br i1 undef, label %check_stack.exit456.thread, label %bb.i451.preheader
+
+bb.i451.preheader: ; preds = %bb116
+ br label %bb.i451
+
+bb.i451: ; preds = %bb.i451, %bb.i451.preheader
+ br label %bb.i451
+
+check_stack.exit456.thread: ; preds = %bb116
+ unreachable
+
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; ModuleID = '/home/grosser/Projekte/polly/git/tools/polly/test/CodeGen/20100708_2.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+define void @init_array() nounwind {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb4, %bb
+ br i1 undef, label %bb2, label %bb5
+
+bb2: ; preds = %bb3, %bb1
+ %indvar = phi i64 [ %indvar.next, %bb3 ], [ 0, %bb1 ] ; <i64> [#uses=1]
+ %tmp3 = trunc i64 undef to i32 ; <i32> [#uses=1]
+ br i1 false, label %bb3, label %bb4
+
+bb3: ; preds = %bb2
+ %tmp = srem i32 %tmp3, 1024 ; <i32> [#uses=0]
+ store double undef, double* undef
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %bb2
+
+bb4: ; preds = %bb2
+ br label %bb1
+
+bb5: ; preds = %bb1
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @fft_float(i32 %NumSamples) nounwind {
+ br label %bb18
+
+bb18: ; preds = %bb17
+ br i1 false, label %bb19, label %bb22
+
+bb19: ; preds = %bb18
+ %a = uitofp i32 %NumSamples to double ; <double> [#uses=1]
+ br label %bb21
+
+bb20: ; preds = %bb21
+ %1 = load float* undef, align 4 ; <float> [#uses=0]
+ %2 = fpext float undef to double ; <double> [#uses=1]
+ %3 = fdiv double %2, %a ; <double> [#uses=0]
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %bb21
+
+bb21: ; preds = %bb20, %bb19
+ %indvar = phi i64 [ %indvar.next, %bb20 ], [ 0, %bb19 ] ; <i64> [#uses=1]
+ br i1 false, label %bb20, label %bb22.loopexit
+
+bb22.loopexit: ; preds = %bb21
+ br label %bb22
+
+bb22: ; preds = %bb22.loopexit, %bb18
+ br label %return
+
+return: ; preds = %bb22
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define hidden void @luaD_callhook() nounwind {
+entry:
+ br i1 undef, label %bb, label %return
+
+bb: ; preds = %entry
+ br i1 undef, label %bb1, label %return
+
+bb1: ; preds = %bb
+ %0 = sub nsw i64 undef, undef ; <i64> [#uses=1]
+ br i1 false, label %bb2, label %bb3
+
+bb2: ; preds = %bb1
+ br label %bb4
+
+bb3: ; preds = %bb1
+ br label %bb4
+
+bb4: ; preds = %bb3, %bb2
+ br i1 undef, label %bb5, label %bb6
+
+bb5: ; preds = %bb4
+ unreachable
+
+bb6: ; preds = %bb4
+ %1 = getelementptr inbounds i8* undef, i64 %0 ; <i8*> [#uses=0]
+ ret void
+
+return: ; preds = %bb, %entry
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -disable-output < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @matrixTranspose(double** %A) nounwind {
+entry:
+ br label %bb4
+
+bb: ; preds = %bb4
+ %0 = add nsw i32 %i.0, 1 ; <i32> [#uses=1]
+ br label %bb2
+
+bb1: ; preds = %bb2
+ %1 = getelementptr inbounds double** %A, i64 0 ; <double**> [#uses=0]
+ %2 = getelementptr inbounds double** %A, i64 0 ; <double**> [#uses=0]
+ %3 = getelementptr inbounds double** %A, i64 0 ; <double**> [#uses=0]
+ %4 = sext i32 %j.0 to i64 ; <i64> [#uses=1]
+ %5 = getelementptr inbounds double** %A, i64 %4 ; <double**> [#uses=1]
+ %6 = load double** %5, align 8 ; <double*> [#uses=0]
+ %7 = add nsw i32 %j.0, 1 ; <i32> [#uses=1]
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %j.0 = phi i32 [ %0, %bb ], [ %7, %bb1 ] ; <i32> [#uses=3]
+ %8 = icmp sle i32 %j.0, 50 ; <i1> [#uses=1]
+ br i1 %8, label %bb1, label %bb3
+
+bb3: ; preds = %bb2
+ %9 = add nsw i32 %i.0, 1 ; <i32> [#uses=1]
+ br label %bb4
+
+bb4: ; preds = %bb3, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %9, %bb3 ] ; <i32> [#uses=3]
+ %10 = icmp sle i32 %i.0, 50 ; <i1> [#uses=1]
+ br i1 %10, label %bb, label %return
+
+return: ; preds = %bb4
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -verify-dom-info -disable-output < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @getNonAffNeighbour() nounwind {
+entry:
+ br i1 undef, label %bb, label %bb6
+
+bb: ; preds = %entry
+ br i1 false, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ br label %bb16
+
+bb2: ; preds = %bb
+ br i1 false, label %bb3, label %bb4
+
+bb3: ; preds = %bb2
+ br label %bb16
+
+bb4: ; preds = %bb2
+ br label %bb16
+
+bb6: ; preds = %entry
+ br i1 false, label %bb7, label %bb9
+
+bb7: ; preds = %bb6
+ br label %bb16
+
+bb9: ; preds = %bb6
+ br label %bb16
+
+bb16: ; preds = %bb9, %bb7, %bb4, %bb3, %bb1
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -verify-dom-info -disable-output < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @intrapred_luma_16x16(i32 %predmode) nounwind {
+entry:
+ switch i32 %predmode, label %bb81 [
+ i32 0, label %bb25
+ i32 1, label %bb26
+ ]
+
+bb23: ; preds = %bb25
+ %indvar.next95 = add i64 %indvar94, 1 ; <i64> [#uses=1]
+ br label %bb25
+
+bb25: ; preds = %bb23, %entry
+ %indvar94 = phi i64 [ %indvar.next95, %bb23 ], [ 0, %entry ] ; <i64> [#uses=1]
+ br i1 false, label %bb23, label %return
+
+bb26: ; preds = %entry
+ ret void
+
+bb81: ; preds = %entry
+ ret void
+
+return: ; preds = %bb25
+ ret void
+}
--- /dev/null
+int bar1();
+int bar2();
+int bar3();
+int k;
+#define N 100
+int A[N];
+
+int main() {
+ int i, j, z;
+
+ __sync_synchronize();
+ for (i = 0; i < N; i++) {
+ if (i < 50)
+ A[i] = 8;
+ if (i < 4)
+ A[i] = 9;
+ if (i < 3)
+ A[i] = 10;
+ }
+ __sync_synchronize();
+
+ return A[z];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s
+; ModuleID = '20100720-MultipleConditions.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [100 x i32] zeroinitializer, align 16 ; <[100 x i32]*> [#uses=2]
+@k = common global i32 0, align 4 ; <i32*> [#uses=0]
+
+define i32 @main() nounwind {
+; <label>:0
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %1
+
+; <label>:1 ; preds = %12, %0
+ %indvar = phi i64 [ %indvar.next, %12 ], [ 0, %0 ] ; <i64> [#uses=4]
+ %scevgep = getelementptr [100 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=3]
+ %i.0 = trunc i64 %indvar to i32 ; <i32> [#uses=3]
+ %exitcond = icmp ne i64 %indvar, 100 ; <i1> [#uses=1]
+ br i1 %exitcond, label %2, label %13
+
+; <label>:2 ; preds = %1
+ %3 = icmp slt i32 %i.0, 50 ; <i1> [#uses=1]
+ br i1 %3, label %4, label %5
+
+; <label>:4 ; preds = %2
+ store i32 8, i32* %scevgep
+ br label %5
+
+; <label>:5 ; preds = %4, %2
+ %6 = icmp slt i32 %i.0, 4 ; <i1> [#uses=1]
+ br i1 %6, label %7, label %8
+
+; <label>:7 ; preds = %5
+ store i32 9, i32* %scevgep
+ br label %8
+
+; <label>:8 ; preds = %7, %5
+ %9 = icmp slt i32 %i.0, 3 ; <i1> [#uses=1]
+ br i1 %9, label %10, label %11
+
+; <label>:10 ; preds = %8
+ store i32 10, i32* %scevgep
+ br label %11
+
+; <label>:11 ; preds = %10, %8
+ br label %12
+
+; <label>:12 ; preds = %11
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %1
+
+; <label>:13 ; preds = %1
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %14 = sext i32 undef to i64 ; <i64> [#uses=1]
+ %15 = getelementptr inbounds i32* getelementptr inbounds ([100 x i32]* @A, i32 0, i32 0), i64 %14 ; <i32*> [#uses=1]
+ %16 = load i32* %15 ; <i32> [#uses=1]
+ ret i32 %16
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+; CHECK: for (c2=0;c2<=2;c2++) {
+; CHECK: S0(c2);
+; CHECK: S1(c2);
+; CHECK: S2(c2);
+; CHECK: }
+; CHECK: S0(3);
+; CHECK: S1(3);
+; CHECK: for (c2=4;c2<=49;c2++) {
+; CHECK: S0(c2);
+; CHECK: }
+; CHECK: S0: Stmt_4
+; CHECK: S1: Stmt_7
+; CHECK: S2: Stmt_10
+; CHECK:
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -disable-output %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @cfft2([2 x float]* %x) nounwind {
+entry:
+ %d.1.reg2mem = alloca [2 x float]* ; <[2 x float]**> [#uses=3]
+ br i1 undef, label %bb2, label %bb34
+
+bb2: ; preds = %bb34, %entry
+ ret void
+
+bb20: ; preds = %bb34
+ store [2 x float]* undef, [2 x float]** %d.1.reg2mem
+ br i1 false, label %bb21, label %bb23
+
+bb21: ; preds = %bb20
+ %0 = getelementptr inbounds [2 x float]* %x, i64 undef ; <[2 x float]*> [#uses=1]
+ store [2 x float]* %0, [2 x float]** %d.1.reg2mem
+ br label %bb23
+
+bb23: ; preds = %bb21, %bb20
+ %d.1.reload = load [2 x float]** %d.1.reg2mem ; <[2 x float]*> [#uses=1]
+ br i1 undef, label %bb29, label %bb34
+
+bb29: ; preds = %bb23
+ %1 = getelementptr inbounds [2 x float]* %d.1.reload, i64 undef ; <[2 x float]*> [#uses=0]
+ br label %bb34
+
+bb34: ; preds = %bb29, %bb23, %entry
+ br i1 undef, label %bb20, label %bb2
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -disable-output %s
+target datalayout =
+"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @main() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvar1 = phi i64 [ %indvar.next2, %for.inc ], [ 0, %entry ] ; <i64> [#uses=2]
+ %exitcond = icmp ne i64 %indvar1, 1024 ; <i1> [#uses=1]
+ br label %a
+
+a: ; preds = %for.cond
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %a
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %a
+ br label %for.cond5
+
+for.cond5: ; preds = %for.inc17, %for.end
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @compdecomp() nounwind {
+entry:
+ %max = alloca i64
+ %i = load i64* undef
+ br label %bb37
+
+bb37: ; preds = %bb36, %bb28
+ %tmp = icmp ugt i64 %i, 0
+ br i1 %tmp, label %bb38, label %bb39
+
+bb38: ; preds = %bb37
+ store i64 %i, i64* %max
+ br label %bb39
+
+bb39: ; preds = %bb38, %bb37
+ unreachable
+
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @Reflection_coefficients(i16* %r) nounwind {
+bb20:
+ %indvar3.lcssa20.reload = load i64* undef
+ %tmp = mul i64 %indvar3.lcssa20.reload, -1
+ %tmp5 = add i64 %tmp, 8
+ br label %bb22
+
+bb21: ; preds = %bb22
+ %r_addr.1.moved.to.bb21 = getelementptr i16* %r, i64 0
+ store i16 0, i16* %r_addr.1.moved.to.bb21, align 2
+ %indvar.next = add i64 %indvar, 1
+ br label %bb22
+
+bb22: ; preds = %bb21, %bb20
+ %indvar = phi i64 [ %indvar.next, %bb21 ], [ 0, %bb20 ]
+ %exitcond = icmp ne i64 %indvar, %tmp5
+ br i1 %exitcond, label %bb21, label %return
+
+return: ; preds = %bb22
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+define void @CleanNet() nounwind {
+entry:
+ %firstVia.0.reg2mem = alloca i64
+ br label %bb7
+
+bb7: ; preds = %bb7, %entry
+ br i1 undef, label %bb7, label %bb8
+
+bb8: ; preds = %bb7
+ %indvar5.lcssa.reload = load i64* undef
+ %tmp17 = mul i64 %indvar5.lcssa.reload, -1
+ %tmp18 = add i64 0, %tmp17
+ br label %bb18
+
+bb13: ; preds = %bb18
+ %0 = icmp ult i64 %i.1, 0
+ br i1 %0, label %bb14, label %bb17
+
+bb14: ; preds = %bb13
+ store i64 %i.1, i64* %firstVia.0.reg2mem
+ br label %bb17
+
+bb17: ; preds = %bb14, %bb13
+ %indvar.next16 = add i64 %indvar15, 1
+ br label %bb18
+
+bb18: ; preds = %bb17, %bb8
+ %indvar15 = phi i64 [ %indvar.next16, %bb17 ], [ 0, %bb8 ]
+ %i.1 = add i64 %tmp18, %indvar15
+ br i1 undef, label %bb13, label %bb25
+
+bb25: ; preds = %bb18
+ ret void
+}
--- /dev/null
+; ModuleID = '20110226-Ignore-dead-code.ll'
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @main() nounwind {
+.split:
+ br label %0
+
+.loopexit.loopexit: ; preds = %.preheader.us
+ br label %.loopexit.simregexit
+
+.loopexit.simregexit: ; preds = %.loopexit.loopexit, %._crit_edge
+ br label %.loopexit
+
+.loopexit: ; preds = %.loopexit.simregexit
+ %indvar.next16 = add i64 %indvar15, 1
+ %exitcond53 = icmp eq i64 %indvar.next16, 2048
+ br i1 %exitcond53, label %2, label %0
+
+; <label>:0 ; preds = %.loopexit, %.split
+ %indvar15 = phi i64 [ 0, %.split ], [ %indvar.next16, %.loopexit ]
+ br label %.simregentry
+
+.simregentry: ; preds = %0
+ %indvar15.ph = phi i64 [ %indvar15, %0 ]
+ %tmp67 = add i64 %indvar15, 1
+ %i.06 = trunc i64 %tmp67 to i32
+ %tmp25 = add i64 undef, 1
+ %1 = icmp slt i32 %i.06, 2048
+ br i1 %1, label %.lr.ph.preheader, label %._crit_edge.simregexit
+
+.lr.ph.preheader: ; preds = %.simregentry
+ br label %.lr.ph
+
+.lr.ph: ; preds = %.lr.ph, %.lr.ph.preheader
+ %indvar33 = phi i64 [ %indvar.next34, %.lr.ph ], [ 0, %.lr.ph.preheader ]
+ %indvar.next34 = add i64 %indvar33, 1
+ %exitcond40 = icmp eq i64 %indvar.next34, 0
+ br i1 %exitcond40, label %._crit_edge.loopexit, label %.lr.ph
+
+._crit_edge.loopexit: ; preds = %.lr.ph
+ br label %._crit_edge.simregexit
+
+._crit_edge.simregexit: ; preds = %.simregentry, %._crit_edge.loopexit
+ br label %._crit_edge
+
+._crit_edge: ; preds = %._crit_edge.simregexit
+ br i1 false, label %.loopexit.simregexit, label %.preheader.us.preheader
+
+.preheader.us.preheader: ; preds = %._crit_edge
+ br label %.preheader.us
+
+.preheader.us: ; preds = %.preheader.us, %.preheader.us.preheader
+ %exitcond26.old = icmp eq i64 undef, %tmp25
+ br i1 false, label %.loopexit.loopexit, label %.preheader.us
+
+; <label>:2 ; preds = %.loopexit
+ ret void
+}
--- /dev/null
+; ModuleID = '20110226.ll'
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @main() nounwind {
+.split:
+ br label %0
+
+.loopexit: ; preds = %.lr.ph, %0
+ %indvar.next16 = add i64 %indvar15, 1
+ %exitcond53 = icmp eq i64 %indvar.next16, 2048
+ br i1 %exitcond53, label %1, label %0
+
+; <label>:0 ; preds = %.loopexit, %.split
+ %indvar15 = phi i64 [ 0, %.split ], [ %indvar.next16, %.loopexit ]
+ %tmp59 = sub i64 2046, %indvar15
+ %tmp38 = and i64 %tmp59, 4294967295
+ %tmp39 = add i64 %tmp38, 1
+ br i1 false, label %.lr.ph, label %.loopexit
+
+.lr.ph: ; preds = %.lr.ph, %0
+ %indvar33 = phi i64 [ %indvar.next34, %.lr.ph ], [ 0, %0 ]
+ %indvar.next34 = add i64 %indvar33, 1
+ %exitcond40 = icmp eq i64 %indvar.next34, %tmp39
+ br i1 %exitcond40, label %.loopexit, label %.lr.ph
+
+; <label>:1 ; preds = %.loopexit
+ ret void
+}
--- /dev/null
+; ModuleID = 'test1.ll'
+; This should be run without alias analysis enabled.
+;RUN: opt %loadPolly -polly-independent %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %t.02.reg2mem = alloca float
+ br label %entry.split
+
+entry.split: ; preds = %entry
+ store float 0.000000e+00, float* %t.02.reg2mem
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry.split
+ %j.01 = phi i32 [ 0, %entry.split ], [ %inc3, %for.body ]
+ %t.02.reload = load float* %t.02.reg2mem
+ %inc = fadd float %t.02.reload, 1.000000e+00
+ %inc3 = add nsw i32 %j.01, 1
+ %exitcond = icmp eq i32 %inc3, 5000001
+ store float %inc, float* %t.02.reg2mem
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ %conv = fptosi float %inc to i32
+ ret i32 %conv
+}
--- /dev/null
+#define N 10
+
+void foo() {
+ float A[N];
+
+ for (int i=0; i < N; i++)
+ A[i] = 10;
+
+ return;
+}
--- /dev/null
+; ModuleID = 'add_memref.s'
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -disable-verify -S < %s | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+define void @foo() nounwind {
+entry:
+ %A = alloca [10 x float], align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %cmp = icmp slt i32 %i.0, 10
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arrayidx = getelementptr inbounds [10 x float]* %A, i32 0, i32 %i.0
+ store float 1.000000e+01, float* %arrayidx
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+; CHECK: store [10 x float]* %A, [10 x float]**
--- /dev/null
+#define N 10
+
+void foo() {
+ float A[N];
+ int i = 0;
+
+ for (i=0; i < N; i++)
+ A[i] = 10;
+
+ return;
+}
+
+
+int main()
+{
+ foo();
+}
--- /dev/null
+; ModuleID = 'extract_memref.s'
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -S < %s | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+define void @foo() nounwind {
+entry:
+ %A = alloca [10 x float], align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %cmp = icmp slt i32 %i.0, 10
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arrayidx = getelementptr inbounds [10 x float]* %A, i32 0, i32 %i.0
+ store float 1.000000e+01, float* %arrayidx
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
+define i32 @main() nounwind {
+entry:
+ call void @foo()
+ ret i32 0
+}
+; CHECK: store [10 x float]* %A, [10 x float]**
+; CHECK: getelementptr inbounds %foo.omp_subfn.omp.userContext* %omp.userContext1
+; CHECK: load [10 x float]**
+; CHECK: getelementptr inbounds [10 x float]*
--- /dev/null
+#define N 500000
+float A[N];
+int main() {
+ int j, k;
+
+ for(k = 0; k < N; k++)
+ for (j = 0; j <= N; j++)
+ A[j] = k;
+
+ return 0;
+}
--- /dev/null
+; ModuleID = 'test.ll'
+; RUN: opt %loadPolly %defaultOpts -basicaa -polly-codegen -enable-polly-openmp < %s | not FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+@A = common global [500000 x float] zeroinitializer, align 4
+
+define i32 @main() nounwind {
+entry:
+ br label %entry.split
+
+entry.split: ; preds = %entry
+ br label %for.cond1.preheader
+
+for.cond1.preheader: ; preds = %for.inc8, %entry.split
+ %0 = phi i32 [ 0, %entry.split ], [ %inc10, %for.inc8 ]
+ br label %for.body4
+
+for.body4: ; preds = %for.body4, %for.cond1.preheader
+ %j.01 = phi i32 [ 0, %for.cond1.preheader ], [ %inc, %for.body4 ]
+ %arrayidx = getelementptr [500000 x float]* @A, i32 0, i32 %j.01
+ %conv = sitofp i32 %0 to float
+ store float %conv, float* %arrayidx, align 4
+ %inc = add nsw i32 %j.01, 1
+ %exitcond = icmp eq i32 %inc, 500001
+ br i1 %exitcond, label %for.inc8, label %for.body4
+
+for.inc8: ; preds = %for.body4
+ %inc10 = add nsw i32 %0, 1
+ %exitcond3 = icmp eq i32 %inc10, 500000
+ br i1 %exitcond3, label %for.end11, label %for.cond1.preheader
+
+for.end11: ; preds = %for.inc8
+ ret i32 0
+}
+
+
+; CHECK: define internal void @main.omp_subfn.omp_subfn
--- /dev/null
+#define M 1024
+#define N 1024
+#define K 1024
+
+float A[M][K], B[K][N], C[M][N], X[K];
+
+float parallel_loop() {
+ int i, j, k;
+
+ for (i = 0; i < M; i++)
+ for (j = 0; j< N; j++)
+ for (k = 0; k < K; k++)
+ C[i][j] += A[i][k] * B[k][j];
+
+ for (i = 0; i < M; i++)
+ for (j = 0; j < N; j++)
+ for (k = 0; k < K; k++)
+ X[k] += X[k];
+
+ return C[42][42] + X[42];
+}
--- /dev/null
+; ModuleID = 'parallel_loop.s'
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -polly-codegen -enable-polly-openmp -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-cloog -polly-codegen -enable-polly-openmp -analyze < %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-cloog -polly-codegen -enable-polly-openmp -analyze < %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-postfix=tiled -polly-import-jscop-dir=`dirname %s` -polly-cloog -polly-codegen -enable-polly-openmp -analyze -disable-polly-legality < %s | FileCheck -check-prefix=TILED %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x [1024 x float]] zeroinitializer, align 16
+@B = common global [1024 x [1024 x float]] zeroinitializer, align 16
+@C = common global [1024 x [1024 x float]] zeroinitializer, align 16
+@X = common global [1024 x float] zeroinitializer, align 16
+
+define float @parallel_loop() nounwind {
+bb:
+ br label %bb18
+
+bb18: ; preds = %bb32, %bb
+ %indvar9 = phi i64 [ %indvar.next10, %bb32 ], [ 0, %bb ]
+ %exitcond15 = icmp ne i64 %indvar9, 1024
+ br i1 %exitcond15, label %bb19, label %bb33
+
+bb19: ; preds = %bb18
+ br label %bb20
+
+bb20: ; preds = %bb30, %bb19
+ %indvar6 = phi i64 [ %indvar.next7, %bb30 ], [ 0, %bb19 ]
+ %scevgep14 = getelementptr [1024 x [1024 x float]]* @C, i64 0, i64 %indvar9, i64 %indvar6
+ %exitcond12 = icmp ne i64 %indvar6, 1024
+ br i1 %exitcond12, label %bb21, label %bb31
+
+bb21: ; preds = %bb20
+ br label %bb22
+
+bb22: ; preds = %bb28, %bb21
+ %indvar3 = phi i64 [ %indvar.next4, %bb28 ], [ 0, %bb21 ]
+ %scevgep11 = getelementptr [1024 x [1024 x float]]* @A, i64 0, i64 %indvar9, i64 %indvar3
+ %scevgep8 = getelementptr [1024 x [1024 x float]]* @B, i64 0, i64 %indvar3, i64 %indvar6
+ %exitcond5 = icmp ne i64 %indvar3, 1024
+ br i1 %exitcond5, label %bb23, label %bb29
+
+bb23: ; preds = %bb22
+ %tmp = load float* %scevgep11, align 4
+ %tmp24 = load float* %scevgep8, align 4
+ %tmp25 = fmul float %tmp, %tmp24
+ %tmp26 = load float* %scevgep14, align 4
+ %tmp27 = fadd float %tmp26, %tmp25
+ store float %tmp27, float* %scevgep14, align 4
+ br label %bb28
+
+bb28: ; preds = %bb23
+ %indvar.next4 = add i64 %indvar3, 1
+ br label %bb22
+
+bb29: ; preds = %bb22
+ br label %bb30
+
+bb30: ; preds = %bb29
+ %indvar.next7 = add i64 %indvar6, 1
+ br label %bb20
+
+bb31: ; preds = %bb20
+ br label %bb32
+
+bb32: ; preds = %bb31
+ %indvar.next10 = add i64 %indvar9, 1
+ br label %bb18
+
+bb33: ; preds = %bb18
+ br label %bb34
+
+bb34: ; preds = %bb48, %bb33
+ %i.1 = phi i32 [ 0, %bb33 ], [ %tmp49, %bb48 ]
+ %exitcond2 = icmp ne i32 %i.1, 1024
+ br i1 %exitcond2, label %bb35, label %bb50
+
+bb35: ; preds = %bb34
+ br label %bb36
+
+bb36: ; preds = %bb45, %bb35
+ %j.1 = phi i32 [ 0, %bb35 ], [ %tmp46, %bb45 ]
+ %exitcond1 = icmp ne i32 %j.1, 1024
+ br i1 %exitcond1, label %bb37, label %bb47
+
+bb37: ; preds = %bb36
+ br label %bb38
+
+bb38: ; preds = %bb43, %bb37
+ %indvar = phi i64 [ %indvar.next, %bb43 ], [ 0, %bb37 ]
+ %scevgep = getelementptr [1024 x float]* @X, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 1024
+ br i1 %exitcond, label %bb39, label %bb44
+
+bb39: ; preds = %bb38
+ %tmp40 = load float* %scevgep, align 4
+ %tmp41 = load float* %scevgep, align 4
+ %tmp42 = fadd float %tmp41, %tmp40
+ store float %tmp42, float* %scevgep, align 4
+ br label %bb43
+
+bb43: ; preds = %bb39
+ %indvar.next = add i64 %indvar, 1
+ br label %bb38
+
+bb44: ; preds = %bb38
+ br label %bb45
+
+bb45: ; preds = %bb44
+ %tmp46 = add nsw i32 %j.1, 1
+ br label %bb36
+
+bb47: ; preds = %bb36
+ br label %bb48
+
+bb48: ; preds = %bb47
+ %tmp49 = add nsw i32 %i.1, 1
+ br label %bb34
+
+bb50: ; preds = %bb34
+ %tmp51 = load float* getelementptr inbounds ([1024 x [1024 x float]]* @C, i64 0, i64 42, i64 42), align 8
+ %tmp52 = load float* getelementptr inbounds ([1024 x float]* @X, i64 0, i64 42), align 8
+ %tmp53 = fadd float %tmp51, %tmp52
+ ret float %tmp53
+}
+
+; CHECK: for (c2=0;c2<=1023;c2++) {
+; CHECK: for (c4=0;c4<=1023;c4++) {
+; CHECK: for (c6=0;c6<=1023;c6++) {
+; CHECK: Stmt_bb23(c2,c4,c6);
+; CHECK: }
+; CHECK: }
+; CHECK: }
+; CHECK: for (c2=0;c2<=1023;c2++) {
+; CHECK: for (c4=0;c4<=1023;c4++) {
+; CHECK: for (c6=0;c6<=1023;c6++) {
+; CHECK: Stmt_bb39(c2,c4,c6);
+; CHECK: }
+; CHECK: }
+; CHECK: }
+; CHECK: Parallel loop with iterator 'c2' generated
+; CHECK: Parallel loop with iterator 'c6' generated
+; CHECK-NOT: Parallel loop
+
+
+; IMPORT: for (c2=0;c2<=1023;c2++) {
+; IMPORT: for (c4=0;c4<=1023;c4++) {
+; IMPORT: for (c6=0;c6<=1023;c6++) {
+; IMPORT: Stmt_bb23(c2,c4,c6);
+; IMPORT: Stmt_bb39(c2,c4,c6);
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+; IMPORT-NOT: Parallel loop
+
+; TILED: for (c2=0;c2<=1023;c2+=4) {
+; TILED: for (c4=0;c4<=1023;c4+=4) {
+; TILED: for (c6=0;c6<=1023;c6+=4) {
+; TILED: for (c8=c2;c8<=c2+3;c8++) {
+; TILED: for (c9=c4;c9<=c4+3;c9++) {
+; TILED: for (c10=c6;c10<=c6+3;c10++) {
+; TILED: Stmt_bb23(c8,c9,c10);
+; TILED: }
+; TILED: }
+; TILED: }
+; TILED: }
+; TILED: }
+; TILED: }
+; TILED: for (c2=0;c2<=1023;c2+=4) {
+; TILED: for (c4=0;c4<=1023;c4+=4) {
+; TILED: for (c6=0;c6<=1023;c6+=4) {
+; TILED: for (c8=c2;c8<=c2+3;c8++) {
+; TILED: for (c9=c4;c9<=c4+3;c9++) {
+; TILED: for (c10=c6;c10<=c6+3;c10++) {
+; TILED: Stmt_bb39(c8,c9,c10);
+; TILED: }
+; TILED: }
+; TILED: }
+; TILED: }
+; TILED: }
+; TILED: }
+; I am not sure if we actually may have parallel loops here. The dependency
+; analysis does not detect any. This may however be because we do not
+; correctly update the imported schedule. Add a check that hopefully fails
+; after this is corrected. Or someone proves there are no parallel loops and
+; we can remove this comment.
+; TILDED-NOT: Parallel loop
--- /dev/null
+{
+ "name": "bb18 => bb50",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_bb23",
+ "domain": "{ Stmt_bb23[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+ "schedule": "{ Stmt_bb23[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_A[1024i0 + i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_B[i1 + 1024i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_C[1024i0 + i1] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_C[1024i0 + i1] }"
+ }]
+ },
+ {
+ "name": "Stmt_bb39",
+ "domain": "{ Stmt_bb39[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+ "schedule": "{ Stmt_bb39[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_bb39[i0, i1, i2] -> MemRef_X[i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_bb39[i0, i1, i2] -> MemRef_X[i2] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_bb39[i0, i1, i2] -> MemRef_X[i2] }"
+ }]
+ }]
+}
--- /dev/null
+{
+ "name": "bb18 => bb50",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_bb23",
+ "domain": "{ Stmt_bb23[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+ "schedule": "{ Stmt_bb23[i0, i1, i2] -> scattering[0, o0, 0, o1, 0, o2, 0, i0, i1, i2] : (exists e0, e1, e2: 4e0 = o0 and 4e1 = o1 and 4e2 = o2 and o0 <= i0 <= 3 + o0 and o1 <= i1 <= 3 + o1 and o2 <= i2 <= 3 + o2)}",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_A[1024i0 + i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_B[i1 + 1024i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_C[1024i0 + i1] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_bb23[i0, i1, i2] -> MemRef_C[1024i0 + i1] }"
+ }]
+ },
+ {
+ "name": "Stmt_bb39",
+ "domain": "{ Stmt_bb39[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+ "schedule": "{ Stmt_bb39[i0, i1, i2] -> scattering[1, o0, 0, o1, 0, o2, 0, i0, i1, i2] : (exists e0, e1, e2: 4e0 = o0 and 4e1 = o1 and 4e2 = o2 and o0 <= i0 <= 3 + o0 and o1 <= i1 <= 3 + o1 and o2 <= i2 <= 3 + o2)}",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_bb39[i0, i1, i2] -> MemRef_X[i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_bb39[i0, i1, i2] -> MemRef_X[i2] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_bb39[i0, i1, i2] -> MemRef_X[i2] }"
+ }]
+ }]
+}
--- /dev/null
+#define M 1024
+#define N 1024
+#define K 1024
+
+float X[K];
+
+float parallel_loop_simple() {
+ int i, k;
+
+ for (i = 0; i < M; i++)
+ for (k = 0; k < K; k++)
+ X[k] += X[k];
+
+ return X[42];
+}
--- /dev/null
+; ModuleID = 'parallel_loop_simple.s'
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -polly-codegen -enable-polly-openmp -analyze < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@X = common global [1024 x float] zeroinitializer, align 16
+
+define float @parallel_loop_simple() nounwind {
+bb:
+ br label %bb2
+
+bb2: ; preds = %bb10, %bb
+ %i.0 = phi i32 [ 0, %bb ], [ %tmp11, %bb10 ]
+ %exitcond1 = icmp ne i32 %i.0, 1024
+ br i1 %exitcond1, label %bb3, label %bb12
+
+bb3: ; preds = %bb2
+ br label %bb4
+
+bb4: ; preds = %bb8, %bb3
+ %indvar = phi i64 [ %indvar.next, %bb8 ], [ 0, %bb3 ]
+ %scevgep = getelementptr [1024 x float]* @X, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 1024
+ br i1 %exitcond, label %bb5, label %bb9
+
+bb5: ; preds = %bb4
+ %tmp = load float* %scevgep, align 4
+ %tmp6 = load float* %scevgep, align 4
+ %tmp7 = fadd float %tmp6, %tmp
+ store float %tmp7, float* %scevgep, align 4
+ br label %bb8
+
+bb8: ; preds = %bb5
+ %indvar.next = add i64 %indvar, 1
+ br label %bb4
+
+bb9: ; preds = %bb4
+ br label %bb10
+
+bb10: ; preds = %bb9
+ %tmp11 = add nsw i32 %i.0, 1
+ br label %bb2
+
+bb12: ; preds = %bb2
+ %tmp13 = load float* getelementptr inbounds ([1024 x float]* @X, i64 0, i64 42), align 8
+ ret float %tmp13
+}
+
+; CHECK: for (c2=0;c2<=1023;c2++) {
+; CHECK: for (c4=0;c4<=1023;c4++) {
+; CHECK: Stmt_bb5(c2,c4);
+; CHECK: }
+; CHECK: }
+; CHECK: Parallel loop with iterator 'c4' generated
+; CHECK-NOT: Parallel loop
+
--- /dev/null
+#define N 1024
+
+float C[N], X[N];
+
+float parallel_loop_simple2() {
+ int j;
+
+ for (j = 0; j < N; j++)
+ C[j] = j;
+
+ for (j = 0; j < N; j++)
+ X[j] += X[j];
+
+ return C[42] + X[42];
+}
--- /dev/null
+; ModuleID = 'parallel_loop_simple2.s'
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -polly-codegen -enable-polly-openmp -analyze < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@C = common global [1024 x float] zeroinitializer, align 16
+@X = common global [1024 x float] zeroinitializer, align 16
+
+define float @parallel_loop_simple2() nounwind {
+bb:
+ br label %bb5
+
+bb5: ; preds = %bb7, %bb
+ %indvar1 = phi i64 [ %indvar.next2, %bb7 ], [ 0, %bb ]
+ %scevgep4 = getelementptr [1024 x float]* @C, i64 0, i64 %indvar1
+ %j.0 = trunc i64 %indvar1 to i32
+ %exitcond3 = icmp ne i64 %indvar1, 1024
+ br i1 %exitcond3, label %bb6, label %bb8
+
+bb6: ; preds = %bb5
+ %tmp = sitofp i32 %j.0 to float
+ store float %tmp, float* %scevgep4, align 4
+ br label %bb7
+
+bb7: ; preds = %bb6
+ %indvar.next2 = add i64 %indvar1, 1
+ br label %bb5
+
+bb8: ; preds = %bb5
+ br label %bb9
+
+bb9: ; preds = %bb14, %bb8
+ %indvar = phi i64 [ %indvar.next, %bb14 ], [ 0, %bb8 ]
+ %scevgep = getelementptr [1024 x float]* @X, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 1024
+ br i1 %exitcond, label %bb10, label %bb15
+
+bb10: ; preds = %bb9
+ %tmp11 = load float* %scevgep, align 4
+ %tmp12 = load float* %scevgep, align 4
+ %tmp13 = fadd float %tmp12, %tmp11
+ store float %tmp13, float* %scevgep, align 4
+ br label %bb14
+
+bb14: ; preds = %bb10
+ %indvar.next = add i64 %indvar, 1
+ br label %bb9
+
+bb15: ; preds = %bb9
+ %tmp16 = load float* getelementptr inbounds ([1024 x float]* @C, i64 0, i64 42), align 8
+ %tmp17 = load float* getelementptr inbounds ([1024 x float]* @X, i64 0, i64 42), align 8
+ %tmp18 = fadd float %tmp16, %tmp17
+ ret float %tmp18
+}
+
+; CHECK: for (c2=0;c2<=1023;c2++) {
+; CHECK: Stmt_bb6(c2);
+; CHECK: }
+; CHECK: for (c2=0;c2<=1023;c2++) {
+; CHECK: Stmt_bb10(c2);
+; CHECK: }
+; CHECK: Parallel loop with iterator 'c2' generated
+; CHECK: Parallel loop with iterator 'c2' generated
+; CHECK-NOT: Parallel loop
--- /dev/null
+#include <string.h>
+#define N 10
+
+double A[N];
+double B[N];
+
+void loop_openmp() {
+ for (int i = 0; i < N; i++) {
+ for (int j = 0; j < N; j++) {
+ A[j] += j;
+ }
+ }
+}
+
+int main () {
+ memset(A, 0, sizeof(float) * N);
+
+ loop_openmp();
+
+ return 0;
+}
+
--- /dev/null
+; ModuleID = 'simple_nested_loop.s'
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -S %s | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+@A = common global [10 x double] zeroinitializer, align 4
+@B = common global [10 x double] zeroinitializer, align 4
+
+define void @loop_openmp() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc10, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc12, %for.inc10 ]
+ %exitcond1 = icmp ne i32 %i.0, 10
+ br i1 %exitcond1, label %for.body, label %for.end13
+
+for.body: ; preds = %for.cond
+ br label %for.cond2
+
+for.cond2: ; preds = %for.inc, %for.body
+ %tmp = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+ %arrayidx = getelementptr [10 x double]* @A, i32 0, i32 %tmp
+ %exitcond = icmp ne i32 %tmp, 10
+ br i1 %exitcond, label %for.body5, label %for.end
+
+for.body5: ; preds = %for.cond2
+ %conv = sitofp i32 %tmp to double
+ %tmp8 = load double* %arrayidx, align 4
+ %add = fadd double %tmp8, %conv
+ store double %add, double* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body5
+ %inc = add nsw i32 %tmp, 1
+ br label %for.cond2
+
+for.end: ; preds = %for.cond2
+ br label %for.inc10
+
+for.inc10: ; preds = %for.end
+ %inc12 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end13: ; preds = %for.cond
+ ret void
+}
+
+define i32 @main() nounwind {
+entry:
+ call void @llvm.memset.p0i8.i32(i8* bitcast ([10 x double]* @A to i8*), i8 0, i32 40, i32 4, i1 false)
+ call void @loop_openmp()
+ ret i32 0
+}
+
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
+
+; CHECK: %omp.userContext = alloca %loop_openmp.omp_subfn.omp.userContext
+; CHECK: getelementptr inbounds %loop_openmp.omp_subfn.omp.userContext* %omp.userContext
+; CHECK: %omp_data = bitcast %loop_openmp.omp_subfn.omp.userContext* %omp.userContext to i8*
+; CHECK: @GOMP_parallel_loop_runtime_start(void (i8*)* @loop_openmp.omp_subfn, i8* %omp_data
+; CHECK: call void @loop_openmp.omp_subfn(i8* %omp_data)
+; CHECK: %omp.userContext1 = bitcast i8* %omp.userContext to %loop_openmp.omp_subfn.omp.userContext*
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#define N 5
+
+float A[N];
+float B[N];
+
+void loop1_openmp() {
+ for (int i = 0; i <= N; i++)
+ A[i] = 0;
+
+ for (int j = 0; j <= N; j++)
+ for (int k = 0; k <= N; k++)
+ B[k] += j;
+}
+
+int main () {
+ int i;
+ memset(A, 0, sizeof(float) * N);
+ memset(B, 0, sizeof(float) * N);
+
+ loop1_openmp();
+
+ return 0;
+}
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -S %s | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+@A = common global [5 x float] zeroinitializer, align 4
+@B = common global [5 x float] zeroinitializer, align 4
+
+define void @loop1_openmp() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %arrayidx = getelementptr [5 x float]* @A, i32 0, i32 %i.0
+ %exitcond2 = icmp ne i32 %i.0, 6
+ br i1 %exitcond2, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ store float 0.000000e+00, float* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ br label %for.cond4
+
+for.cond4: ; preds = %for.inc21, %for.end
+ %tmp = phi i32 [ 0, %for.end ], [ %inc23, %for.inc21 ]
+ %exitcond1 = icmp ne i32 %tmp, 6
+ br i1 %exitcond1, label %for.body7, label %for.end24
+
+for.body7: ; preds = %for.cond4
+ br label %for.cond9
+
+for.cond9: ; preds = %for.inc17, %for.body7
+ %k.0 = phi i32 [ 0, %for.body7 ], [ %inc19, %for.inc17 ]
+ %arrayidx15 = getelementptr [5 x float]* @B, i32 0, i32 %k.0
+ %exitcond = icmp ne i32 %k.0, 6
+ br i1 %exitcond, label %for.body12, label %for.end20
+
+for.body12: ; preds = %for.cond9
+ %conv = sitofp i32 %tmp to float
+ %tmp16 = load float* %arrayidx15, align 4
+ %add = fadd float %tmp16, %conv
+ store float %add, float* %arrayidx15, align 4
+ br label %for.inc17
+
+for.inc17: ; preds = %for.body12
+ %inc19 = add nsw i32 %k.0, 1
+ br label %for.cond9
+
+for.end20: ; preds = %for.cond9
+ br label %for.inc21
+
+for.inc21: ; preds = %for.end20
+ %inc23 = add nsw i32 %tmp, 1
+ br label %for.cond4
+
+for.end24: ; preds = %for.cond4
+ ret void
+}
+
+define i32 @main() nounwind {
+entry:
+ call void @llvm.memset.p0i8.i32(i8* bitcast ([5 x float]* @A to i8*), i8 0, i32 20, i32 4, i1 false)
+ call void @llvm.memset.p0i8.i32(i8* bitcast ([5 x float]* @B to i8*), i8 0, i32 20, i32 4, i1 false)
+ call void @loop1_openmp()
+ ret i32 0
+}
+
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
+
+; CHECK: loop1_openmp.omp_subfn.omp.userContext
+; CHECK: loop1_openmp.omp_subfn1.omp.userContext
--- /dev/null
+#include <string.h>
+#define N 10240000
+
+float A[N];
+float B[N];
+
+void loop1_openmp() {
+ for (int i = 0; i <= N; i++)
+ A[i] = 0;
+ for (int j = 0; j <= N; j++)
+ B[j] = 0;
+}
+
+
+int main () {
+ int i;
+ memset(A, 0, sizeof(float) * N);
+ memset(B, 1, sizeof(float) * N);
+
+ loop1_openmp();
+
+ return 0;
+}
+
--- /dev/null
+; ModuleID = 'two_loop.s'
+; RUN: opt %loadPolly %defaultOpts -mem2reg -polly-codegen -enable-polly-openmp -S < %s
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+target triple = "i386-pc-linux-gnu"
+
+@A = common global [10240000 x float] zeroinitializer, align 4
+@B = common global [10240000 x float] zeroinitializer, align 4
+
+define void @loop1_openmp() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %arrayidx = getelementptr [10240000 x float]* @A, i32 0, i32 %i.0
+ %exitcond1 = icmp ne i32 %i.0, 10240001
+ br i1 %exitcond1, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ store float 0.000000e+00, float* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ br label %for.cond4
+
+for.cond4: ; preds = %for.inc10, %for.end
+ %j.0 = phi i32 [ 0, %for.end ], [ %inc12, %for.inc10 ]
+ %arrayidx9 = getelementptr [10240000 x float]* @B, i32 0, i32 %j.0
+ %exitcond = icmp ne i32 %j.0, 10240001
+ br i1 %exitcond, label %for.body7, label %for.end13
+
+for.body7: ; preds = %for.cond4
+ store float 0.000000e+00, float* %arrayidx9, align 4
+ br label %for.inc10
+
+for.inc10: ; preds = %for.body7
+ %inc12 = add nsw i32 %j.0, 1
+ br label %for.cond4
+
+for.end13: ; preds = %for.cond4
+ ret void
+}
+
+define i32 @main() nounwind {
+entry:
+ call void @llvm.memset.p0i8.i32(i8* bitcast ([10240000 x float]* @A to i8*), i8 0, i32 40960000, i32 4, i1 false)
+ call void @llvm.memset.p0i8.i32(i8* bitcast ([10240000 x float]* @B to i8*), i8 1, i32 40960000, i32 4, i1 false)
+ call void @loop1_openmp()
+ ret i32 0
+}
+
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct..0__pthread_mutex_s = type { i32, i32, i32, i32, i32, i32, %struct.__pthread_list_t }
+%struct.__pthread_list_t = type { %struct.__pthread_list_t*, %struct.__pthread_list_t* }
+%union.pthread_attr_t = type { i64, [12 x i32] }
+%union.pthread_mutex_t = type { %struct..0__pthread_mutex_s }
+%union.pthread_mutexattr_t = type { i32 }
+
+@_ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)* @pthread_once ; <i32 (i32*, void ()*)*> [#uses=0]
+@_ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)* @pthread_getspecific ; <i8* (i32)*> [#uses=0]
+@_ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)* @pthread_setspecific ; <i32 (i32, i8*)*> [#uses=0]
+@_ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_ = alias weak i32 (i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*)* @pthread_create ; <i32 (i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*)*> [#uses=0]
+@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i64)* @pthread_cancel ; <i32 (i64)*> [#uses=0]
+@_ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_lock ; <i32 (%union.pthread_mutex_t*)*> [#uses=0]
+@_ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_trylock ; <i32 (%union.pthread_mutex_t*)*> [#uses=0]
+@_ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_unlock ; <i32 (%union.pthread_mutex_t*)*> [#uses=0]
+@_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutex_t*, %union.pthread_mutexattr_t*)* @pthread_mutex_init ; <i32 (%union.pthread_mutex_t*, %union.pthread_mutexattr_t*)*> [#uses=0]
+@_ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*, void (i8*)*)* @pthread_key_create ; <i32 (i32*, void (i8*)*)*> [#uses=0]
+@_ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)* @pthread_key_delete ; <i32 (i32)*> [#uses=0]
+@_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_init ; <i32 (%union.pthread_mutexattr_t*)*> [#uses=0]
+@_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%union.pthread_mutexattr_t*, i32)* @pthread_mutexattr_settype ; <i32 (%union.pthread_mutexattr_t*, i32)*> [#uses=0]
+@_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_destroy ; <i32 (%union.pthread_mutexattr_t*)*> [#uses=0]
+
+define void @_ZL6createP6node_tii3v_tS1_d() {
+entry:
+ br i1 undef, label %bb, label %bb5
+
+bb: ; preds = %entry
+ br i1 false, label %bb1, label %bb3
+
+bb1: ; preds = %bb
+ br label %bb3
+
+bb3: ; preds = %bb1, %bb
+ %iftmp.99.0 = phi i64 [ undef, %bb1 ], [ 1, %bb ] ; <i64> [#uses=0]
+ br label %bb5
+
+bb5: ; preds = %bb3, %entry
+ br i1 undef, label %return, label %bb7
+
+bb7: ; preds = %bb5
+ unreachable
+
+return: ; preds = %bb5
+ ret void
+}
+
+declare i32 @pthread_once(i32*, void ()*)
+
+declare i8* @pthread_getspecific(i32)
+
+declare i32 @pthread_setspecific(i32, i8*)
+
+declare i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*)
+
+declare i32 @pthread_cancel(i64)
+
+declare i32 @pthread_mutex_lock(%union.pthread_mutex_t*)
+
+declare i32 @pthread_mutex_trylock(%union.pthread_mutex_t*)
+
+declare i32 @pthread_mutex_unlock(%union.pthread_mutex_t*)
+
+declare i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*)
+
+declare i32 @pthread_key_create(i32*, void (i8*)*)
+
+declare i32 @pthread_key_delete(i32)
+
+declare i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*)
+
+declare i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32)
+
+declare i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*)
--- /dev/null
+#include <string.h>
+int A[1];
+
+void constant_condition () {
+ int a = 0;
+ int b = 0;
+
+ if (a == b)
+ A[0] = 0;
+ else
+ A[0] = 1;
+}
+
+int main () {
+ int i;
+
+ A[0] = 2;
+
+ constant_condition();
+
+ return A[0];
+}
+
--- /dev/null
+;RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+@A = common global [1 x i32] zeroinitializer, align 4 ; <[1 x i32]*> [#uses=1]
+
+define void @constant_condition() nounwind {
+bb:
+ %tmp = icmp eq i32 0, 0 ; <i1> [#uses=0]
+ br i1 true, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ store i32 0, i32* getelementptr inbounds ([1 x i32]* @A, i32 0, i32 0)
+ br label %bb3
+
+bb2: ; preds = %bb
+ store i32 1, i32* getelementptr inbounds ([1 x i32]* @A, i32 0, i32 0)
+ br label %bb3
+
+bb3: ; preds = %bb2, %bb1
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+bb:
+ store i32 2, i32* getelementptr inbounds ([1 x i32]* @A, i32 0, i32 0)
+ call void @constant_condition()
+ %tmp = load i32* getelementptr inbounds ([1 x i32]* @A, i32 0, i32 0) ; <i32> [#uses=1]
+ ret i32 %tmp
+}
+
+
+; CHECK: Stmt_bb1();
--- /dev/null
+#define M 36
+#define N 36
+#define K 36
+#define alpha 1
+#define beta 1
+double A[M][K+13];
+double B[K][N+13];
+double C[M][N+13];
+
+#include <stdio.h>
+
+void init_array()
+{
+ int i, j;
+
+ for (i=0; i<N; i++) {
+ for (j=0; j<N; j++) {
+ A[i][j] = (i + j);
+ // We do not want to optimize this.
+ __sync_synchronize();
+ B[i][j] = (double)(i*j);
+ C[i][j] = 0.0;
+ }
+ }
+}
+
+
+void print_array()
+{
+ int i, j;
+
+ for (i=0; i<N; i++) {
+ for (j=0; j<N; j++) {
+ fprintf(stdout, "%lf ", C[i][j]);
+ if (j%80 == 79) fprintf(stdout, "\n");
+ }
+ fprintf(stdout, "\n");
+ }
+}
+
+
+void do_pluto_matmult(void) {
+ int i, j, k;
+
+ __sync_synchronize();
+ i = 0;
+ do {
+ j = 0;
+ do {
+ k = 0;
+ do {
+ C[i][j] = beta*C[i][j] + alpha*A[i][k] * B[k][j];
+ ++k;
+ } while (k < K);
+ ++j;
+ } while (j < N);
+ ++i;
+ } while (i < M);
+ __sync_synchronize();
+}
+
+int main()
+{
+ register double s;
+
+ init_array();
+
+#pragma scop
+ do_pluto_matmult();
+#pragma endscop
+ print_array();
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -disable-output < %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-cloog -analyze < %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-import-jscop-postfix=valid_reverse -polly-cloog -analyze < %s | FileCheck -check-prefix=REVERSE %s > /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-import-jscop-postfix=invalid_reverse -polly-cloog -analyze < %s 2>&1 | FileCheck -check-prefix=INVALID %s > /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-cloog -analyze < %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-codegen < %s | lli | diff %s.result -
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-codegen -S < %s | FileCheck -check-prefix=CODEGEN %s
+
+
+; ModuleID = 'do_pluto_matmult.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [36 x [49 x double]] zeroinitializer, align 8 ; <[36 x [49 x double]]*> [#uses=3]
+@B = common global [36 x [49 x double]] zeroinitializer, align 8 ; <[36 x [49 x double]]*> [#uses=3]
+@C = common global [36 x [49 x double]] zeroinitializer, align 8 ; <[36 x [49 x double]]*> [#uses=4]
+@stdout = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=3]
+@.str = private constant [5 x i8] c"%lf \00" ; <[5 x i8]*> [#uses=1]
+@.str1 = private constant [2 x i8] c"\0A\00" ; <[2 x i8]*> [#uses=1]
+
+define void @init_array() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc29, %entry
+ %indvar1 = phi i64 [ %indvar.next2, %for.inc29 ], [ 0, %entry ] ; <i64> [#uses=7]
+ %exitcond6 = icmp ne i64 %indvar1, 36 ; <i1> [#uses=1]
+ br i1 %exitcond6, label %for.body, label %for.end32
+
+for.body: ; preds = %for.cond
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc, %for.body
+ %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body ] ; <i64> [#uses=7]
+ %tmp7 = add i64 %indvar1, %indvar ; <i64> [#uses=1]
+ %add = trunc i64 %tmp7 to i32 ; <i32> [#uses=1]
+ %arrayidx10 = getelementptr [36 x [49 x double]]* @A, i64 0, i64 %indvar1, i64 %indvar ; <double*> [#uses=1]
+ %tmp9 = mul i64 %indvar1, %indvar ; <i64> [#uses=1]
+ %mul = trunc i64 %tmp9 to i32 ; <i32> [#uses=1]
+ %arrayidx20 = getelementptr [36 x [49 x double]]* @B, i64 0, i64 %indvar1, i64 %indvar ; <double*> [#uses=1]
+ %arrayidx27 = getelementptr [36 x [49 x double]]* @C, i64 0, i64 %indvar1, i64 %indvar ; <double*> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 36 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body4, label %for.end
+
+for.body4: ; preds = %for.cond1
+ %conv = sitofp i32 %add to double ; <double> [#uses=1]
+ store double %conv, double* %arrayidx10
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %conv13 = sitofp i32 %mul to double ; <double> [#uses=1]
+ store double %conv13, double* %arrayidx20
+ store double 0.000000e+00, double* %arrayidx27
+ br label %for.inc
+
+for.inc: ; preds = %for.body4
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br label %for.inc29
+
+for.inc29: ; preds = %for.end
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end32: ; preds = %for.cond
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define void @print_array() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc18, %entry
+ %indvar1 = phi i64 [ %indvar.next2, %for.inc18 ], [ 0, %entry ] ; <i64> [#uses=3]
+ %exitcond3 = icmp ne i64 %indvar1, 36 ; <i1> [#uses=1]
+ br i1 %exitcond3, label %for.body, label %for.end21
+
+for.body: ; preds = %for.cond
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc, %for.body
+ %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body ] ; <i64> [#uses=3]
+ %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ] ; <i32> [#uses=2]
+ %arrayidx9 = getelementptr [36 x [49 x double]]* @C, i64 0, i64 %indvar1, i64 %indvar ; <double*> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 36 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body4, label %for.end
+
+for.body4: ; preds = %for.cond1
+ %tmp5 = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1]
+ %tmp10 = load double* %arrayidx9 ; <double> [#uses=1]
+ %call = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %tmp5, i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), double %tmp10) ; <i32> [#uses=0]
+ %cmp12 = icmp eq i32 %j.0, 79 ; <i1> [#uses=1]
+ br i1 %cmp12, label %if.then, label %if.end
+
+if.then: ; preds = %for.body4
+ %tmp13 = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1]
+ %call14 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %tmp13, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0)) ; <i32> [#uses=0]
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body4
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %inc = add nsw i32 %j.0, 1 ; <i32> [#uses=1]
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ %tmp16 = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1]
+ %call17 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %tmp16, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0)) ; <i32> [#uses=0]
+ br label %for.inc18
+
+for.inc18: ; preds = %for.end
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end21: ; preds = %for.cond
+ ret void
+}
+
+declare i32 @fprintf(%struct._IO_FILE*, i8*, ...)
+
+define void @do_pluto_matmult() nounwind {
+entry:
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %do.body
+
+do.body: ; preds = %do.cond42, %entry
+ %indvar3 = phi i64 [ %indvar.next4, %do.cond42 ], [ 0, %entry ] ; <i64> [#uses=3]
+ br label %do.body1
+
+do.body1: ; preds = %do.cond36, %do.body
+ %indvar1 = phi i64 [ %indvar.next2, %do.cond36 ], [ 0, %do.body ] ; <i64> [#uses=3]
+ %arrayidx5 = getelementptr [36 x [49 x double]]* @C, i64 0, i64 %indvar3, i64 %indvar1 ; <double*> [#uses=2]
+ br label %do.body2
+
+do.body2: ; preds = %do.cond, %do.body1
+ %indvar = phi i64 [ %indvar.next, %do.cond ], [ 0, %do.body1 ] ; <i64> [#uses=3]
+ %arrayidx13 = getelementptr [36 x [49 x double]]* @A, i64 0, i64 %indvar3, i64 %indvar ; <double*> [#uses=1]
+ %arrayidx22 = getelementptr [36 x [49 x double]]* @B, i64 0, i64 %indvar, i64 %indvar1 ; <double*> [#uses=1]
+ %tmp6 = load double* %arrayidx5 ; <double> [#uses=1]
+ %mul = fmul double 1.000000e+00, %tmp6 ; <double> [#uses=1]
+ %tmp14 = load double* %arrayidx13 ; <double> [#uses=1]
+ %mul15 = fmul double 1.000000e+00, %tmp14 ; <double> [#uses=1]
+ %tmp23 = load double* %arrayidx22 ; <double> [#uses=1]
+ %mul24 = fmul double %mul15, %tmp23 ; <double> [#uses=1]
+ %add = fadd double %mul, %mul24 ; <double> [#uses=1]
+ store double %add, double* %arrayidx5
+ br label %do.cond
+
+do.cond: ; preds = %do.body2
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond = icmp ne i64 %indvar.next, 36 ; <i1> [#uses=1]
+ br i1 %exitcond, label %do.body2, label %do.end
+
+do.end: ; preds = %do.cond
+ br label %do.cond36
+
+do.cond36: ; preds = %do.end
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=2]
+ %exitcond5 = icmp ne i64 %indvar.next2, 36 ; <i1> [#uses=1]
+ br i1 %exitcond5, label %do.body1, label %do.end39
+
+do.end39: ; preds = %do.cond36
+ br label %do.cond42
+
+do.cond42: ; preds = %do.end39
+ %indvar.next4 = add i64 %indvar3, 1 ; <i64> [#uses=2]
+ %exitcond6 = icmp ne i64 %indvar.next4, 36 ; <i1> [#uses=1]
+ br i1 %exitcond6, label %do.body, label %do.end45
+
+do.end45: ; preds = %do.cond42
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+define i32 @main() nounwind {
+entry:
+ call void @init_array()
+ call void @do_pluto_matmult()
+ call void @print_array()
+ ret i32 0
+}
+
+; CHECK: for (c2=0;c2<=35;c2++) {
+; CHECK: for (c4=0;c4<=35;c4++) {
+; CHECK: for (c6=0;c6<=35;c6++) {
+; CHECK: Stmt_do_body2(c2,c4,c6);
+; CHECK: }
+; CHECK: }
+; CHECK: }
+
+
+; Do not dump the complete CLooG output. New CLooG version optimize more
+; in this test case.
+; IMPORT: for (c2=0;c2<=35;c2+=4) {
+; IMPORT: c3<=min(35,c2+3);c3++) {
+; IMPORT: for (c6=0;c6<=35;c6+=4) {
+; IMPORT: c7<=min(35,c6+3);c7++) {
+; IMPORT: for (c10=0;c10<=35;c10+=4) {
+; IMPORT: c11<=min(35,c10+3);c11++)
+; IMPORT: {
+; IMPORT: Stmt_do_body2(c3,c7,c11);
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+
+
+; CODEGEN: polly.stmt_do.body2
+
+; REVERSE: for (c2=-35;c2<=0;c2++) {
+; REVERSE: for (c4=-35;c4<=0;c4++) {
+; REVERSE: for (c6=0;c6<=35;c6++) {
+; REVERSE: Stmt_do_body2(-c2,-c4,c6);
+; REVERSE: }
+; REVERSE: }
+; REVERSE: }
+
+; INVALID: file contains a scattering that changes the dependences.
+
+
+
--- /dev/null
+0.000000 14910.000000 29820.000000 44730.000000 59640.000000 74550.000000 89460.000000 104370.000000 119280.000000 134190.000000 149100.000000 164010.000000 178920.000000 193830.000000 208740.000000 223650.000000 238560.000000 253470.000000 268380.000000 283290.000000 298200.000000 313110.000000 328020.000000 342930.000000 357840.000000 372750.000000 387660.000000 402570.000000 417480.000000 432390.000000 447300.000000 462210.000000 477120.000000 492030.000000 506940.000000 521850.000000
+0.000000 15540.000000 31080.000000 46620.000000 62160.000000 77700.000000 93240.000000 108780.000000 124320.000000 139860.000000 155400.000000 170940.000000 186480.000000 202020.000000 217560.000000 233100.000000 248640.000000 264180.000000 279720.000000 295260.000000 310800.000000 326340.000000 341880.000000 357420.000000 372960.000000 388500.000000 404040.000000 419580.000000 435120.000000 450660.000000 466200.000000 481740.000000 497280.000000 512820.000000 528360.000000 543900.000000
+0.000000 16170.000000 32340.000000 48510.000000 64680.000000 80850.000000 97020.000000 113190.000000 129360.000000 145530.000000 161700.000000 177870.000000 194040.000000 210210.000000 226380.000000 242550.000000 258720.000000 274890.000000 291060.000000 307230.000000 323400.000000 339570.000000 355740.000000 371910.000000 388080.000000 404250.000000 420420.000000 436590.000000 452760.000000 468930.000000 485100.000000 501270.000000 517440.000000 533610.000000 549780.000000 565950.000000
+0.000000 16800.000000 33600.000000 50400.000000 67200.000000 84000.000000 100800.000000 117600.000000 134400.000000 151200.000000 168000.000000 184800.000000 201600.000000 218400.000000 235200.000000 252000.000000 268800.000000 285600.000000 302400.000000 319200.000000 336000.000000 352800.000000 369600.000000 386400.000000 403200.000000 420000.000000 436800.000000 453600.000000 470400.000000 487200.000000 504000.000000 520800.000000 537600.000000 554400.000000 571200.000000 588000.000000
+0.000000 17430.000000 34860.000000 52290.000000 69720.000000 87150.000000 104580.000000 122010.000000 139440.000000 156870.000000 174300.000000 191730.000000 209160.000000 226590.000000 244020.000000 261450.000000 278880.000000 296310.000000 313740.000000 331170.000000 348600.000000 366030.000000 383460.000000 400890.000000 418320.000000 435750.000000 453180.000000 470610.000000 488040.000000 505470.000000 522900.000000 540330.000000 557760.000000 575190.000000 592620.000000 610050.000000
+0.000000 18060.000000 36120.000000 54180.000000 72240.000000 90300.000000 108360.000000 126420.000000 144480.000000 162540.000000 180600.000000 198660.000000 216720.000000 234780.000000 252840.000000 270900.000000 288960.000000 307020.000000 325080.000000 343140.000000 361200.000000 379260.000000 397320.000000 415380.000000 433440.000000 451500.000000 469560.000000 487620.000000 505680.000000 523740.000000 541800.000000 559860.000000 577920.000000 595980.000000 614040.000000 632100.000000
+0.000000 18690.000000 37380.000000 56070.000000 74760.000000 93450.000000 112140.000000 130830.000000 149520.000000 168210.000000 186900.000000 205590.000000 224280.000000 242970.000000 261660.000000 280350.000000 299040.000000 317730.000000 336420.000000 355110.000000 373800.000000 392490.000000 411180.000000 429870.000000 448560.000000 467250.000000 485940.000000 504630.000000 523320.000000 542010.000000 560700.000000 579390.000000 598080.000000 616770.000000 635460.000000 654150.000000
+0.000000 19320.000000 38640.000000 57960.000000 77280.000000 96600.000000 115920.000000 135240.000000 154560.000000 173880.000000 193200.000000 212520.000000 231840.000000 251160.000000 270480.000000 289800.000000 309120.000000 328440.000000 347760.000000 367080.000000 386400.000000 405720.000000 425040.000000 444360.000000 463680.000000 483000.000000 502320.000000 521640.000000 540960.000000 560280.000000 579600.000000 598920.000000 618240.000000 637560.000000 656880.000000 676200.000000
+0.000000 19950.000000 39900.000000 59850.000000 79800.000000 99750.000000 119700.000000 139650.000000 159600.000000 179550.000000 199500.000000 219450.000000 239400.000000 259350.000000 279300.000000 299250.000000 319200.000000 339150.000000 359100.000000 379050.000000 399000.000000 418950.000000 438900.000000 458850.000000 478800.000000 498750.000000 518700.000000 538650.000000 558600.000000 578550.000000 598500.000000 618450.000000 638400.000000 658350.000000 678300.000000 698250.000000
+0.000000 20580.000000 41160.000000 61740.000000 82320.000000 102900.000000 123480.000000 144060.000000 164640.000000 185220.000000 205800.000000 226380.000000 246960.000000 267540.000000 288120.000000 308700.000000 329280.000000 349860.000000 370440.000000 391020.000000 411600.000000 432180.000000 452760.000000 473340.000000 493920.000000 514500.000000 535080.000000 555660.000000 576240.000000 596820.000000 617400.000000 637980.000000 658560.000000 679140.000000 699720.000000 720300.000000
+0.000000 21210.000000 42420.000000 63630.000000 84840.000000 106050.000000 127260.000000 148470.000000 169680.000000 190890.000000 212100.000000 233310.000000 254520.000000 275730.000000 296940.000000 318150.000000 339360.000000 360570.000000 381780.000000 402990.000000 424200.000000 445410.000000 466620.000000 487830.000000 509040.000000 530250.000000 551460.000000 572670.000000 593880.000000 615090.000000 636300.000000 657510.000000 678720.000000 699930.000000 721140.000000 742350.000000
+0.000000 21840.000000 43680.000000 65520.000000 87360.000000 109200.000000 131040.000000 152880.000000 174720.000000 196560.000000 218400.000000 240240.000000 262080.000000 283920.000000 305760.000000 327600.000000 349440.000000 371280.000000 393120.000000 414960.000000 436800.000000 458640.000000 480480.000000 502320.000000 524160.000000 546000.000000 567840.000000 589680.000000 611520.000000 633360.000000 655200.000000 677040.000000 698880.000000 720720.000000 742560.000000 764400.000000
+0.000000 22470.000000 44940.000000 67410.000000 89880.000000 112350.000000 134820.000000 157290.000000 179760.000000 202230.000000 224700.000000 247170.000000 269640.000000 292110.000000 314580.000000 337050.000000 359520.000000 381990.000000 404460.000000 426930.000000 449400.000000 471870.000000 494340.000000 516810.000000 539280.000000 561750.000000 584220.000000 606690.000000 629160.000000 651630.000000 674100.000000 696570.000000 719040.000000 741510.000000 763980.000000 786450.000000
+0.000000 23100.000000 46200.000000 69300.000000 92400.000000 115500.000000 138600.000000 161700.000000 184800.000000 207900.000000 231000.000000 254100.000000 277200.000000 300300.000000 323400.000000 346500.000000 369600.000000 392700.000000 415800.000000 438900.000000 462000.000000 485100.000000 508200.000000 531300.000000 554400.000000 577500.000000 600600.000000 623700.000000 646800.000000 669900.000000 693000.000000 716100.000000 739200.000000 762300.000000 785400.000000 808500.000000
+0.000000 23730.000000 47460.000000 71190.000000 94920.000000 118650.000000 142380.000000 166110.000000 189840.000000 213570.000000 237300.000000 261030.000000 284760.000000 308490.000000 332220.000000 355950.000000 379680.000000 403410.000000 427140.000000 450870.000000 474600.000000 498330.000000 522060.000000 545790.000000 569520.000000 593250.000000 616980.000000 640710.000000 664440.000000 688170.000000 711900.000000 735630.000000 759360.000000 783090.000000 806820.000000 830550.000000
+0.000000 24360.000000 48720.000000 73080.000000 97440.000000 121800.000000 146160.000000 170520.000000 194880.000000 219240.000000 243600.000000 267960.000000 292320.000000 316680.000000 341040.000000 365400.000000 389760.000000 414120.000000 438480.000000 462840.000000 487200.000000 511560.000000 535920.000000 560280.000000 584640.000000 609000.000000 633360.000000 657720.000000 682080.000000 706440.000000 730800.000000 755160.000000 779520.000000 803880.000000 828240.000000 852600.000000
+0.000000 24990.000000 49980.000000 74970.000000 99960.000000 124950.000000 149940.000000 174930.000000 199920.000000 224910.000000 249900.000000 274890.000000 299880.000000 324870.000000 349860.000000 374850.000000 399840.000000 424830.000000 449820.000000 474810.000000 499800.000000 524790.000000 549780.000000 574770.000000 599760.000000 624750.000000 649740.000000 674730.000000 699720.000000 724710.000000 749700.000000 774690.000000 799680.000000 824670.000000 849660.000000 874650.000000
+0.000000 25620.000000 51240.000000 76860.000000 102480.000000 128100.000000 153720.000000 179340.000000 204960.000000 230580.000000 256200.000000 281820.000000 307440.000000 333060.000000 358680.000000 384300.000000 409920.000000 435540.000000 461160.000000 486780.000000 512400.000000 538020.000000 563640.000000 589260.000000 614880.000000 640500.000000 666120.000000 691740.000000 717360.000000 742980.000000 768600.000000 794220.000000 819840.000000 845460.000000 871080.000000 896700.000000
+0.000000 26250.000000 52500.000000 78750.000000 105000.000000 131250.000000 157500.000000 183750.000000 210000.000000 236250.000000 262500.000000 288750.000000 315000.000000 341250.000000 367500.000000 393750.000000 420000.000000 446250.000000 472500.000000 498750.000000 525000.000000 551250.000000 577500.000000 603750.000000 630000.000000 656250.000000 682500.000000 708750.000000 735000.000000 761250.000000 787500.000000 813750.000000 840000.000000 866250.000000 892500.000000 918750.000000
+0.000000 26880.000000 53760.000000 80640.000000 107520.000000 134400.000000 161280.000000 188160.000000 215040.000000 241920.000000 268800.000000 295680.000000 322560.000000 349440.000000 376320.000000 403200.000000 430080.000000 456960.000000 483840.000000 510720.000000 537600.000000 564480.000000 591360.000000 618240.000000 645120.000000 672000.000000 698880.000000 725760.000000 752640.000000 779520.000000 806400.000000 833280.000000 860160.000000 887040.000000 913920.000000 940800.000000
+0.000000 27510.000000 55020.000000 82530.000000 110040.000000 137550.000000 165060.000000 192570.000000 220080.000000 247590.000000 275100.000000 302610.000000 330120.000000 357630.000000 385140.000000 412650.000000 440160.000000 467670.000000 495180.000000 522690.000000 550200.000000 577710.000000 605220.000000 632730.000000 660240.000000 687750.000000 715260.000000 742770.000000 770280.000000 797790.000000 825300.000000 852810.000000 880320.000000 907830.000000 935340.000000 962850.000000
+0.000000 28140.000000 56280.000000 84420.000000 112560.000000 140700.000000 168840.000000 196980.000000 225120.000000 253260.000000 281400.000000 309540.000000 337680.000000 365820.000000 393960.000000 422100.000000 450240.000000 478380.000000 506520.000000 534660.000000 562800.000000 590940.000000 619080.000000 647220.000000 675360.000000 703500.000000 731640.000000 759780.000000 787920.000000 816060.000000 844200.000000 872340.000000 900480.000000 928620.000000 956760.000000 984900.000000
+0.000000 28770.000000 57540.000000 86310.000000 115080.000000 143850.000000 172620.000000 201390.000000 230160.000000 258930.000000 287700.000000 316470.000000 345240.000000 374010.000000 402780.000000 431550.000000 460320.000000 489090.000000 517860.000000 546630.000000 575400.000000 604170.000000 632940.000000 661710.000000 690480.000000 719250.000000 748020.000000 776790.000000 805560.000000 834330.000000 863100.000000 891870.000000 920640.000000 949410.000000 978180.000000 1006950.000000
+0.000000 29400.000000 58800.000000 88200.000000 117600.000000 147000.000000 176400.000000 205800.000000 235200.000000 264600.000000 294000.000000 323400.000000 352800.000000 382200.000000 411600.000000 441000.000000 470400.000000 499800.000000 529200.000000 558600.000000 588000.000000 617400.000000 646800.000000 676200.000000 705600.000000 735000.000000 764400.000000 793800.000000 823200.000000 852600.000000 882000.000000 911400.000000 940800.000000 970200.000000 999600.000000 1029000.000000
+0.000000 30030.000000 60060.000000 90090.000000 120120.000000 150150.000000 180180.000000 210210.000000 240240.000000 270270.000000 300300.000000 330330.000000 360360.000000 390390.000000 420420.000000 450450.000000 480480.000000 510510.000000 540540.000000 570570.000000 600600.000000 630630.000000 660660.000000 690690.000000 720720.000000 750750.000000 780780.000000 810810.000000 840840.000000 870870.000000 900900.000000 930930.000000 960960.000000 990990.000000 1021020.000000 1051050.000000
+0.000000 30660.000000 61320.000000 91980.000000 122640.000000 153300.000000 183960.000000 214620.000000 245280.000000 275940.000000 306600.000000 337260.000000 367920.000000 398580.000000 429240.000000 459900.000000 490560.000000 521220.000000 551880.000000 582540.000000 613200.000000 643860.000000 674520.000000 705180.000000 735840.000000 766500.000000 797160.000000 827820.000000 858480.000000 889140.000000 919800.000000 950460.000000 981120.000000 1011780.000000 1042440.000000 1073100.000000
+0.000000 31290.000000 62580.000000 93870.000000 125160.000000 156450.000000 187740.000000 219030.000000 250320.000000 281610.000000 312900.000000 344190.000000 375480.000000 406770.000000 438060.000000 469350.000000 500640.000000 531930.000000 563220.000000 594510.000000 625800.000000 657090.000000 688380.000000 719670.000000 750960.000000 782250.000000 813540.000000 844830.000000 876120.000000 907410.000000 938700.000000 969990.000000 1001280.000000 1032570.000000 1063860.000000 1095150.000000
+0.000000 31920.000000 63840.000000 95760.000000 127680.000000 159600.000000 191520.000000 223440.000000 255360.000000 287280.000000 319200.000000 351120.000000 383040.000000 414960.000000 446880.000000 478800.000000 510720.000000 542640.000000 574560.000000 606480.000000 638400.000000 670320.000000 702240.000000 734160.000000 766080.000000 798000.000000 829920.000000 861840.000000 893760.000000 925680.000000 957600.000000 989520.000000 1021440.000000 1053360.000000 1085280.000000 1117200.000000
+0.000000 32550.000000 65100.000000 97650.000000 130200.000000 162750.000000 195300.000000 227850.000000 260400.000000 292950.000000 325500.000000 358050.000000 390600.000000 423150.000000 455700.000000 488250.000000 520800.000000 553350.000000 585900.000000 618450.000000 651000.000000 683550.000000 716100.000000 748650.000000 781200.000000 813750.000000 846300.000000 878850.000000 911400.000000 943950.000000 976500.000000 1009050.000000 1041600.000000 1074150.000000 1106700.000000 1139250.000000
+0.000000 33180.000000 66360.000000 99540.000000 132720.000000 165900.000000 199080.000000 232260.000000 265440.000000 298620.000000 331800.000000 364980.000000 398160.000000 431340.000000 464520.000000 497700.000000 530880.000000 564060.000000 597240.000000 630420.000000 663600.000000 696780.000000 729960.000000 763140.000000 796320.000000 829500.000000 862680.000000 895860.000000 929040.000000 962220.000000 995400.000000 1028580.000000 1061760.000000 1094940.000000 1128120.000000 1161300.000000
+0.000000 33810.000000 67620.000000 101430.000000 135240.000000 169050.000000 202860.000000 236670.000000 270480.000000 304290.000000 338100.000000 371910.000000 405720.000000 439530.000000 473340.000000 507150.000000 540960.000000 574770.000000 608580.000000 642390.000000 676200.000000 710010.000000 743820.000000 777630.000000 811440.000000 845250.000000 879060.000000 912870.000000 946680.000000 980490.000000 1014300.000000 1048110.000000 1081920.000000 1115730.000000 1149540.000000 1183350.000000
+0.000000 34440.000000 68880.000000 103320.000000 137760.000000 172200.000000 206640.000000 241080.000000 275520.000000 309960.000000 344400.000000 378840.000000 413280.000000 447720.000000 482160.000000 516600.000000 551040.000000 585480.000000 619920.000000 654360.000000 688800.000000 723240.000000 757680.000000 792120.000000 826560.000000 861000.000000 895440.000000 929880.000000 964320.000000 998760.000000 1033200.000000 1067640.000000 1102080.000000 1136520.000000 1170960.000000 1205400.000000
+0.000000 35070.000000 70140.000000 105210.000000 140280.000000 175350.000000 210420.000000 245490.000000 280560.000000 315630.000000 350700.000000 385770.000000 420840.000000 455910.000000 490980.000000 526050.000000 561120.000000 596190.000000 631260.000000 666330.000000 701400.000000 736470.000000 771540.000000 806610.000000 841680.000000 876750.000000 911820.000000 946890.000000 981960.000000 1017030.000000 1052100.000000 1087170.000000 1122240.000000 1157310.000000 1192380.000000 1227450.000000
+0.000000 35700.000000 71400.000000 107100.000000 142800.000000 178500.000000 214200.000000 249900.000000 285600.000000 321300.000000 357000.000000 392700.000000 428400.000000 464100.000000 499800.000000 535500.000000 571200.000000 606900.000000 642600.000000 678300.000000 714000.000000 749700.000000 785400.000000 821100.000000 856800.000000 892500.000000 928200.000000 963900.000000 999600.000000 1035300.000000 1071000.000000 1106700.000000 1142400.000000 1178100.000000 1213800.000000 1249500.000000
+0.000000 36330.000000 72660.000000 108990.000000 145320.000000 181650.000000 217980.000000 254310.000000 290640.000000 326970.000000 363300.000000 399630.000000 435960.000000 472290.000000 508620.000000 544950.000000 581280.000000 617610.000000 653940.000000 690270.000000 726600.000000 762930.000000 799260.000000 835590.000000 871920.000000 908250.000000 944580.000000 980910.000000 1017240.000000 1053570.000000 1089900.000000 1126230.000000 1162560.000000 1198890.000000 1235220.000000 1271550.000000
+0.000000 36960.000000 73920.000000 110880.000000 147840.000000 184800.000000 221760.000000 258720.000000 295680.000000 332640.000000 369600.000000 406560.000000 443520.000000 480480.000000 517440.000000 554400.000000 591360.000000 628320.000000 665280.000000 702240.000000 739200.000000 776160.000000 813120.000000 850080.000000 887040.000000 924000.000000 960960.000000 997920.000000 1034880.000000 1071840.000000 1108800.000000 1145760.000000 1182720.000000 1219680.000000 1256640.000000 1293600.000000
--- /dev/null
+{
+ "name": "do.body => do.end45",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_do_body2",
+ "domain": "{ Stmt_do_body2[i0, i1, i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 35 }",
+ "schedule": "{ Stmt_do_body2[i0, i1, i2] -> scattering[0, o1, i0, o3, 0, o5, i1, o7, 0, o9, i2, o11, 0] : 4o7 = o5 and 4o11 = o9 and 4o3 = o1 and o1 <= i0 and o1 >= -3 + i0 and o5 <= i1 and o5 >= -3 + i1 and o9 <= i2 and o9 >= -3 + i2 }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_C[49i0 + i1] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_A[49i0 + i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_B[i1 + 49i2] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_C[49i0 + i1] }"
+ }]
+ }]
+}
\ No newline at end of file
--- /dev/null
+{
+ "name": "do.body => do.end45",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_do_body2",
+ "domain": "{ Stmt_do_body2[i0, i1, i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 35 }",
+ "schedule": "{ Stmt_do_body2[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, -i2, 0] }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_C[49i0 + i1] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_A[49i0 + i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_B[i1 + 49i2] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_C[49i0 + i1] }"
+ }]
+ }]
+}
\ No newline at end of file
--- /dev/null
+{
+ "name": "do.body => do.end45",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_do_body2",
+ "domain": "{ Stmt_do_body2[i0, i1, i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 35 }",
+ "schedule": "{ Stmt_do_body2[i0, i1, i2] -> scattering[0, -i0, 0, -i1, 0, i2, 0] }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_C[49i0 + i1] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_A[49i0 + i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_B[i1 + 49i2] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_do_body2[i0, i1, i2] -> MemRef_C[49i0 + i1] }"
+ }]
+ }]
+}
\ No newline at end of file
--- /dev/null
+#include <string.h>
+#define N 1024
+int A[N];
+int B[N];
+
+void loop_with_condition() {
+ int i;
+
+ __sync_synchronize();
+ for (i = 0; i < N; i++) {
+ if (i <= N / 2)
+ A[i] = 1;
+ else
+ A[i] = 2;
+ B[i] = 3;
+ }
+ __sync_synchronize();
+}
+
+int main () {
+ int i;
+
+ memset(A, 0, sizeof(int) * N);
+ memset(B, 0, sizeof(int) * N);
+
+ loop_with_condition();
+
+ for (i = 0; i < N; i++)
+ if (B[i] != 3)
+ return 1;
+
+ for (i = 0; i < N; i++)
+ if (i <= N / 2 && A[i] != 1)
+ return 1;
+ else if (i > N / 2 && A[i] != 2)
+ return 1;
+ return 0;
+}
+
--- /dev/null
+; ModuleID = 'loop_with_condition.s'
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=4]
+@B = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=4]
+
+define void @loop_with_condition() nounwind {
+; <label>:0
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %1
+
+; <label>:1 ; preds = %7, %0
+ %indvar = phi i64 [ %indvar.next, %7 ], [ 0, %0 ] ; <i64> [#uses=5]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %scevgep1 = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar to i32 ; <i32> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 1024 ; <i1> [#uses=1]
+ br i1 %exitcond, label %2, label %8
+
+; <label>:2 ; preds = %1
+ %3 = icmp sle i32 %i.0, 512 ; <i1> [#uses=1]
+ br i1 %3, label %4, label %5
+
+; <label>:4 ; preds = %2
+ store i32 1, i32* %scevgep
+ br label %6
+
+; <label>:5 ; preds = %2
+ store i32 2, i32* %scevgep
+ br label %6
+
+; <label>:6 ; preds = %5, %4
+ store i32 3, i32* %scevgep1
+ br label %7
+
+; <label>:7 ; preds = %6
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %1
+
+; <label>:8 ; preds = %1
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+; <label>:0
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @A to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @B to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @loop_with_condition()
+ br label %1
+
+; <label>:1 ; preds = %8, %0
+ %indvar1 = phi i64 [ %indvar.next2, %8 ], [ 0, %0 ] ; <i64> [#uses=3]
+ %scevgep3 = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar1 ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar1 to i32 ; <i32> [#uses=1]
+ %2 = icmp slt i32 %i.0, 1024 ; <i1> [#uses=1]
+ br i1 %2, label %3, label %9
+
+; <label>:3 ; preds = %1
+ %4 = load i32* %scevgep3 ; <i32> [#uses=1]
+ %5 = icmp ne i32 %4, 3 ; <i1> [#uses=1]
+ br i1 %5, label %6, label %7
+
+; <label>:6 ; preds = %3
+ br label %28
+
+; <label>:7 ; preds = %3
+ br label %8
+
+; <label>:8 ; preds = %7
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %1
+
+; <label>:9 ; preds = %1
+ br label %10
+
+; <label>:10 ; preds = %26, %9
+ %indvar = phi i64 [ %indvar.next, %26 ], [ 0, %9 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %i.1 = trunc i64 %indvar to i32 ; <i32> [#uses=3]
+ %11 = icmp slt i32 %i.1, 1024 ; <i1> [#uses=1]
+ br i1 %11, label %12, label %27
+
+; <label>:12 ; preds = %10
+ %13 = icmp sle i32 %i.1, 512 ; <i1> [#uses=1]
+ br i1 %13, label %14, label %18
+
+; <label>:14 ; preds = %12
+ %15 = load i32* %scevgep ; <i32> [#uses=1]
+ %16 = icmp ne i32 %15, 1 ; <i1> [#uses=1]
+ br i1 %16, label %17, label %18
+
+; <label>:17 ; preds = %14
+ br label %28
+
+; <label>:18 ; preds = %14, %12
+ %19 = icmp sgt i32 %i.1, 512 ; <i1> [#uses=1]
+ br i1 %19, label %20, label %24
+
+; <label>:20 ; preds = %18
+ %21 = load i32* %scevgep ; <i32> [#uses=1]
+ %22 = icmp ne i32 %21, 2 ; <i1> [#uses=1]
+ br i1 %22, label %23, label %24
+
+; <label>:23 ; preds = %20
+ br label %28
+
+; <label>:24 ; preds = %20, %18
+ br label %25
+
+; <label>:25 ; preds = %24
+ br label %26
+
+; <label>:26 ; preds = %25
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %10
+
+; <label>:27 ; preds = %10
+ br label %28
+
+; <label>:28 ; preds = %27, %23, %17, %6
+ %.0 = phi i32 [ 1, %6 ], [ 1, %17 ], [ 1, %23 ], [ 0, %27 ] ; <i32> [#uses=1]
+ ret i32 %.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; CHECK: for (c2=0;c2<=512;c2++) {
+; CHECK: Stmt_4(c2);
+; CHECK: Stmt_6(c2);
+; CHECK: }
+; CHECK: for (c2=513;c2<=1023;c2++) {
+; CHECK: Stmt_5(c2);
+; CHECK: Stmt_6(c2);
+; CHECK: }
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s | lli
+
+; ModuleID = 'loop_with_condition_2.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16
+@B = common global [1024 x i32] zeroinitializer, align 16
+
+define void @loop_with_condition(i32 %m) nounwind {
+entry:
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %tmp = sub i32 0, %m
+ %tmp1 = zext i32 %tmp to i64
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+ %arrayidx = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar
+ %arrayidx10 = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar
+ %tmp2 = add i64 %tmp1, %indvar
+ %sub = trunc i64 %tmp2 to i32
+ %exitcond = icmp ne i64 %indvar, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %cmp3 = icmp sle i32 %sub, 1024
+ br i1 %cmp3, label %if.then, label %if.else
+
+if.then: ; preds = %for.body
+ store i32 1, i32* %arrayidx
+ br label %if.end
+
+if.else: ; preds = %for.body
+ store i32 2, i32* %arrayidx
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ store i32 3, i32* %arrayidx10
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %indvar.next = add i64 %indvar, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+entry:
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @A to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @B to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @loop_with_condition(i32 5)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvar1 = phi i64 [ %indvar.next2, %for.inc ], [ 0, %entry ]
+ %arrayidx = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar1
+ %i.0 = trunc i64 %indvar1 to i32
+ %cmp = icmp slt i32 %i.0, 1024
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp3 = load i32* %arrayidx
+ %cmp4 = icmp ne i32 %tmp3, 3
+ br i1 %cmp4, label %if.then, label %if.end
+
+if.then: ; preds = %for.body
+ br label %return
+
+if.end: ; preds = %for.body
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %indvar.next2 = add i64 %indvar1, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ br label %for.cond6
+
+for.cond6: ; preds = %for.inc32, %for.end
+ %indvar = phi i64 [ %indvar.next, %for.inc32 ], [ 0, %for.end ]
+ %arrayidx15 = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar
+ %i.1 = trunc i64 %indvar to i32
+ %cmp8 = icmp slt i32 %i.1, 1024
+ br i1 %cmp8, label %for.body9, label %for.end35
+
+for.body9: ; preds = %for.cond6
+ br i1 true, label %land.lhs.true, label %if.else
+
+land.lhs.true: ; preds = %for.body9
+ %tmp16 = load i32* %arrayidx15
+ %cmp17 = icmp ne i32 %tmp16, 1
+ br i1 %cmp17, label %if.then18, label %if.else
+
+if.then18: ; preds = %land.lhs.true
+ br label %return
+
+if.else: ; preds = %land.lhs.true, %for.body9
+ br i1 false, label %land.lhs.true23, label %if.end30
+
+land.lhs.true23: ; preds = %if.else
+ %tmp27 = load i32* %arrayidx15
+ %cmp28 = icmp ne i32 %tmp27, 2
+ br i1 %cmp28, label %if.then29, label %if.end30
+
+if.then29: ; preds = %land.lhs.true23
+ br label %return
+
+if.end30: ; preds = %land.lhs.true23, %if.else
+ br label %if.end31
+
+if.end31: ; preds = %if.end30
+ br label %for.inc32
+
+for.inc32: ; preds = %if.end31
+ %indvar.next = add i64 %indvar, 1
+ br label %for.cond6
+
+for.end35: ; preds = %for.cond6
+ br label %return
+
+return: ; preds = %for.end35, %if.then29, %if.then18, %if.then
+ %retval.0 = phi i32 [ 1, %if.then ], [ 1, %if.then18 ], [ 1, %if.then29 ], [ 0, %for.end35 ]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; CHECK: for (c2=0;c2<=min(1023,M+1024);c2++) {
+; CHECK: Stmt_if_then(c2);
+; CHECK: Stmt_if_end(c2);
+; CHECK: }
+; CHECK: for (c2=max(0,M+1025);c2<=1023;c2++) {
+; CHECK: Stmt_if_else(c2);
+; CHECK: Stmt_if_end(c2);
+; CHECK: }
+
--- /dev/null
+#include <string.h>
+#define N 1024
+int A[N];
+int B[N];
+
+void loop_with_condition_ineq() {
+ int i;
+
+ __sync_synchronize();
+ for (i = 0; i < N; i++) {
+ if (i != N / 2)
+ A[i] = 1;
+ else
+ A[i] = 2;
+ B[i] = 3;
+ }
+ __sync_synchronize();
+}
+
+int main () {
+ int i;
+
+ memset(A, 0, sizeof(int) * N);
+ memset(B, 0, sizeof(int) * N);
+
+ loop_with_condition_ineq();
+
+ for (i = 0; i < N; i++)
+ if (B[i] != 3)
+ return 1;
+
+ for (i = 0; i < N; i++)
+ if (i != N / 2 && A[i] != 1)
+ return 1;
+ else if (i == N && A[i] != 2)
+ return 1;
+ return 0;
+}
+
--- /dev/null
+; ModuleID = 'loop_with_condition_ineq.s'
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=4]
+@B = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=4]
+
+define void @loop_with_condition_ineq() nounwind {
+; <label>:0
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %1
+
+; <label>:1 ; preds = %7, %0
+ %indvar = phi i64 [ %indvar.next, %7 ], [ 0, %0 ] ; <i64> [#uses=5]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %scevgep1 = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar to i32 ; <i32> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 1024 ; <i1> [#uses=1]
+ br i1 %exitcond, label %2, label %8
+
+; <label>:2 ; preds = %1
+ %3 = icmp ne i32 %i.0, 512 ; <i1> [#uses=1]
+ br i1 %3, label %4, label %5
+
+; <label>:4 ; preds = %2
+ store i32 1, i32* %scevgep
+ br label %6
+
+; <label>:5 ; preds = %2
+ store i32 2, i32* %scevgep
+ br label %6
+
+; <label>:6 ; preds = %5, %4
+ store i32 3, i32* %scevgep1
+ br label %7
+
+; <label>:7 ; preds = %6
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %1
+
+; <label>:8 ; preds = %1
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+; <label>:0
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @A to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @B to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @loop_with_condition_ineq()
+ br label %1
+
+; <label>:1 ; preds = %8, %0
+ %indvar1 = phi i64 [ %indvar.next2, %8 ], [ 0, %0 ] ; <i64> [#uses=3]
+ %scevgep3 = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar1 ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar1 to i32 ; <i32> [#uses=1]
+ %2 = icmp slt i32 %i.0, 1024 ; <i1> [#uses=1]
+ br i1 %2, label %3, label %9
+
+; <label>:3 ; preds = %1
+ %4 = load i32* %scevgep3 ; <i32> [#uses=1]
+ %5 = icmp ne i32 %4, 3 ; <i1> [#uses=1]
+ br i1 %5, label %6, label %7
+
+; <label>:6 ; preds = %3
+ br label %28
+
+; <label>:7 ; preds = %3
+ br label %8
+
+; <label>:8 ; preds = %7
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %1
+
+; <label>:9 ; preds = %1
+ br label %10
+
+; <label>:10 ; preds = %26, %9
+ %indvar = phi i64 [ %indvar.next, %26 ], [ 0, %9 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %i.1 = trunc i64 %indvar to i32 ; <i32> [#uses=3]
+ %11 = icmp slt i32 %i.1, 1024 ; <i1> [#uses=1]
+ br i1 %11, label %12, label %27
+
+; <label>:12 ; preds = %10
+ %13 = icmp ne i32 %i.1, 512 ; <i1> [#uses=1]
+ br i1 %13, label %14, label %18
+
+; <label>:14 ; preds = %12
+ %15 = load i32* %scevgep ; <i32> [#uses=1]
+ %16 = icmp ne i32 %15, 1 ; <i1> [#uses=1]
+ br i1 %16, label %17, label %18
+
+; <label>:17 ; preds = %14
+ br label %28
+
+; <label>:18 ; preds = %14, %12
+ %19 = icmp eq i32 %i.1, 1024 ; <i1> [#uses=1]
+ br i1 %19, label %20, label %24
+
+; <label>:20 ; preds = %18
+ %21 = load i32* %scevgep ; <i32> [#uses=1]
+ %22 = icmp ne i32 %21, 2 ; <i1> [#uses=1]
+ br i1 %22, label %23, label %24
+
+; <label>:23 ; preds = %20
+ br label %28
+
+; <label>:24 ; preds = %20, %18
+ br label %25
+
+; <label>:25 ; preds = %24
+ br label %26
+
+; <label>:26 ; preds = %25
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %10
+
+; <label>:27 ; preds = %10
+ br label %28
+
+; <label>:28 ; preds = %27, %23, %17, %6
+ %.0 = phi i32 [ 1, %6 ], [ 1, %17 ], [ 1, %23 ], [ 0, %27 ] ; <i32> [#uses=1]
+ ret i32 %.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; CHECK: for (c2=0;c2<=511;c2++) {
+; CHECK: Stmt_4(c2);
+; CHECK: Stmt_6(c2);
+; CHECK: }
+; CHECK: Stmt_5(512);
+; CHECK: Stmt_6(512);
+; CHECK: for (c2=513;c2<=1023;c2++) {
+; CHECK: Stmt_4(c2);
+; CHECK: Stmt_6(c2);
+; CHECK: }
+
--- /dev/null
+#include <string.h>
+#define N 1024
+int A[N];
+int B[N];
+
+void loop_with_condition() {
+ int i;
+
+ __sync_synchronize();
+ for (i = 0; i < N; i++) {
+ if (i <= N / 2) {
+ if (i > 20)
+ A[i] = 1;
+ else
+ A[i] = 2;
+ }
+ B[i] = 3;
+ }
+ __sync_synchronize();
+}
+
+int main () {
+ int i;
+
+ memset(A, 0, sizeof(int) * N);
+ memset(B, 0, sizeof(int) * N);
+
+ loop_with_condition();
+
+ for (i = 0; i < N; i++)
+ if (B[i] != 3)
+ return 1;
+
+ for (i = 0; i < N; i++)
+ if (i <= N / 2 && i > 20 && A[i] != 1)
+ return 1;
+ else if (i > N / 2) {
+ if (i <= 20 && A[i] != 2)
+ return 1;
+ if (i > 20 && A[i] != 0)
+ return 1;
+ }
+ return 0;
+}
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli
+; ModuleID = 'loop_with_condition_nested.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=4]
+@B = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=4]
+
+define void @loop_with_condition() nounwind {
+; <label>:0
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %1
+
+; <label>:1 ; preds = %10, %0
+ %indvar = phi i64 [ %indvar.next, %10 ], [ 0, %0 ] ; <i64> [#uses=5]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %scevgep1 = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar to i32 ; <i32> [#uses=2]
+ %exitcond = icmp ne i64 %indvar, 1024 ; <i1> [#uses=1]
+ br i1 %exitcond, label %2, label %11
+
+; <label>:2 ; preds = %1
+ %3 = icmp sle i32 %i.0, 512 ; <i1> [#uses=1]
+ br i1 %3, label %4, label %9
+
+; <label>:4 ; preds = %2
+ %5 = icmp sgt i32 %i.0, 20 ; <i1> [#uses=1]
+ br i1 %5, label %6, label %7
+
+; <label>:6 ; preds = %4
+ store i32 1, i32* %scevgep
+ br label %8
+
+; <label>:7 ; preds = %4
+ store i32 2, i32* %scevgep
+ br label %8
+
+; <label>:8 ; preds = %7, %6
+ br label %9
+
+; <label>:9 ; preds = %8, %2
+ store i32 3, i32* %scevgep1
+ br label %10
+
+; <label>:10 ; preds = %9
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %1
+
+; <label>:11 ; preds = %1
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+; <label>:0
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @A to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @B to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @loop_with_condition()
+ br label %1
+
+; <label>:1 ; preds = %8, %0
+ %indvar1 = phi i64 [ %indvar.next2, %8 ], [ 0, %0 ] ; <i64> [#uses=3]
+ %scevgep3 = getelementptr [1024 x i32]* @B, i64 0, i64 %indvar1 ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar1 to i32 ; <i32> [#uses=1]
+ %2 = icmp slt i32 %i.0, 1024 ; <i1> [#uses=1]
+ br i1 %2, label %3, label %9
+
+; <label>:3 ; preds = %1
+ %4 = load i32* %scevgep3 ; <i32> [#uses=1]
+ %5 = icmp ne i32 %4, 3 ; <i1> [#uses=1]
+ br i1 %5, label %6, label %7
+
+; <label>:6 ; preds = %3
+ br label %39
+
+; <label>:7 ; preds = %3
+ br label %8
+
+; <label>:8 ; preds = %7
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %1
+
+; <label>:9 ; preds = %1
+ br label %10
+
+; <label>:10 ; preds = %37, %9
+ %indvar = phi i64 [ %indvar.next, %37 ], [ 0, %9 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=3]
+ %i.1 = trunc i64 %indvar to i32 ; <i32> [#uses=6]
+ %11 = icmp slt i32 %i.1, 1024 ; <i1> [#uses=1]
+ br i1 %11, label %12, label %38
+
+; <label>:12 ; preds = %10
+ %13 = icmp sle i32 %i.1, 512 ; <i1> [#uses=1]
+ br i1 %13, label %14, label %20
+
+; <label>:14 ; preds = %12
+ %15 = icmp sgt i32 %i.1, 20 ; <i1> [#uses=1]
+ br i1 %15, label %16, label %20
+
+; <label>:16 ; preds = %14
+ %17 = load i32* %scevgep ; <i32> [#uses=1]
+ %18 = icmp ne i32 %17, 1 ; <i1> [#uses=1]
+ br i1 %18, label %19, label %20
+
+; <label>:19 ; preds = %16
+ br label %39
+
+; <label>:20 ; preds = %16, %14, %12
+ %21 = icmp sgt i32 %i.1, 512 ; <i1> [#uses=1]
+ br i1 %21, label %22, label %35
+
+; <label>:22 ; preds = %20
+ %23 = icmp sle i32 %i.1, 20 ; <i1> [#uses=1]
+ br i1 %23, label %24, label %28
+
+; <label>:24 ; preds = %22
+ %25 = load i32* %scevgep ; <i32> [#uses=1]
+ %26 = icmp ne i32 %25, 2 ; <i1> [#uses=1]
+ br i1 %26, label %27, label %28
+
+; <label>:27 ; preds = %24
+ br label %39
+
+; <label>:28 ; preds = %24, %22
+ %29 = icmp sgt i32 %i.1, 20 ; <i1> [#uses=1]
+ br i1 %29, label %30, label %34
+
+; <label>:30 ; preds = %28
+ %31 = load i32* %scevgep ; <i32> [#uses=1]
+ %32 = icmp ne i32 %31, 0 ; <i1> [#uses=1]
+ br i1 %32, label %33, label %34
+
+; <label>:33 ; preds = %30
+ br label %39
+
+; <label>:34 ; preds = %30, %28
+ br label %35
+
+; <label>:35 ; preds = %34, %20
+ br label %36
+
+; <label>:36 ; preds = %35
+ br label %37
+
+; <label>:37 ; preds = %36
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %10
+
+; <label>:38 ; preds = %10
+ br label %39
+
+; <label>:39 ; preds = %38, %33, %27, %19, %6
+ %.0 = phi i32 [ 1, %6 ], [ 1, %19 ], [ 1, %27 ], [ 1, %33 ], [ 0, %38 ] ; <i32> [#uses=1]
+ ret i32 %.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; CHECK: for (c2=0;c2<=20;c2++) {
+; CHECK: Stmt_7(c2);
+; CHECK: Stmt_9(c2);
+; CHECK: }
+; CHECK: for (c2=21;c2<=512;c2++) {
+; CHECK: Stmt_6(c2);
+; CHECK: Stmt_9(c2);
+; CHECK: }
+; CHECK: for (c2=513;c2<=1023;c2++) {
+; CHECK: Stmt_9(c2);
+; CHECK: }
+
--- /dev/null
+#define M 1024
+#define N 1024
+#define K 1024
+float A[K][M];
+float B[N][K];
+float C[M][N];
+/*
+void matmul_vec(void) {
+ int i, j, k;
+
+
+ /* With much unrolling
+ for (i=0;i<=M;i++)
+ for (j=0;j<=N;j+=4)
+ for (k=0;k<=K;k+=8)
+ for (kk=k;kk<=k+7;kk++)
+ for (jj=j;jj<=j+3;jj++)
+ C[i][jj] += A[kk][i] * B[jj][kk];
+ vec_load splat scalar_load
+ */
+ /* Without unrolling
+ for (i=0;i<=M;i++)
+ for (j=0;j<=N;j+=4)
+ for (k=0;k<=K;k++)
+ for (jj=j;jj<=j+3;jj++)
+ C[i][jj] += A[k][i] * B[jj][kk];
+ vec_load splat scalar_load
+ /
+
+}
+i*/
+int main()
+{
+ int i, j, k;
+ //matmul_vec();
+ for(i=0; i<M/4; i++)
+ for(k=0; k<K; k++) {
+ for(j=0; j<N; j++)
+ C[i+0][j] += A[k][i+0] * B[j][k];
+ C[i+1][j] += A[k][i+1] * B[j][k];
+ C[i+2][j] += A[k][i+2] * B[j][k];
+ C[i+3][j] += A[k][i+3] * B[j][k];
+ }
+
+ return A[42][42];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-codegen -enable-polly-vector -S -dce %s | FileCheck %s
+
+; ModuleID = 'matmul_vec.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x [1024 x float]] zeroinitializer, align 16
+@B = common global [1024 x [1024 x float]] zeroinitializer, align 16
+@C = common global [1024 x [1024 x float]] zeroinitializer, align 16
+
+define void @matmul_vec() nounwind {
+; <label>:0
+ br label %1
+
+; <label>:1 ; preds = %16, %0
+ %indvar3 = phi i64 [ %indvar.next4, %16 ], [ 0, %0 ]
+ %exitcond9 = icmp ne i64 %indvar3, 1024
+ br i1 %exitcond9, label %2, label %17
+
+; <label>:2 ; preds = %1
+ br label %3
+
+; <label>:3 ; preds = %14, %2
+ %indvar1 = phi i64 [ %indvar.next2, %14 ], [ 0, %2 ]
+ %scevgep8 = getelementptr [1024 x [1024 x float]]* @C, i64 0, i64 %indvar3, i64 %indvar1
+ %exitcond6 = icmp ne i64 %indvar1, 1024
+ br i1 %exitcond6, label %4, label %15
+
+; <label>:4 ; preds = %3
+ br label %5
+
+; <label>:5 ; preds = %12, %4
+ %indvar = phi i64 [ %indvar.next, %12 ], [ 0, %4 ]
+ %scevgep5 = getelementptr [1024 x [1024 x float]]* @A, i64 0, i64 %indvar, i64 %indvar3
+ %scevgep = getelementptr [1024 x [1024 x float]]* @B, i64 0, i64 %indvar1, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 1024
+ br i1 %exitcond, label %6, label %13
+
+; <label>:6 ; preds = %5
+ %7 = load float* %scevgep5, align 4
+ %8 = load float* %scevgep, align 4
+ %9 = fmul float %7, %8
+ %10 = load float* %scevgep8, align 4
+ %11 = fadd float %10, %9
+ store float %11, float* %scevgep8, align 4
+ br label %12
+
+; <label>:12 ; preds = %6
+ %indvar.next = add i64 %indvar, 1
+ br label %5
+
+; <label>:13 ; preds = %5
+ br label %14
+
+; <label>:14 ; preds = %13
+ %indvar.next2 = add i64 %indvar1, 1
+ br label %3
+
+; <label>:15 ; preds = %3
+ br label %16
+
+; <label>:16 ; preds = %15
+ %indvar.next4 = add i64 %indvar3, 1
+ br label %1
+
+; <label>:17 ; preds = %1
+ ret void
+}
+
+define i32 @main() nounwind {
+ call void @matmul_vec()
+ %1 = load float* getelementptr inbounds ([1024 x [1024 x float]]* @A, i64 0, i64 42, i64 42), align 8
+ %2 = fptosi float %1 to i32
+ ret i32 %2
+}
+
+; CHECK: load <1 x float>*
+; CHECK: shufflevector <1 x float>
+; CHECK: load float*
+; CHECK: insertelement <4 x float>
+; CHECK: load float*
+; CHECK: insertelement <4 x float>
+; CHECK: load float*
+; CHECK: insertelement <4 x float>
+; CHECK: load float*
+; CHECK: insertelement <4 x float>
+; CHECK: fmul <4 x float>
+; CHECK: bitcast float*
+; CHECK: load <4 x float>*
+; CHECK: fadd <4 x float>
+; CHECK: bitcast float*
+; CHECK: store <4 x float>
--- /dev/null
+{
+ "name": "%1 => %17",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_6",
+ "domain": "{ Stmt_6[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+ "schedule": "{ Stmt_6[i0, i2, i1] -> scattering[i0, i1, o, i2] : exists (e0 = [(o)/4]: 4e0 = o and o <= i2 and o >= -3 + i2) }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_6[i0, i1, i2] -> MemRef_A[i0 + 1024i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_6[i0, i1, i2] -> MemRef_B[1024i1 + i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_6[i0, i1, i2] -> MemRef_C[1024i0 + i1] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_6[i0, i1, i2] -> MemRef_C[1024i0 + i1] }"
+ }]
+ }]
+}
--- /dev/null
+#define M 2048
+#define N 2048
+#define K 2048
+#define alpha 1
+#define beta 1
+double A[M][K+13];
+double B[K][N+13];
+double C[M][N+13];
+
+void init_array();
+void print_array();
+
+void pluto_matmult(void) {
+ int i, j, k;
+
+ __sync_synchronize();
+ for(i=0; i<M; i++)
+ for(j=0; j<N; j++)
+ for(k=0; k<K; k++)
+ C[i][j] = beta*C[i][j] + alpha*A[i][k] * B[k][j];
+ __sync_synchronize();
+}
+
+int main()
+{
+ register double s;
+
+ init_array();
+
+#pragma scop
+ pluto_matmult();
+#pragma endscop
+ print_array();
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s > /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-cloog -analyze -S < %s | FileCheck -check-prefix=IMPORT %s
+; ModuleID = 'pluto-matmul.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@C = common global [2048 x [2061 x double]] zeroinitializer, align 8 ; <[2048 x [2061 x double]]*> [#uses=2]
+@A = common global [2048 x [2061 x double]] zeroinitializer, align 8 ; <[2048 x [2061 x double]]*> [#uses=2]
+@B = common global [2048 x [2061 x double]] zeroinitializer, align 8 ; <[2048 x [2061 x double]]*> [#uses=2]
+
+define void @pluto_matmult() nounwind {
+entry:
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc44, %entry
+ %indvar3 = phi i64 [ %indvar.next4, %for.inc44 ], [ 0, %entry ] ; <i64> [#uses=4]
+ %exitcond6 = icmp ne i64 %indvar3, 2048 ; <i1> [#uses=1]
+ br i1 %exitcond6, label %for.body, label %for.end47
+
+for.body: ; preds = %for.cond
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc40, %for.body
+ %indvar1 = phi i64 [ %indvar.next2, %for.inc40 ], [ 0, %for.body ] ; <i64> [#uses=4]
+ %arrayidx12 = getelementptr [2048 x [2061 x double]]* @C, i64 0, i64 %indvar3, i64 %indvar1 ; <double*> [#uses=2]
+ %exitcond5 = icmp ne i64 %indvar1, 2048 ; <i1> [#uses=1]
+ br i1 %exitcond5, label %for.body4, label %for.end43
+
+for.body4: ; preds = %for.cond1
+ br label %for.cond5
+
+for.cond5: ; preds = %for.inc, %for.body4
+ %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body4 ] ; <i64> [#uses=4]
+ %arrayidx20 = getelementptr [2048 x [2061 x double]]* @A, i64 0, i64 %indvar3, i64 %indvar ; <double*> [#uses=1]
+ %arrayidx29 = getelementptr [2048 x [2061 x double]]* @B, i64 0, i64 %indvar, i64 %indvar1 ; <double*> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 2048 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body8, label %for.end
+
+for.body8: ; preds = %for.cond5
+ %tmp13 = load double* %arrayidx12 ; <double> [#uses=1]
+ %mul = fmul double 1.000000e+00, %tmp13 ; <double> [#uses=1]
+ %tmp21 = load double* %arrayidx20 ; <double> [#uses=1]
+ %mul22 = fmul double 1.000000e+00, %tmp21 ; <double> [#uses=1]
+ %tmp30 = load double* %arrayidx29 ; <double> [#uses=1]
+ %mul31 = fmul double %mul22, %tmp30 ; <double> [#uses=1]
+ %add = fadd double %mul, %mul31 ; <double> [#uses=1]
+ store double %add, double* %arrayidx12
+ br label %for.inc
+
+for.inc: ; preds = %for.body8
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %for.cond5
+
+for.end: ; preds = %for.cond5
+ br label %for.inc40
+
+for.inc40: ; preds = %for.end
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %for.cond1
+
+for.end43: ; preds = %for.cond1
+ br label %for.inc44
+
+for.inc44: ; preds = %for.end43
+ %indvar.next4 = add i64 %indvar3, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end47: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+entry:
+ call void (...)* @init_array()
+ call void @pluto_matmult()
+ call void (...)* @print_array()
+ ret i32 0
+}
+
+declare void @init_array(...)
+
+declare void @print_array(...)
+; CHECK: for (c2=0;c2<=2047;c2++) {
+; CHECK: for (c4=0;c4<=2047;c4++) {
+; CHECK: for (c6=0;c6<=2047;c6++) {
+; CHECK: Stmt_for_body8(c2,c4,c6);
+; CHECK: }
+; CHECK: }
+; CHECK: }
+
+
+; Do not dump the complete CLooG output. New CLooG version optimize more
+; in this test case.
+; IMPORT: for (c2=0;c2<=2047;c2+=64) {
+; IMPORT: c3<=min(2047,c2+63);c3++) {
+; IMPORT: for (c6=0;c6<=2047;c6+=64) {
+; IMPORT: c7<=min(2047,c6+63);c7++) {
+; IMPORT: for (c10=0;c10<=2047;c10+=64) {
+; IMPORT: c11<=min(2047,c10+63);c11++)
+; IMPORT: {
+; IMPORT: Stmt_for_body8(c3,c7,c11);
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+; IMPORT: }
+
--- /dev/null
+{
+ "name": "for.cond => for.end47",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_for_body8",
+ "domain": "{ Stmt_for_body8[i0, i1, i2] : i0 >= 0 and i0 <= 2047 and i1 >= 0 and i1 <= 2047 and i2 >= 0 and i2 <= 2047 }",
+ "schedule": "{ Stmt_for_body8[i0, i1, i2] -> scattering[0, o1, i0, o3, 0, o5, i1, o7, 0, o9, i2, o11, 0] : 64o7 = o5 and 64o11 = o9 and 64o3 = o1 and o1 <= i0 and o1 >= -63 + i0 and o5 <= i1 and o5 >= -63 + i1 and o9 <= i2 and o9 >= -63 + i2 }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_for_body8[i0, i1, i2] -> MemRef_C[2061i0 + i1] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_for_body8[i0, i1, i2] -> MemRef_A[2061i0 + i2] }"
+ },
+ {
+ "kind": "read",
+ "relation": "{ Stmt_for_body8[i0, i1, i2] -> MemRef_B[i1 + 2061i2] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_for_body8[i0, i1, i2] -> MemRef_C[2061i0 + i1] }"
+ }]
+ }]
+}
\ No newline at end of file
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#define N 1021
+
+int main () {
+ int i;
+ int A[N];
+ int red;
+
+ memset(A, 0, sizeof(int) * N);
+
+ A[0] = 1;
+ A[1] = 1;
+ red = 0;
+
+ __sync_synchronize();
+
+ for (i = 2; i < N; i++) {
+ A[i] = A[i-1] + A[i-2];
+ red += A[i-2];
+ }
+
+ __sync_synchronize();
+
+ if (red != 382399368)
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -S < %s 2>&1 | not FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen | lli
+; XFAIL: *
+; ModuleID = 'reduction.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+define i32 @main() nounwind {
+; <label>:0
+ %A = alloca [1021 x i32], align 16 ; <[1021 x i32]*> [#uses=6]
+ %1 = getelementptr inbounds [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %2 = bitcast i32* %1 to i8* ; <i8*> [#uses=1]
+ call void @llvm.memset.p0i8.i64(i8* %2, i8 0, i64 4084, i32 1, i1 false)
+ %3 = getelementptr inbounds [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %4 = getelementptr inbounds i32* %3, i64 0 ; <i32*> [#uses=1]
+ store i32 1, i32* %4
+ %5 = getelementptr inbounds [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %6 = getelementptr inbounds i32* %5, i64 1 ; <i32*> [#uses=1]
+ store i32 1, i32* %6
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %7
+
+; <label>:7 ; preds = %14, %0
+ %indvar = phi i64 [ %indvar.next, %14 ], [ 0, %0 ] ; <i64> [#uses=5]
+ %red.0 = phi i32 [ 0, %0 ], [ %13, %14 ] ; <i32> [#uses=2]
+ %scevgep = getelementptr [1021 x i32]* %A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %tmp = add i64 %indvar, 2 ; <i64> [#uses=1]
+ %scevgep1 = getelementptr [1021 x i32]* %A, i64 0, i64 %tmp ; <i32*> [#uses=1]
+ %tmp2 = add i64 %indvar, 1 ; <i64> [#uses=1]
+ %scevgep3 = getelementptr [1021 x i32]* %A, i64 0, i64 %tmp2 ; <i32*> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 1019 ; <i1> [#uses=1]
+ br i1 %exitcond, label %8, label %15
+
+; <label>:8 ; preds = %7
+ %9 = load i32* %scevgep3 ; <i32> [#uses=1]
+ %10 = load i32* %scevgep ; <i32> [#uses=1]
+ %11 = add nsw i32 %9, %10 ; <i32> [#uses=1]
+ store i32 %11, i32* %scevgep1
+ %12 = load i32* %scevgep ; <i32> [#uses=1]
+ %13 = add nsw i32 %red.0, %12 ; <i32> [#uses=1]
+ br label %14
+
+; <label>:14 ; preds = %8
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %7
+
+; <label>:15 ; preds = %7
+ %red.0.lcssa = phi i32 [ %red.0, %7 ] ; <i32> [#uses=1]
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %16 = icmp ne i32 %red.0.lcssa, 382399368 ; <i1> [#uses=1]
+ br i1 %16, label %17, label %18
+
+; <label>:17 ; preds = %15
+ br label %18
+
+; <label>:18 ; preds = %17, %15
+ %.0 = phi i32 [ 1, %17 ], [ 0, %15 ] ; <i32> [#uses=1]
+ ret i32 %.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+; CHECK: Could not generate independent blocks
--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#define N 1021
+
+int main () {
+ int i;
+ int A[N];
+ int RED[1];
+
+ memset(A, 0, sizeof(int) * N);
+
+ A[0] = 1;
+ A[1] = 1;
+ RED[0] = 0;
+
+ for (i = 2; i < N; i++) {
+ A[i] = A[i-1] + A[i-2];
+ RED[0] += A[i-2];
+ }
+
+ if (RED[0] != 382399368)
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli
+; ModuleID = 'reduction_2.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [1021 x i32], align 4 ; <[1021 x i32]*> [#uses=6]
+ %RED = alloca [1 x i32], align 4 ; <[1 x i32]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %conv = bitcast i32* %arraydecay to i8* ; <i8*> [#uses=1]
+ call void @llvm.memset.p0i8.i64(i8* %conv, i8 0, i64 4084, i32 1, i1 false)
+ %arraydecay1 = getelementptr inbounds [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx = getelementptr inbounds i32* %arraydecay1, i64 0 ; <i32*> [#uses=1]
+ store i32 1, i32* %arrayidx
+ %arraydecay2 = getelementptr inbounds [1021 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx3 = getelementptr inbounds i32* %arraydecay2, i64 1 ; <i32*> [#uses=1]
+ store i32 1, i32* %arrayidx3
+ %arraydecay4 = getelementptr inbounds [1 x i32]* %RED, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx5 = getelementptr inbounds i32* %arraydecay4, i64 0 ; <i32*> [#uses=1]
+ store i32 0, i32* %arrayidx5
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] ; <i64> [#uses=5]
+ %arrayidx15 = getelementptr [1021 x i32]* %A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %tmp = add i64 %indvar, 2 ; <i64> [#uses=1]
+ %arrayidx20 = getelementptr [1021 x i32]* %A, i64 0, i64 %tmp ; <i32*> [#uses=1]
+ %tmp1 = add i64 %indvar, 1 ; <i64> [#uses=1]
+ %arrayidx9 = getelementptr [1021 x i32]* %A, i64 0, i64 %tmp1 ; <i32*> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 1019 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp10 = load i32* %arrayidx9 ; <i32> [#uses=1]
+ %tmp16 = load i32* %arrayidx15 ; <i32> [#uses=1]
+ %add = add nsw i32 %tmp10, %tmp16 ; <i32> [#uses=1]
+ store i32 %add, i32* %arrayidx20
+ %tmp26 = load i32* %arrayidx15 ; <i32> [#uses=1]
+ %arraydecay27 = getelementptr inbounds [1 x i32]* %RED, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx28 = getelementptr inbounds i32* %arraydecay27, i64 0 ; <i32*> [#uses=2]
+ %tmp29 = load i32* %arrayidx28 ; <i32> [#uses=1]
+ %add30 = add nsw i32 %tmp29, %tmp26 ; <i32> [#uses=1]
+ store i32 %add30, i32* %arrayidx28
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ %arraydecay32 = getelementptr inbounds [1 x i32]* %RED, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx33 = getelementptr inbounds i32* %arraydecay32, i64 0 ; <i32*> [#uses=1]
+ %tmp34 = load i32* %arrayidx33 ; <i32> [#uses=1]
+ %cmp35 = icmp ne i32 %tmp34, 382399368 ; <i1> [#uses=1]
+ br i1 %cmp35, label %if.then, label %if.end
+
+if.then: ; preds = %for.end
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.end
+ %retval.0 = phi i32 [ 1, %if.then ], [ 0, %for.end ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; CHECK: for (c2=0;c2<=1018;c2++) {
+; CHECK: Stmt_for_body(c2);
+; CHECK: }
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect < %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define fastcc void @f () inlinehint align 2 {
+entry:
+ %0 = fmul double undef, 1.250000e+00 ; <double> [#uses=1]
+ %1 = fptoui double %0 to i32 ; <i32> [#uses=0]
+ br i1 false, label %bb5.i, label %bb.nph.i
+
+bb.nph.i: ; preds = %bb.i1
+ br label %bb3.i2
+
+bb3.i2: ; preds = %bb3.i2, %bb.nph.i
+ br i1 undef, label %bb3.i2, label %bb5.i
+
+bb5.i: ; preds = %bb3.i2, %bb.i1
+ br label %exit
+
+exit:
+ ret void
+}
--- /dev/null
+#include <string.h>
+#define N 1024
+
+int A[N];
+
+void sequential_loops() {
+ int i;
+ for (i = 0; i < N/2; i++) {
+ A[i] = 1;
+ }
+ for (i = N/2 ; i < N; i++) {
+ A[i] = 2;
+ }
+}
+
+int main () {
+ int i;
+ memset(A, 0, sizeof(int) * N);
+
+ sequential_loops();
+
+ for (i = 0; i < N; i++) {
+ if (A[i] != 1 && i < N/2)
+ return 1;
+ if (A[i] != 2 && i >= N/2)
+ return 1;
+ }
+
+ return 0;
+}
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli -
+; ModuleID = 'sequential_loops.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 4 ; <[1024 x i32]*> [#uses=5]
+
+define void @sequential_loops() nounwind {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb3, %bb
+ %indvar1 = phi i64 [ %indvar.next2, %bb3 ], [ 0, %bb ]
+ %scevgep4 = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar1
+ %exitcond3 = icmp ne i64 %indvar1, 512
+ br i1 %exitcond3, label %bb2, label %bb4
+
+bb2: ; preds = %bb1
+ store i32 1, i32* %scevgep4
+ br label %bb3
+
+bb3: ; preds = %bb2
+ %indvar.next2 = add i64 %indvar1, 1
+ br label %bb1
+
+bb4: ; preds = %bb1
+ br label %bb5
+
+bb5: ; preds = %bb7, %bb4
+ %indvar = phi i64 [ %indvar.next, %bb7 ], [ 0, %bb4 ]
+ %tmp = add i64 %indvar, 512
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %tmp
+ %exitcond = icmp ne i64 %indvar, 512
+ br i1 %exitcond, label %bb6, label %bb8
+
+bb6: ; preds = %bb5
+ store i32 2, i32* %scevgep
+ br label %bb7
+
+bb7: ; preds = %bb6
+ %indvar.next = add i64 %indvar, 1
+ br label %bb5
+
+bb8: ; preds = %bb5
+ ret void
+}
+
+define i32 @main() nounwind {
+bb:
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @A to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @sequential_loops()
+ br label %bb1
+
+bb1: ; preds = %bb15, %bb
+ %indvar = phi i64 [ %indvar.next, %bb15 ], [ 0, %bb ]
+ %i.0 = trunc i64 %indvar to i32
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar
+ %tmp = icmp slt i32 %i.0, 1024
+ br i1 %tmp, label %bb2, label %bb16
+
+bb2: ; preds = %bb1
+ %tmp3 = load i32* %scevgep
+ %tmp4 = icmp ne i32 %tmp3, 1
+ br i1 %tmp4, label %bb5, label %bb8
+
+bb5: ; preds = %bb2
+ %tmp6 = icmp slt i32 %i.0, 512
+ br i1 %tmp6, label %bb7, label %bb8
+
+bb7: ; preds = %bb5
+ br label %bb17
+
+bb8: ; preds = %bb5, %bb2
+ %tmp9 = load i32* %scevgep
+ %tmp10 = icmp ne i32 %tmp9, 2
+ br i1 %tmp10, label %bb11, label %bb14
+
+bb11: ; preds = %bb8
+ %tmp12 = icmp sge i32 %i.0, 512
+ br i1 %tmp12, label %bb13, label %bb14
+
+bb13: ; preds = %bb11
+ br label %bb17
+
+bb14: ; preds = %bb11, %bb8
+ br label %bb15
+
+bb15: ; preds = %bb14
+ %indvar.next = add i64 %indvar, 1
+ br label %bb1
+
+bb16: ; preds = %bb1
+ br label %bb17
+
+bb17: ; preds = %bb16, %bb13, %bb7
+ %.0 = phi i32 [ 1, %bb7 ], [ 1, %bb13 ], [ 0, %bb16 ]
+ ret i32 %.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+; CHECK: for (c2=0;c2<=511;c2++) {
+; CHECK: Stmt_bb2(c2);
+; CHECK: }
+; CHECK: for (c2=0;c2<=511;c2++) {
+; CHECK: Stmt_bb6(c2);
+; CHECK: }
+
--- /dev/null
+#define N 1024
+float A[N];
+float B[N];
+
+void simple_vec_const(void) {
+ int i;
+
+ for (i = 0; i < 4; i++)
+ B[i] = A[i] + 1;
+}
+int main()
+{
+ simple_vec_const();
+ return A[42];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -dce -S %s | FileCheck %s
+; ModuleID = 'simple_vec_assign_scalar.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+
+define void @simple_vec_const() nounwind {
+bb:
+ br label %bb2
+
+bb2: ; preds = %bb5, %bb
+ %indvar = phi i64 [ %indvar.next, %bb5 ], [ 0, %bb ]
+ %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+ %scevgep1 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 4
+ br i1 %exitcond, label %bb3, label %bb6
+
+bb3: ; preds = %bb2
+ %tmp = load float* %scevgep1, align 4
+ %tmp4 = fadd float %tmp, 1.000000e+00
+ store float %tmp4, float* %scevgep, align 4
+ br label %bb5
+
+bb5: ; preds = %bb3
+ %indvar.next = add i64 %indvar, 1
+ br label %bb2
+
+bb6: ; preds = %bb2
+ ret void
+}
+
+define i32 @main() nounwind {
+bb:
+ call void @simple_vec_const()
+ %tmp = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 42), align 8
+ %tmp1 = fptosi float %tmp to i32
+ ret i32 %tmp1
+}
+
+; CHECK: %tmp4p_vec = fadd <4 x float> %tmp_p_vec_full, <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+
--- /dev/null
+#define N 1024
+float A[N];
+float B[N];
+
+void simple_vec_const(void) {
+ int i;
+
+ for (i = 0; i < 4; i++)
+ B[i] = A[i] + i;
+}
+int main()
+{
+ simple_vec_const();
+ return A[42];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -dce -S %s | FileCheck %s
+; ModuleID = 'simple_vec_assign_scalar_2.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+
+define void @simple_vec_const() nounwind {
+bb:
+ br label %bb2
+
+bb2: ; preds = %bb6, %bb
+ %indvar = phi i64 [ %indvar.next, %bb6 ], [ 0, %bb ]
+ %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+ %i.0 = trunc i64 %indvar to i32
+ %scevgep1 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 4
+ br i1 %exitcond, label %bb3, label %bb7
+
+bb3: ; preds = %bb2
+ %tmp = load float* %scevgep1, align 4
+ %tmp4 = sitofp i32 %i.0 to float
+ %tmp5 = fadd float %tmp, %tmp4
+ store float %tmp5, float* %scevgep, align 4
+ br label %bb6
+
+bb6: ; preds = %bb3
+ %indvar.next = add i64 %indvar, 1
+ br label %bb2
+
+bb7: ; preds = %bb2
+ ret void
+}
+
+define i32 @main() nounwind {
+bb:
+ call void @simple_vec_const()
+ %tmp = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 42), align 8
+ %tmp1 = fptosi float %tmp to i32
+ ret i32 %tmp1
+}
+
+; CHECK: insertelement <4 x float> undef, float %p_tmp4, i32 0
+; CHECK: shufflevector <4 x float> %0, <4 x float> %0, <4 x i32> zeroinitializer
+; CHECK: fadd <4 x float> %tmp_p_vec_full, %1
+
--- /dev/null
+#define N 1024
+float A[N];
+float B[N];
+
+void simple_vec_const(void) {
+ int i;
+
+ for (i = 0; i < 4; i++)
+ B[i] = A[0];
+}
+int main()
+{
+ simple_vec_const();
+ return A[42];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -S %s | FileCheck %s
+
+; ModuleID = 'simple_vec_const.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+
+define void @simple_vec_const() nounwind {
+; <label>:0
+ br label %1
+
+; <label>:1 ; preds = %4, %0
+ %indvar = phi i64 [ %indvar.next, %4 ], [ 0, %0 ]
+ %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 4
+ br i1 %exitcond, label %2, label %5
+
+; <label>:2 ; preds = %1
+ %3 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+ store float %3, float* %scevgep, align 4
+ br label %4
+
+; <label>:4 ; preds = %2
+ %indvar.next = add i64 %indvar, 1
+ br label %1
+
+; <label>:5 ; preds = %1
+ ret void
+}
+
+define i32 @main() nounwind {
+ call void @simple_vec_const()
+ %1 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 42), align 8
+ %2 = fptosi float %1 to i32
+ ret i32 %2
+}
+
+
+; CHECK: load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*)
+; CHECK: shufflevector <1 x float> {{.*}}, <1 x float> {{.*}} <4 x i32> zeroinitializer
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -dce -S %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+
+define void @simple_vec_large_width() nounwind {
+; <label>:0
+ br label %1
+
+; <label>:1 ; preds = %4, %0
+ %indvar = phi i64 [ %indvar.next, %4 ], [ 0, %0 ]
+ %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+ %scevgep1 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 15
+ br i1 %exitcond, label %2, label %5
+
+; <label>:2 ; preds = %1
+ %3 = load float* %scevgep1, align 4
+ store float %3, float* %scevgep, align 4
+ br label %4
+
+; <label>:4 ; preds = %2
+ %indvar.next = add i64 %indvar, 1
+ br label %1
+
+; <label>:5 ; preds = %1
+ ret void
+}
+
+define i32 @main() nounwind {
+ call void @simple_vec_large_width()
+ %1 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 42), align 8
+ %2 = fptosi float %1 to i32
+ ret i32 %2
+}
+
+; CHECK: bitcast float* {{.*}} to <15 x float>*
+; CHECK: load <15 x float>*
+; CHECK: store <15 x float> %_p_vec_full, <15 x float>*
--- /dev/null
+#define N 1024
+float A[N];
+float B[N];
+
+void simple_vec_stride_one(void) {
+ int i;
+
+ for (i = 0; i < 4; i++)
+ B[i] = A[i];
+}
+int main()
+{
+ simple_vec_stride_one();
+ return A[42];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -dce -S %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-cloog -analyze %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=`dirname %s` -polly-codegen %s -S -enable-polly-vector | FileCheck -check-prefix=CODEGEN %s
+; ModuleID = 'simple_vec_stride_one.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+
+define void @simple_vec_stride_one() nounwind {
+; <label>:0
+ br label %1
+
+; <label>:1 ; preds = %4, %0
+ %indvar = phi i64 [ %indvar.next, %4 ], [ 0, %0 ]
+ %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+ %scevgep1 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 4
+ br i1 %exitcond, label %2, label %5
+
+; <label>:2 ; preds = %1
+ %3 = load float* %scevgep1, align 4
+ store float %3, float* %scevgep, align 4
+ br label %4
+
+; <label>:4 ; preds = %2
+ %indvar.next = add i64 %indvar, 1
+ br label %1
+
+; <label>:5 ; preds = %1
+ ret void
+}
+
+define i32 @main() nounwind {
+ call void @simple_vec_stride_one()
+ %1 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 42), align 8
+ %2 = fptosi float %1 to i32
+ ret i32 %2
+}
+
+; CHECK: bitcast float* {{.*}} to <4 x float>*
+; CHECK: load <4 x float>*
+; CHECK: store <4 x float> %_p_vec_full, <4 x float>* %vector_ptr
+
+; IMPORT: for (c2=0;c2<=12;c2+=4) {
+; IMPORT: Stmt_2(c2/4);
+; IMPORT: }
+
+; We do not generate optimal loads for this.
+; CODEGEN: <4 x float>
+
--- /dev/null
+{
+ "name": "%1 => %5",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_2",
+ "domain": "{ Stmt_2[i0] : i0 >= 0 and i0 <= 3 }",
+ "schedule": "{ Stmt_2[i0] -> scattering[0, 4i0, 0] }",
+ "accesses": [{
+ "kind": "read",
+ "relation": "{ Stmt_2[i0] -> MemRef_A[i0] }"
+ },
+ {
+ "kind": "write",
+ "relation": "{ Stmt_2[i0] -> MemRef_B[i0] }"
+ }]
+ }]
+}
--- /dev/null
+#define N 1024
+float A[N];
+float B[N];
+
+void simple_vec_stride_x(void) {
+ int i;
+
+ for (i = 0; i < 4; i++)
+ B[2 * i] = A[2 * i];
+}
+int main()
+{
+ simple_vec_stride_x();
+ return A[42];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -dce -S %s | FileCheck %s
+; ModuleID = 'simple_vec_stride_x.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+
+define void @simple_vec_stride_x() nounwind {
+bb:
+ br label %bb2
+
+bb2: ; preds = %bb5, %bb
+ %indvar = phi i64 [ %indvar.next, %bb5 ], [ 0, %bb ]
+ %tmp = mul i64 %indvar, 2
+ %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %tmp
+ %scevgep1 = getelementptr [1024 x float]* @A, i64 0, i64 %tmp
+ %exitcond = icmp ne i64 %indvar, 4
+ br i1 %exitcond, label %bb3, label %bb6
+
+bb3: ; preds = %bb2
+ %tmp4 = load float* %scevgep1, align 8
+ store float %tmp4, float* %scevgep, align 8
+ br label %bb5
+
+bb5: ; preds = %bb3
+ %indvar.next = add i64 %indvar, 1
+ br label %bb2
+
+bb6: ; preds = %bb2
+ ret void
+}
+
+define i32 @main() nounwind {
+bb:
+ call void @simple_vec_stride_x()
+ %tmp = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 42), align 8
+ %tmp1 = fptosi float %tmp to i32
+ ret i32 %tmp1
+}
+
+; CHECK: load float* %p_scevgep1.moved.to.bb3
+; CHECK: insertelement <4 x float> undef, float %tmp4_p_scalar_, i32 0
+; CHECK: load float* %p_scevgep1.moved.to.bb31
+; CHECK: insertelement <4 x float> %tmp4_p_vec_, float %tmp4_p_scalar_7, i32 1
+; CHECK: load float* %p_scevgep1.moved.to.bb32
+; CHECK: insertelement <4 x float> %tmp4_p_vec_8, float %tmp4_p_scalar_9, i32 2
+; CHECK: load float* %p_scevgep1.moved.to.bb33
+; CHECK: insertelement <4 x float> %tmp4_p_vec_10, float %tmp4_p_scalar_11, i32 3
+; CHECK: extractelement <4 x float> %tmp4_p_vec_12, i32 0
+; CHECK: store float %0, float* %p_scevgep.moved.to.bb3
+; CHECK: extractelement <4 x float> %tmp4_p_vec_12, i32 1
+; CHECK: store float %1, float* %p_scevgep.moved.to.bb34
+; CHECK: extractelement <4 x float> %tmp4_p_vec_12, i32 2
+; CHECK: store float %2, float* %p_scevgep.moved.to.bb35
+; CHECK: extractelement <4 x float> %tmp4_p_vec_12, i32 3
+; CHECK: store float %3, float* %p_scevgep.moved.to.bb36
+
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-vector -dce -S %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x float] zeroinitializer, align 16
+@B = common global [1024 x float] zeroinitializer, align 16
+@C = common global [1024 x float] zeroinitializer, align 16
+
+define void @simple_vec_stride_one() nounwind {
+bb0:
+ br label %bb1
+
+bb1:
+ %indvar = phi i64 [ %indvar.next, %bb4 ], [ 0, %bb0 ]
+ %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+ %scevgep2 = getelementptr [1024 x float]* @C, i64 0, i64 %indvar
+ %scevgep1 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 4
+ br i1 %exitcond, label %bb2a, label %bb5
+
+bb2a:
+ %tmp1 = load float* %scevgep1, align 4
+ store float %tmp1, float* %scevgep, align 4
+ br label %bb2b
+
+bb2b:
+ %tmp2 = load float* %scevgep1, align 4
+ store float %tmp2, float* %scevgep2, align 4
+ br label %bb4
+
+bb4:
+ %indvar.next = add i64 %indvar, 1
+ br label %bb1
+
+bb5:
+ ret void
+}
+
+define i32 @main() nounwind {
+ call void @simple_vec_stride_one()
+ %1 = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 42), align 8
+ %2 = fptosi float %1 to i32
+ ret i32 %2
+}
+
+; CHECK: bitcast float* {{.*}} to <4 x float>*
+; CHECK: load <4 x float>*
+; CHECK: store <4 x float> %tmp1_p_vec_full, <4 x float>* %vector_ptr7
+; CHECK: bitcast float* {{.*}} to <4 x float>*
+; CHECK: load <4 x float>*
+; CHECK: store <4 x float> %tmp2_p_vec_full, <4 x float>* %vector_ptr15
+
--- /dev/null
+#define N 20
+#include "limits.h"
+#include <stdio.h>
+volatile int A[N];
+
+void single_do_loop_int_max_iterations() {
+ int i;
+
+ __sync_synchronize();
+
+ i = 0;
+
+ do {
+ A[0] = i;
+ ++i;
+ } while (i < INT_MAX);
+
+ __sync_synchronize();
+}
+
+int main () {
+ int i;
+
+ A[0] = 0;
+
+ single_do_loop_int_max_iterations();
+
+ fprintf(stdout, "Output %d\n", A[0]);
+
+ if (A[0] == INT_MAX - 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze -S < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -O3 < %s | lli
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -O3 < %s | lli
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=%d -polly-codegen < %s | lli
+; ModuleID = 'single_do_loop_int_max_iterations.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [20 x i32] zeroinitializer, align 4 ; <[20 x i32]*> [#uses=1]
+@stdout = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=1]
+@.str = private constant [11 x i8] c"Output %d\0A\00" ; <[11 x i8]*> [#uses=1]
+
+define void @single_do_loop_int_max_iterations() nounwind {
+entry:
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %do.body
+
+do.body: ; preds = %do.cond, %entry
+ %0 = phi i32 [ 0, %entry ], [ %inc, %do.cond ] ; <i32> [#uses=2]
+ volatile store i32 %0, i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0)
+ %inc = add nsw i32 %0, 1 ; <i32> [#uses=2]
+ br label %do.cond
+
+do.cond: ; preds = %do.body
+ %exitcond = icmp ne i32 %inc, 2147483647 ; <i1> [#uses=1]
+ br i1 %exitcond, label %do.body, label %do.end
+
+do.end: ; preds = %do.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+entry:
+ volatile store i32 0, i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0)
+ call void @single_do_loop_int_max_iterations()
+ %tmp = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1]
+ %tmp1 = volatile load i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0) ; <i32> [#uses=1]
+ %call = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %tmp, i8* getelementptr inbounds ([11 x i8]* @.str, i32 0, i32 0), i32 %tmp1) ; <i32> [#uses=0]
+ %tmp2 = volatile load i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0) ; <i32> [#uses=1]
+ %cmp = icmp eq i32 %tmp2, 2147483646 ; <i1> [#uses=1]
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ br label %return
+
+if.else: ; preds = %entry
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare i32 @fprintf(%struct._IO_FILE*, i8*, ...)
+; CHECK:for (c2=0;c2<=2147483646;c2++) {
--- /dev/null
+{
+ "name": "do.body => do.end",
+ "context": "{ [] }",
+ "statements": [{
+ "name": "Stmt_do_body",
+ "domain": "{ Stmt_do_body[i0] : i0 >= 0 and i0 <= 2147483646 }",
+ "schedule": "{ Stmt_do_body[i0] -> scattering[0, o1, i0, o3, 0] : 64o3 = o1 and o1 <= i0 and o1 >= -63 + i0 }",
+ "accesses": [{
+ "kind": "write",
+ "relation": "{ Stmt_do_body[i0] -> MemRef_A[0] }"
+ }]
+ }]
+}
\ No newline at end of file
--- /dev/null
+#define N 20
+#include "limits.h"
+volatile int A[N];
+
+void bar (int n) {
+ int i;
+ __sync_synchronize();
+ i = 0;
+
+ do {
+ A[0] = i;
+ ++i;
+ } while (i < 2 * n);
+ __sync_synchronize();
+}
+
+int main () {
+ A[0] = 0;
+ bar (N/2);
+
+ if (A[0] == N - 1 )
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze < %s | FileCheck %s
+; XFAIL: *
+; ModuleID = 'single_do_loop_int_param_iterations.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [20 x i32] zeroinitializer, align 4 ; <[20 x i32]*> [#uses=1]
+
+define void @bar(i32 %n) nounwind {
+entry:
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %tmp = mul i32 %n, 2 ; <i32> [#uses=2]
+ %tmp1 = icmp sgt i32 %tmp, 1 ; <i1> [#uses=1]
+ %smax = select i1 %tmp1, i32 %tmp, i32 1 ; <i32> [#uses=1]
+ br label %do.body
+
+do.body: ; preds = %do.cond, %entry
+ %0 = phi i32 [ 0, %entry ], [ %inc, %do.cond ] ; <i32> [#uses=2]
+ volatile store i32 %0, i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0)
+ %inc = add nsw i32 %0, 1 ; <i32> [#uses=2]
+ br label %do.cond
+
+do.cond: ; preds = %do.body
+ %exitcond = icmp ne i32 %inc, %smax ; <i1> [#uses=1]
+ br i1 %exitcond, label %do.body, label %do.end
+
+do.end: ; preds = %do.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+entry:
+ volatile store i32 0, i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0)
+ call void @bar(i32 10)
+ %tmp = volatile load i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0) ; <i32> [#uses=1]
+ %cmp = icmp eq i32 %tmp, 19 ; <i1> [#uses=1]
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ br label %return
+
+if.else: ; preds = %entry
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+; CHECK: Scop: do.body => do.end
+
--- /dev/null
+#define N 20
+#include "limits.h"
+volatile long long A[N];
+
+int main () {
+ long long i;
+
+ A[0] = 0;
+
+ __sync_synchronize();
+
+ i = 0;
+
+ do {
+ A[0] = i;
+ ++i;
+ } while (i < LLONG_MAX);
+
+ __sync_synchronize();
+
+ if (A[0] == LLONG_MAX - 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze -S < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -O3 < %s
+; ModuleID = 'single_do_loop_ll_max_iterations.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [20 x i64] zeroinitializer, align 8 ; <[20 x i64]*> [#uses=1]
+
+define i32 @main() nounwind {
+entry:
+ volatile store i64 0, i64* getelementptr inbounds ([20 x i64]* @A, i32 0, i32 0)
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %do.body
+
+do.body: ; preds = %do.cond, %entry
+ %0 = phi i64 [ 0, %entry ], [ %inc, %do.cond ] ; <i64> [#uses=2]
+ volatile store i64 %0, i64* getelementptr inbounds ([20 x i64]* @A, i32 0, i32 0)
+ %inc = add nsw i64 %0, 1 ; <i64> [#uses=2]
+ br label %do.cond
+
+do.cond: ; preds = %do.body
+ %exitcond = icmp ne i64 %inc, 9223372036854775807 ; <i1> [#uses=1]
+ br i1 %exitcond, label %do.body, label %do.end
+
+do.end: ; preds = %do.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %tmp3 = volatile load i64* getelementptr inbounds ([20 x i64]* @A, i32 0, i32 0) ; <i64> [#uses=1]
+ %cmp4 = icmp eq i64 %tmp3, 9223372036854775806 ; <i1> [#uses=1]
+ br i1 %cmp4, label %if.then, label %if.else
+
+if.then: ; preds = %do.end
+ br label %return
+
+if.else: ; preds = %do.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+; CHECK:for (c2=0;c2<=9223372036854775806;c2++) {
+
--- /dev/null
+#define N 20
+#include "limits.h"
+
+int main () {
+ int i;
+ int A[N];
+
+ A[0] = 1;
+
+ __sync_synchronize();
+
+ i = 0;
+
+ do {
+ A[0] = 0;
+ ++i;
+ } while (i < 1);
+
+ __sync_synchronize();
+
+ if (A[0] == 0)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -O3 < %s | lli
+; XFAIL: *
+; ModuleID = 'single_do_loop_one_iteration.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [20 x i32], align 4 ; <[20 x i32]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx = getelementptr inbounds i32* %arraydecay, i64 0 ; <i32*> [#uses=1]
+ store i32 1, i32* %arrayidx
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %do.body
+
+do.body: ; preds = %do.cond, %entry
+ %arraydecay1 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx2 = getelementptr inbounds i32* %arraydecay1, i64 0 ; <i32*> [#uses=1]
+ store i32 0, i32* %arrayidx2
+ br label %do.cond
+
+do.cond: ; preds = %do.body
+ br i1 false, label %do.body, label %do.end
+
+do.end: ; preds = %do.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %arraydecay4 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx5 = getelementptr inbounds i32* %arraydecay4, i64 0 ; <i32*> [#uses=1]
+ %tmp6 = load i32* %arrayidx5 ; <i32> [#uses=1]
+ %cmp7 = icmp eq i32 %tmp6, 0 ; <i1> [#uses=1]
+ br i1 %cmp7, label %if.then, label %if.else
+
+if.then: ; preds = %do.end
+ br label %return
+
+if.else: ; preds = %do.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+; CHECK: S0(0)
--- /dev/null
+#define N 20
+#include "limits.h"
+#include <stdio.h>
+volatile int A[2 * N];
+
+void single_do_loop_scev_replace() {
+ int i;
+
+ __sync_synchronize();
+
+ i = 0;
+
+ do {
+ A[2 * i] = i;
+ ++i;
+ } while (i < N);
+
+ __sync_synchronize();
+}
+
+int main () {
+ int i;
+
+ single_do_loop_scev_replace();
+
+ fprintf(stdout, "Output %d\n", A[0]);
+
+ if (A[2 * N - 2] == N - 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts < %s | lli
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli
+; ModuleID = 'single_do_loop_scev_replace.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [40 x i32] zeroinitializer, align 4 ; <[40 x i32]*> [#uses=3]
+@stdout = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=1]
+@.str = private constant [11 x i8] c"Output %d\0A\00" ; <[11 x i8]*> [#uses=1]
+
+define void @single_do_loop_scev_replace() nounwind {
+entry:
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %do.body
+
+do.body: ; preds = %do.cond, %entry
+ %indvar = phi i64 [ %indvar.next, %do.cond ], [ 0, %entry ] ; <i64> [#uses=3]
+ %tmp = mul i64 %indvar, 2 ; <i64> [#uses=1]
+ %arrayidx = getelementptr [40 x i32]* @A, i64 0, i64 %tmp ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar to i32 ; <i32> [#uses=1]
+ br label %do.cond
+
+do.cond: ; preds = %do.body
+ volatile store i32 %i.0, i32* %arrayidx
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond = icmp ne i64 %indvar.next, 20 ; <i1> [#uses=1]
+ br i1 %exitcond, label %do.body, label %do.end
+
+do.end: ; preds = %do.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+entry:
+ call void @single_do_loop_scev_replace()
+ %tmp = load %struct._IO_FILE** @stdout ; <%struct._IO_FILE*> [#uses=1]
+ %tmp1 = volatile load i32* getelementptr inbounds ([40 x i32]* @A, i32 0, i32 0) ; <i32> [#uses=1]
+ %call = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %tmp, i8* getelementptr inbounds ([11 x i8]* @.str, i32 0, i32 0), i32 %tmp1) ; <i32> [#uses=0]
+ %tmp2 = volatile load i32* getelementptr inbounds ([40 x i32]* @A, i32 0, i64 38) ; <i32> [#uses=1]
+ %cmp = icmp eq i32 %tmp2, 19 ; <i1> [#uses=1]
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ br label %return
+
+if.else: ; preds = %entry
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare i32 @fprintf(%struct._IO_FILE*, i8*, ...)
+
+; CHECK: for (c2=0;c2<=19;c2++) {
+; CHECK: Stmt_do_cond(c2);
+; CHECK: }
+
--- /dev/null
+#include <string.h>
+#define N 1024
+
+int main () {
+ int i;
+ int A[N];
+
+ memset(A, 0, sizeof(int) * N);
+
+ for (i = 0; i < N; i++) {
+ A[i] = 1;
+ }
+
+ for (i = 0; i < N; i++)
+ if (A[i] != 1)
+ return 1;
+
+ return 0;
+}
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli -
+; ModuleID = 'single_loop.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [1024 x i32], align 4 ; <[1024 x i32]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [1024 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %conv = bitcast i32* %arraydecay to i8* ; <i8*> [#uses=1]
+ call void @llvm.memset.p0i8.i64(i8* %conv, i8 0, i64 4096, i32 1, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvar1 = phi i64 [ %indvar.next2, %for.inc ], [ 0, %entry ] ; <i64> [#uses=3]
+ %arrayidx = getelementptr [1024 x i32]* %A, i64 0, i64 %indvar1 ; <i32*> [#uses=1]
+ %exitcond = icmp ne i64 %indvar1, 1024 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ store i32 1, i32* %arrayidx
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ br label %for.cond5
+
+for.cond5: ; preds = %for.inc17, %for.end
+ %indvar = phi i64 [ %indvar.next, %for.inc17 ], [ 0, %for.end ] ; <i64> [#uses=3]
+ %arrayidx13 = getelementptr [1024 x i32]* %A, i64 0, i64 %indvar ; <i32*> [#uses=1]
+ %i.1 = trunc i64 %indvar to i32 ; <i32> [#uses=1]
+ %cmp7 = icmp slt i32 %i.1, 1024 ; <i1> [#uses=1]
+ br i1 %cmp7, label %for.body9, label %for.end20
+
+for.body9: ; preds = %for.cond5
+ %tmp14 = load i32* %arrayidx13 ; <i32> [#uses=1]
+ %cmp15 = icmp ne i32 %tmp14, 1 ; <i1> [#uses=1]
+ br i1 %cmp15, label %if.then, label %if.end
+
+if.then: ; preds = %for.body9
+ br label %return
+
+if.end: ; preds = %for.body9
+ br label %for.inc17
+
+for.inc17: ; preds = %if.end
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %for.cond5
+
+for.end20: ; preds = %for.cond5
+ br label %return
+
+return: ; preds = %for.end20, %if.then
+ %retval.0 = phi i32 [ 1, %if.then ], [ 0, %for.end20 ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; CHECK:for (c2=0;c2<=1023;c2++) {
+; CHECK: Stmt_for_body(c2);
+; CHECK:}
--- /dev/null
+#define N 20
+#include "limits.h"
+
+int main () {
+ int i;
+ int A[N];
+
+ A[0] = 0;
+
+ __sync_synchronize();
+
+ for (i = 0; i < INT_MAX; i++)
+ A[0] = i;
+
+ __sync_synchronize();
+
+ if (A[0] == INT_MAX - 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze -S < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -O3 < %s | lli
+
+; ModuleID = 'single_loop_int_max_iterations.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [20 x i32], align 4 ; <[20 x i32]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx = getelementptr inbounds i32* %arraydecay, i64 0 ; <i32*> [#uses=1]
+ store i32 0, i32* %arrayidx
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] ; <i32> [#uses=3]
+ %exitcond = icmp ne i32 %0, 2147483647 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arraydecay2 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx3 = getelementptr inbounds i32* %arraydecay2, i64 0 ; <i32*> [#uses=1]
+ store i32 %0, i32* %arrayidx3
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %0, 1 ; <i32> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %arraydecay5 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx6 = getelementptr inbounds i32* %arraydecay5, i64 0 ; <i32*> [#uses=1]
+ %tmp7 = load i32* %arrayidx6 ; <i32> [#uses=1]
+ %cmp8 = icmp eq i32 %tmp7, 2147483646 ; <i1> [#uses=1]
+ br i1 %cmp8, label %if.then, label %if.else
+
+if.then: ; preds = %for.end
+ br label %return
+
+if.else: ; preds = %for.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+; CHECK:for (c2=0;c2<=2147483646;c2++) {
--- /dev/null
+#include "limits.h"
+#define N 20
+
+int main () {
+ long long i;
+ long long A[N];
+
+ A[0] = 0;
+
+ __sync_synchronize();
+
+ for (i = 0; i < LLONG_MAX; i++)
+ A[0] = i;
+
+ __sync_synchronize();
+
+ if (A[0] == LLONG_MAX - 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze -S < %s | FileCheck %s
+
+; ModuleID = 'single_loop_ll_max_iterations.s'
+;
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [20 x i64], align 8 ; <[20 x i64]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [20 x i64]* %A, i32 0, i32 0 ; <i64*> [#uses=1]
+ %arrayidx = getelementptr inbounds i64* %arraydecay, i64 0 ; <i64*> [#uses=1]
+ store i64 0, i64* %arrayidx
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ] ; <i64> [#uses=3]
+ %exitcond = icmp ne i64 %0, 9223372036854775807 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arraydecay2 = getelementptr inbounds [20 x i64]* %A, i32 0, i32 0 ; <i64*> [#uses=1]
+ %arrayidx3 = getelementptr inbounds i64* %arraydecay2, i64 0 ; <i64*> [#uses=1]
+ store i64 %0, i64* %arrayidx3
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i64 %0, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %arraydecay5 = getelementptr inbounds [20 x i64]* %A, i32 0, i32 0 ; <i64*> [#uses=1]
+ %arrayidx6 = getelementptr inbounds i64* %arraydecay5, i64 0 ; <i64*> [#uses=1]
+ %tmp7 = load i64* %arrayidx6 ; <i64> [#uses=1]
+ %cmp8 = icmp eq i64 %tmp7, 9223372036854775806 ; <i1> [#uses=1]
+ br i1 %cmp8, label %if.then, label %if.else
+
+if.then: ; preds = %for.end
+ br label %return
+
+if.else: ; preds = %for.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+; CHECK:for (c2=0;c2<=9223372036854775806;c2++) {
--- /dev/null
+#define N 20
+
+int main () {
+ int i;
+ int A[N];
+
+ A[0] = 0;
+
+ __sync_synchronize();
+
+ for (i = 0; i < 1; i++)
+ A[i] = 1;
+
+ __sync_synchronize();
+
+ if (A[0] == 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+; ModuleID = 'single_loop_one_iteration.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [20 x i32], align 4 ; <[20 x i32]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx = getelementptr inbounds i32* %arraydecay, i64 0 ; <i32*> [#uses=1]
+ store i32 0, i32* %arrayidx
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] ; <i64> [#uses=3]
+ %arrayidx3 = getelementptr [20 x i32]* %A, i64 0, i64 %indvar ; <i32*> [#uses=1]
+ %exitcond = icmp ne i64 %indvar, 1 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ store i32 1, i32* %arrayidx3
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %arraydecay5 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx6 = getelementptr inbounds i32* %arraydecay5, i64 0 ; <i32*> [#uses=1]
+ %tmp7 = load i32* %arrayidx6 ; <i32> [#uses=1]
+ %cmp8 = icmp eq i32 %tmp7, 1 ; <i1> [#uses=1]
+ br i1 %cmp8, label %if.then, label %if.else
+
+if.then: ; preds = %for.end
+ br label %return
+
+if.else: ; preds = %for.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+; CHECK: Stmt_for_body(0);
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s | lli -
+; ModuleID = 'single_loop_param.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=3]
+
+define void @bar(i64 %n) nounwind {
+bb:
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %bb1
+
+bb1: ; preds = %bb3, %bb
+ %i.0 = phi i64 [ 0, %bb ], [ %tmp, %bb3 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %i.0 ; <i32*> [#uses=1]
+ %exitcond = icmp ne i64 %i.0, %n ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb4
+
+bb2: ; preds = %bb1
+ store i32 1, i32* %scevgep
+ br label %bb3
+
+bb3: ; preds = %bb2
+ %tmp = add nsw i64 %i.0, 1 ; <i64> [#uses=1]
+ br label %bb1
+
+bb4: ; preds = %bb1
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ ret void
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+define i32 @main() nounwind {
+bb:
+ call void @llvm.memset.p0i8.i64(i8* bitcast ([1024 x i32]* @A to i8*), i8 0, i64 4096, i32 1, i1 false)
+ call void @bar(i64 1024)
+ br label %bb1
+
+bb1: ; preds = %bb7, %bb
+ %indvar = phi i64 [ %indvar.next, %bb7 ], [ 0, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=1]
+ %i.0 = trunc i64 %indvar to i32 ; <i32> [#uses=1]
+ %tmp = icmp slt i32 %i.0, 1024 ; <i1> [#uses=1]
+ br i1 %tmp, label %bb2, label %bb8
+
+bb2: ; preds = %bb1
+ %tmp3 = load i32* %scevgep ; <i32> [#uses=1]
+ %tmp4 = icmp ne i32 %tmp3, 1 ; <i1> [#uses=1]
+ br i1 %tmp4, label %bb5, label %bb6
+
+bb5: ; preds = %bb2
+ br label %bb9
+
+bb6: ; preds = %bb2
+ br label %bb7
+
+bb7: ; preds = %bb6
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %bb1
+
+bb8: ; preds = %bb1
+ br label %bb9
+
+bb9: ; preds = %bb8, %bb5
+ %.0 = phi i32 [ 1, %bb5 ], [ 0, %bb8 ] ; <i32> [#uses=1]
+ ret i32 %.0
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
+
+; CHECK: if (M >= 1) {
+; CHECK: for (c2=0;c2<=M-1;c2++) {
+; CHECK: Stmt_bb2(c2);
+; CHECK: }
+; CHECK: }
+
--- /dev/null
+#include "limits.h"
+#define N 20
+
+int main () {
+ unsigned int i;
+ unsigned int A[N];
+
+ A[0] = 0;
+
+ __sync_synchronize();
+
+ for (i = 0; i < UINT_MAX; i++)
+ A[0] = i;
+
+ __sync_synchronize();
+
+ if (A[0] == UINT_MAX - 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze < %s | FileCheck %s
+; XFAIL: *
+; ModuleID = 'single_loop_uint_max_iterations.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [20 x i32], align 4 ; <[20 x i32]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx = getelementptr inbounds i32* %arraydecay, i64 0 ; <i32*> [#uses=1]
+ store i32 0, i32* %arrayidx
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] ; <i32> [#uses=3]
+ %exitcond = icmp ne i32 %0, -1 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arraydecay2 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx3 = getelementptr inbounds i32* %arraydecay2, i64 0 ; <i32*> [#uses=1]
+ store i32 %0, i32* %arrayidx3
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add i32 %0, 1 ; <i32> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %arraydecay5 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx6 = getelementptr inbounds i32* %arraydecay5, i64 0 ; <i32*> [#uses=1]
+ %tmp7 = load i32* %arrayidx6 ; <i32> [#uses=1]
+ %cmp8 = icmp eq i32 %tmp7, -2 ; <i1> [#uses=1]
+ br i1 %cmp8, label %if.then, label %if.else
+
+if.then: ; preds = %for.end
+ br label %return
+
+if.else: ; preds = %for.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+
+; CHECK:for (c2=0;
--- /dev/null
+#include "limits.h"
+#define N 20
+
+int main () {
+ unsigned long long i;
+ unsigned long long A[N];
+
+ A[0] = 0;
+
+ __sync_synchronize();
+
+ for (i = 0; i < ULLONG_MAX; i++)
+ A[0] = i;
+
+ __sync_synchronize();
+
+ if (A[0] == ULLONG_MAX - 1)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze < %s | FileCheck %s
+; XFAIL: *
+; ModuleID = 'single_loop_ull_max_iterations.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [20 x i64], align 8 ; <[20 x i64]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [20 x i64]* %A, i32 0, i32 0 ; <i64*> [#uses=1]
+ %arrayidx = getelementptr inbounds i64* %arraydecay, i64 0 ; <i64*> [#uses=1]
+ store i64 0, i64* %arrayidx
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %0 = phi i64 [ 0, %entry ], [ %inc, %for.inc ] ; <i64> [#uses=3]
+ %exitcond = icmp ne i64 %0, -1 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arraydecay2 = getelementptr inbounds [20 x i64]* %A, i32 0, i32 0 ; <i64*> [#uses=1]
+ %arrayidx3 = getelementptr inbounds i64* %arraydecay2, i64 0 ; <i64*> [#uses=1]
+ store i64 %0, i64* %arrayidx3
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add i64 %0, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %arraydecay5 = getelementptr inbounds [20 x i64]* %A, i32 0, i32 0 ; <i64*> [#uses=1]
+ %arrayidx6 = getelementptr inbounds i64* %arraydecay5, i64 0 ; <i64*> [#uses=1]
+ %tmp7 = load i64* %arrayidx6 ; <i64> [#uses=1]
+ %cmp8 = icmp eq i64 %tmp7, -2 ; <i1> [#uses=1]
+ br i1 %cmp8, label %if.then, label %if.else
+
+if.then: ; preds = %for.end
+ br label %return
+
+if.else: ; preds = %for.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+; CHECK:for (c2=0;
--- /dev/null
+#define N 20
+
+int main () {
+ int i;
+ int A[N];
+
+ A[0] = 0;
+
+ __sync_synchronize();
+
+ for (i = 0; i < 0; i++)
+ A[i] = 1;
+
+ __sync_synchronize();
+
+ if (A[0] == 0)
+ return 0;
+ else
+ return 1;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze -S < %s | FileCheck %s
+
+; ModuleID = 'single_loop_zero_iterations.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind {
+entry:
+ %A = alloca [20 x i32], align 4 ; <[20 x i32]*> [#uses=3]
+ %arraydecay = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx = getelementptr inbounds i32* %arraydecay, i64 0 ; <i32*> [#uses=1]
+ store i32 0, i32* %arrayidx
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ] ; <i64> [#uses=2]
+ %arrayidx3 = getelementptr [20 x i32]* %A, i64 0, i64 %indvar ; <i32*> [#uses=1]
+ br i1 false, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ store i32 1, i32* %arrayidx3
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 false)
+ %arraydecay5 = getelementptr inbounds [20 x i32]* %A, i32 0, i32 0 ; <i32*> [#uses=1]
+ %arrayidx6 = getelementptr inbounds i32* %arraydecay5, i64 0 ; <i32*> [#uses=1]
+ %tmp7 = load i32* %arrayidx6 ; <i32> [#uses=1]
+ %cmp8 = icmp eq i32 %tmp7, 0 ; <i1> [#uses=1]
+ br i1 %cmp8, label %if.then, label %if.else
+
+if.then: ; preds = %for.end
+ br label %return
+
+if.else: ; preds = %for.end
+ br label %return
+
+return: ; preds = %if.else, %if.then
+ %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ] ; <i32> [#uses=1]
+ ret i32 %retval.0
+}
+
+declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind
+; CHECK: for region: 'for.cond => for.end.region' in function 'main':
+; CHECK-NEXT: main():
+; CHECK-NEXT: Stmt_for_body(0);
--- /dev/null
+int bar1();
+int bar2();
+int bar3();
+int k;
+#define N 100
+int A[N];
+
+int foo (int z) {
+ int i, j;
+
+ for (i = 0; i < N; i++) {
+ A[i] = i;
+
+ for (j = 0; j < N * 2; j++)
+ A[i] = j * A[i];
+ }
+
+ return A[z];
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -O3 -polly-cloog -analyze -S < %s | FileCheck %s
+; XFAIL: *
+; ModuleID = 'test.c'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [100 x i32] zeroinitializer, align 4 ; <[100 x i32]*> [#uses=2]
+@k = common global i32 0, align 4 ; <i32*> [#uses=0]
+
+define i32 @foo(i32 %z) nounwind {
+bb.nph31.split.us:
+ br label %bb.nph.us
+
+for.inc16.us: ; preds = %for.body6.us
+ store i32 %mul.us, i32* %arrayidx.us
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond32 = icmp eq i64 %indvar.next, 100 ; <i1> [#uses=1]
+ br i1 %exitcond32, label %for.end19, label %bb.nph.us
+
+for.body6.us: ; preds = %for.body6.us, %bb.nph.us
+ %arrayidx10.tmp.0.us = phi i32 [ %i.027.us, %bb.nph.us ], [ %mul.us, %for.body6.us ] ; <i32> [#uses=1]
+ %0 = phi i32 [ 0, %bb.nph.us ], [ %inc.us, %for.body6.us ] ; <i32> [#uses=2]
+ %mul.us = mul i32 %arrayidx10.tmp.0.us, %0 ; <i32> [#uses=2]
+ %inc.us = add nsw i32 %0, 1 ; <i32> [#uses=2]
+ %exitcond = icmp eq i32 %inc.us, 200 ; <i1> [#uses=1]
+ br i1 %exitcond, label %for.inc16.us, label %for.body6.us
+
+bb.nph.us: ; preds = %bb.nph31.split.us, %for.inc16.us
+ %indvar = phi i64 [ %indvar.next, %for.inc16.us ], [ 0, %bb.nph31.split.us ] ; <i64> [#uses=3]
+ %arrayidx.us = getelementptr [100 x i32]* @A, i64 0, i64 %indvar ; <i32*> [#uses=2]
+ %i.027.us = trunc i64 %indvar to i32 ; <i32> [#uses=2]
+ store i32 %i.027.us, i32* %arrayidx.us
+ br label %for.body6.us
+
+for.end19: ; preds = %for.inc16.us
+ %idxprom21 = sext i32 %z to i64 ; <i64> [#uses=1]
+ %arrayidx22 = getelementptr inbounds [100 x i32]* @A, i64 0, i64 %idxprom21 ; <i32*> [#uses=1]
+ %tmp23 = load i32* %arrayidx22 ; <i32> [#uses=1]
+ ret i32 %tmp23
+}
+; CHECK: for (c2=0;c2<=99;c2++) {
+; CHECK: S{{[0-4]}}(c2);
+; CHECK: for (c4=0;c4<=199;c4++) {
+; CHECK: S{{[[0-4]}}(c2,c4);
+; CHECK: }
+; CHECK: S{{[0-4]}}(c2);
+; CHECK: }
+
--- /dev/null
+LEVEL := ..
+include $(LEVEL)/Makefile.common
+
+# Test in all immediate subdirectories if unset.
+ifdef TESTSUITE
+TESTDIRS := $(TESTSUITE:%=$(PROJ_SRC_DIR)/%)
+else
+TESTDIRS ?= $(PROJ_SRC_DIR)
+endif
+
+# 'lit' wants objdir paths, so it will pick up the lit.site.cfg.
+TESTDIRS := $(TESTDIRS:$(PROJ_SRC_DIR)%=$(PROJ_OBJ_DIR)%)
+
+# Allow EXTRA_TESTDIRS to provide additional test directories.
+TESTDIRS += $(EXTRA_TESTDIRS)
+
+ifndef TESTARGS
+ifdef VERBOSE
+TESTARGS = -v
+else
+TESTARGS = -s -v
+endif
+endif
+
+# Make sure any extra test suites can find the main site config.
+LIT_ARGS := --param polly_site_config=${PROJ_OBJ_DIR}/lit.site.cfg \
+ --param build_config=$(PROJ_OBJ_DIR)
+
+
+ifdef VG
+ LIT_ARGS += "--vg"
+endif
+
+polly-test:: lit.site.cfg
+ @ echo '--- Running polly tests for $(TARGET_TRIPLE) ---'
+ @ $(PYTHON) $(LLVM_SRC_ROOT)/utils/lit/lit.py \
+ $(LIT_ARGS) $(TESTARGS) $(TESTDIRS)
+
+FORCE:
+
+lit.site.cfg: FORCE
+ @echo "Making Polly 'lit.site.cfg' file..."
+ @sed -e "s#@LLVM_SOURCE_DIR@#$(LLVM_SRC_ROOT)#g" \
+ -e "s#@LLVM_BINARY_DIR@#$(LLVM_OBJ_ROOT)#g" \
+ -e "s#@LLVM_TOOLS_DIR@#$(LLVM_OBJ_ROOT)/$(BuildMode)/bin#g" \
+ -e "s#@LLVM_LIBS_DIR@#$(LibDir)#g" \
+ -e "s#@POLLY_SOURCE_DIR@#$(PROJ_SRC_DIR)/..#g" \
+ -e "s#@POLLY_BINARY_DIR@#$(PROJ_OBJ_DIR)/..#g" \
+ -e "s#@TARGET_TRIPLE@#$(TARGET_TRIPLE)#g" \
+ $(PROJ_SRC_DIR)/lit.site.cfg.in > $@
+
+clean::
+ @ find . -name Output | xargs rm -fr
+
+.PHONY: polly-test clean
--- /dev/null
+place tests here
\ No newline at end of file
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s -stats 2>&1 | FileCheck %s
+
+; ModuleID = '/tmp/webcompile/_17966_0.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define void @f(i32* nocapture %a, i32* nocapture %b) nounwind {
+bb.nph:
+ %0 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=1]
+ %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
+ %iftmp.0.0 = select i1 %1, i32* %b, i32* %a ; <i32*> [#uses=2]
+ br label %bb3
+
+bb3: ; preds = %bb3, %bb.nph
+ %i.06 = phi i64 [ 0, %bb.nph ], [ %tmp, %bb3 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i32* %a, i64 %i.06 ; <i32*> [#uses=1]
+ %scevgep7 = getelementptr i32* %iftmp.0.0, i64 %i.06 ; <i32*> [#uses=1]
+ %tmp = add i64 %i.06, 1 ; <i64> [#uses=3]
+ %scevgep8 = getelementptr i32* %iftmp.0.0, i64 %tmp ; <i32*> [#uses=1]
+ %2 = load i32* %scevgep, align 4 ; <i32> [#uses=1]
+ %3 = load i32* %scevgep8, align 4 ; <i32> [#uses=1]
+ %4 = shl i32 %3, 1 ; <i32> [#uses=1]
+ %5 = add nsw i32 %4, %2 ; <i32> [#uses=1]
+ store i32 %5, i32* %scevgep7, align 4
+ %exitcond = icmp eq i64 %tmp, 64 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb3
+
+return: ; preds = %bb3
+ ret void
+}
+
+declare i32 @rnd(...)
+
+
+; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s -stats 2>&1 | FileCheck %s
+
+; ModuleID = '/tmp/webcompile/_17966_0.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define void @f(i32* nocapture %a, i32* nocapture %b) nounwind {
+bb.nph:
+ %0 = tail call i32 (...)* @rnd() nounwind ; <i32> [#uses=1]
+ %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
+ %sel.b = getelementptr inbounds i32* %b, i64 4
+ %iftmp.0.0 = select i1 %1, i32* %sel.b, i32* %a ; <i32*> [#uses=2]
+ br label %bb3
+
+bb3: ; preds = %bb3, %bb.nph
+ %i.06 = phi i64 [ 0, %bb.nph ], [ %tmp, %bb3 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i32* %a, i64 %i.06 ; <i32*> [#uses=1]
+ %scevgep7 = getelementptr i32* %iftmp.0.0, i64 %i.06 ; <i32*> [#uses=1]
+ %tmp = add i64 %i.06, 1 ; <i64> [#uses=3]
+ %scevgep8 = getelementptr i32* %iftmp.0.0, i64 %tmp ; <i32*> [#uses=1]
+ %2 = load i32* %scevgep, align 4 ; <i32> [#uses=1]
+ %3 = load i32* %scevgep8, align 4 ; <i32> [#uses=1]
+ %4 = shl i32 %3, 1 ; <i32> [#uses=1]
+ %5 = add nsw i32 %4, %2 ; <i32> [#uses=1]
+ store i32 %5, i32* %scevgep7, align 4
+ %exitcond = icmp eq i64 %tmp, 64 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb3
+
+return: ; preds = %bb3
+ ret void
+}
+
+declare i32 @rnd(...)
+
+
+; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s -stats 2>&1 | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define void @f(i32** nocapture %ptrs, i64 %p0, i64 %p1, i64 %p2) nounwind {
+bb.nph:
+ %0 = getelementptr inbounds i32** %ptrs, i64 %p0 ; <i32**> [#uses=1]
+ %1 = load i32** %0, align 8 ; <i32*> [#uses=1]
+ %2 = getelementptr inbounds i32** %ptrs, i64 %p1 ; <i32**> [#uses=1]
+ %3 = load i32** %2, align 8 ; <i32*> [#uses=1]
+ %4 = getelementptr inbounds i32** %ptrs, i64 %p2 ; <i32**> [#uses=1]
+ %5 = load i32** %4, align 8 ; <i32*> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph
+ %i.03 = phi i64 [ 0, %bb.nph ], [ %tmp, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i32* %3, i64 %i.03 ; <i32*> [#uses=1]
+ %scevgep4 = getelementptr i32* %5, i64 %i.03 ; <i32*> [#uses=1]
+ %tmp = add i64 %i.03, 1 ; <i64> [#uses=3]
+ %scevgep5 = getelementptr i32* %1, i64 %tmp ; <i32*> [#uses=1]
+ %6 = load i32* %scevgep, align 4 ; <i32> [#uses=1]
+ %7 = load i32* %scevgep4, align 4 ; <i32> [#uses=1]
+ %8 = add nsw i32 %7, %6 ; <i32> [#uses=1]
+ store i32 %8, i32* %scevgep5, align 4
+ %exitcond = icmp eq i64 %tmp, 64 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb
+ ret void
+}
+
+; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s -stats 2>&1 | FileCheck %s
+
+; ModuleID = '/tmp/webcompile/_22751_0.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define void @f(i32* nocapture %a, i32* nocapture %b) nounwind {
+bb.nph:
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph
+ %i.03 = phi i64 [ 0, %bb.nph ], [ %2, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i32* %b, i64 %i.03 ; <i32*> [#uses=1]
+ %scevgep4 = getelementptr i32* %a, i64 %i.03 ; <i32*> [#uses=1]
+ %0 = load i32* %scevgep, align 4 ; <i32> [#uses=1]
+ %1 = add nsw i32 %0, 2 ; <i32> [#uses=1]
+ store i32 %1, i32* %scevgep4, align 4
+ %2 = add nsw i64 %i.03, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, 128 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb
+ ret void
+}
+
+
+; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s -stats 2>&1 | not FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s -check-prefix=MAS
+
+; ModuleID = '/tmp/webcompile/_22751_0.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define void @f(i32* noalias nocapture %a, i32* noalias nocapture %b) nounwind {
+bb.nph:
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph
+ %i.03 = phi i64 [ 0, %bb.nph ], [ %2, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i32* %b, i64 %i.03 ; <i32*> [#uses=1]
+ %scevgep4 = getelementptr i32* %a, i64 %i.03 ; <i32*> [#uses=1]
+ %0 = load i32* %scevgep, align 4 ; <i32> [#uses=1]
+ %1 = add nsw i32 %0, 2 ; <i32> [#uses=1]
+ store i32 %1, i32* %scevgep4, align 4
+ %2 = add nsw i64 %i.03, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, 128 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb
+ ret void
+}
+
+
+; CHECK: Found base address alias
+; MAS: Reads %b[4 * {0,+,1}<nuw><nsw><%bb> + 0] Refs: Must alias {%b, } May alias {},
+; MAS: Writes %a[4 * {0,+,1}<nuw><nsw><%bb> + 0] Refs: Must alias {%a, } May alias {},
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze -analyze %s | not FileCheck %s
+
+;void f(long a[][128], long N, long M) {
+; long i, j;
+; for (j = 0; j < M; ++j)
+; for (i = 0; i < rnd(); ++i)
+; ...
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = icmp sgt i64 %M, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb2.preheader, label %return
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %i.06 = phi i64 [ 0, %bb2.preheader ], [ %1, %bb1 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [128 x i64]* %a, i64 %i.06, i64 %5 ; <i64*> [#uses=1]
+ %tmp = add i64 %i.06, %N ; <i64> [#uses=1]
+ store i64 %tmp, i64* %scevgep, align 8
+ %1 = add nsw i64 %i.06, 1 ; <i64> [#uses=2]
+ %2 = tail call i64 (...)* @rnd() nounwind ; <i64> [#uses=1]
+ %3 = icmp sgt i64 %2, %1 ; <i1> [#uses=1]
+ br i1 %3, label %bb1, label %bb3
+
+bb3: ; preds = %bb2.preheader, %bb1
+ %4 = add i64 %5, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %4, %M ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb2.preheader
+
+bb2.preheader: ; preds = %bb3, %entry
+ %5 = phi i64 [ %4, %bb3 ], [ 0, %entry ] ; <i64> [#uses=2]
+ %6 = tail call i64 (...)* @rnd() nounwind ; <i64> [#uses=1]
+ %7 = icmp sgt i64 %6, 0 ; <i1> [#uses=1]
+ br i1 %7, label %bb1, label %bb3
+
+return: ; preds = %bb3, %entry
+ ret void
+}
+
+declare i64 @rnd(...)
+
+; CHECK: Scop!
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s -check-prefix=INDVAR
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+
+;void f(long a[][128], long N, long M) {
+; long i, j;
+; for (j = 0; j < rnd(); ++j)
+; for (i = 0; i < N; ++i)
+; a[i][j] = 0;
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = tail call i64 (...)* @rnd() nounwind ; <i64> [#uses=1]
+ %1 = icmp sgt i64 %0, 0 ; <i1> [#uses=1]
+ br i1 %1, label %bb.nph8, label %return
+
+bb.nph8: ; preds = %entry
+ %2 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ br i1 %2, label %bb2.preheader.us, label %bb2.preheader
+
+bb2.preheader.us: ; preds = %bb2.bb3_crit_edge.us, %bb.nph8
+ %3 = phi i64 [ 0, %bb.nph8 ], [ %tmp, %bb2.bb3_crit_edge.us ] ; <i64> [#uses=2]
+ %tmp = add i64 %3, 1 ; <i64> [#uses=2]
+ br label %bb1.us
+
+bb1.us: ; preds = %bb1.us, %bb2.preheader.us
+ %i.06.us = phi i64 [ 0, %bb2.preheader.us ], [ %4, %bb1.us ] ; <i64> [#uses=2]
+ %scevgep = getelementptr [128 x i64]* %a, i64 %i.06.us, i64 %3 ; <i64*> [#uses=1]
+ store i64 0, i64* %scevgep, align 8
+ %4 = add nsw i64 %i.06.us, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %4, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2.bb3_crit_edge.us, label %bb1.us
+
+bb2.bb3_crit_edge.us: ; preds = %bb1.us
+ %5 = tail call i64 (...)* @rnd() nounwind ; <i64> [#uses=1]
+ %6 = icmp sgt i64 %5, %tmp ; <i1> [#uses=1]
+ br i1 %6, label %bb2.preheader.us, label %return
+
+bb2.preheader: ; preds = %bb2.preheader, %bb.nph8
+ %j.07 = phi i64 [ %tmp9, %bb2.preheader ], [ 0, %bb.nph8 ] ; <i64> [#uses=1]
+ %tmp9 = add i64 %j.07, 1 ; <i64> [#uses=2]
+ %7 = tail call i64 (...)* @rnd() nounwind ; <i64> [#uses=1]
+ %8 = icmp sgt i64 %7, %tmp9 ; <i1> [#uses=1]
+ br i1 %8, label %bb2.preheader, label %return
+
+return: ; preds = %bb2.preheader, %bb2.bb3_crit_edge.us, %entry
+ ret void
+}
+
+declare i64 @rnd(...)
+
+; INDVAR: Scop: bb1.us => bb2.bb3_crit_edge.us Parameters: (%N, {0,+,1}<%bb2.preheader.us>, ), Max Loop Depth: 1
+; CHECK: Scop: bb1.us => bb2.bb3_crit_edge.us Parameters: (%N, {0,+,1}<%bb2.preheader.us>, ), Max Loop Depth: 1
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+
+; ModuleID = '/home/ether/unexpected_parameter.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @mdct_sub48([2 x [576 x double]]* %mdct_freq) nounwind {
+entry:
+ br label %bb54
+
+bb4: ; preds = %bb54, %bb49
+ br label %bb6
+
+bb6: ; preds = %bb6, %bb4
+ br i1 undef, label %bb6, label %bb48
+
+bb24: ; preds = %bb48
+ br i1 false, label %bb47, label %bb46
+
+bb40: ; preds = %bb46
+ %0 = load double* %scevgep74, align 8 ; <double> [#uses=0]
+ %indvar.next62 = add i64 %indvar61, 1 ; <i64> [#uses=1]
+ br label %bb46
+
+bb46: ; preds = %bb40, %bb24
+ %indvar61 = phi i64 [ %indvar.next62, %bb40 ], [ 0, %bb24 ] ; <i64> [#uses=1]
+ %scevgep74 = getelementptr [2 x [576 x double]]* %mdct_freq, i64 0, i64 %indvar1, i64 0 ; <double*> [#uses=1]
+ store double undef, double* %scevgep74, align 8
+ br i1 false, label %bb40, label %bb47
+
+bb47: ; preds = %bb46, %bb24
+ br label %bb48
+
+bb48: ; preds = %bb47, %bb6
+ br i1 false, label %bb24, label %bb49
+
+bb49: ; preds = %bb48
+ br i1 undef, label %bb4, label %bb53
+
+bb53: ; preds = %bb49
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=1]
+ br label %bb54
+
+bb54: ; preds = %bb53, %entry
+ %indvar1 = phi i64 [ %indvar.next2, %bb53 ], [ 0, %entry ] ; <i64> [#uses=2]
+ br i1 undef, label %bb4, label %return
+
+return: ; preds = %bb54
+ ret void
+}
+
+; CHECK: Scop: bb24 => bb48.region Parameters: ({0,+,1}<%bb54>, ), Max Loop Depth: 1
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir %s
+
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define fastcc void @_Z8wavModelR5Mixer() {
+entry:
+ br label %bb230
+
+bb230: ; preds = %bb233, %bb.nph433
+ %indvar600 = phi i64 [ 0, %entry ], [ %tmp610, %bb233 ]
+ %tmp217 = add i64 %indvar600, -1
+ %tmp204 = trunc i64 %tmp217 to i32
+ %tmp205 = zext i32 %tmp204 to i64
+ %tmp206 = add i64 %tmp205, 1
+ %tmp610 = add i64 %indvar600, 1
+ br i1 false, label %bb231.preheader, label %bb233
+
+bb231.preheader: ; preds = %bb230
+ br label %bb231
+
+bb231: ; preds = %bb231, %bb231.preheader
+ %indvar589 = phi i64 [ %tmp611, %bb231 ], [ 0, %bb231.preheader ]
+ %tmp611 = add i64 %indvar589, 1
+ %exitcond207 = icmp eq i64 %tmp611, %tmp206
+ br i1 %exitcond207, label %bb233.loopexit, label %bb231
+
+bb233.loopexit: ; preds = %bb231
+ br label %bb233
+
+bb233: ; preds = %bb233.loopexit, %bb230
+ %exitcond213 = icmp eq i64 %tmp610, 0
+ br i1 %exitcond213, label %bb241, label %bb230
+
+bb241: ; preds = %bb233, %bb228
+ br label %bb244.preheader
+
+bb244.preheader: ; preds = %bb241, %bb176
+ br i1 undef, label %bb245, label %bb.nph416
+
+bb.nph416: ; preds = %bb244.preheader
+ unreachable
+
+bb245: ; preds = %bb244.preheader
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s
+
+; Bug description: Alias Analysis thinks IntToPtrInst aliases with alloca instructions created by IndependentBlocks Pass.
+; This will trigger the assertion when we are verifying the SCoP after IndependentBlocks.
+
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.precisionType = type { i16, i16, i16, i8, [1 x i16] }
+
+define void @main() nounwind {
+entry:
+ br label %bb1.i198.i
+
+bb1.i198.i: ; preds = %bb.i197.i, %psetq.exit196.i
+ %tmp51.i = inttoptr i64 0 to %struct.precisionType*
+ br i1 undef, label %bb1.i210.i, label %bb.i209.i
+
+bb.i209.i: ; preds = %bb1.i198.i
+ br label %bb1.i210.i
+
+bb1.i210.i: ; preds = %bb.i209.i, %bb1.i198.i
+ %0 = icmp eq i64 0, 0
+ br i1 %0, label %bb1.i216.i, label %bb.i215.i
+
+bb.i215.i: ; preds = %bb1.i210.i
+ %1 = getelementptr inbounds %struct.precisionType* %tmp51.i, i64 0, i32 0
+ store i16 undef, i16* %1, align 2
+ br label %bb1.i216.i
+
+bb1.i216.i: ; preds = %bb.i215.i, %bb1.i210.i
+ br i1 undef, label %psetq.exit220.i, label %bb2.i217.i
+
+bb2.i217.i: ; preds = %bb1.i216.i
+ br i1 undef, label %bb3.i218.i, label %psetq.exit220.i
+
+bb3.i218.i: ; preds = %bb2.i217.i
+ br label %psetq.exit220.i
+
+psetq.exit220.i: ; preds = %bb3.i218.i, %bb2.i217.i, %bb1.i216.i
+ br i1 undef, label %bb14.i76, label %bb15.i77
+
+bb14.i76: ; preds = %psetq.exit220.i
+ unreachable
+
+bb15.i77: ; preds = %psetq.exit220.i
+ br i1 %0, label %psetq.exit238.i, label %bb2.i235.i
+
+bb2.i235.i: ; preds = %bb15.i77
+ br i1 undef, label %bb3.i236.i, label %psetq.exit238.i
+
+bb3.i236.i: ; preds = %bb2.i235.i
+ unreachable
+
+psetq.exit238.i: ; preds = %bb2.i235.i, %bb15.i77
+ unreachable
+
+bb56.i.loopexit: ; preds = %psetq.exit172.i
+ unreachable
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | not FileCheck %s
+; ModuleID = '/home/ether/where_comes_the_indvar.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+@edge.8265 = external global [72 x i32], align 32 ; <[72 x i32]*> [#uses=1]
+
+define void @compact_unitcell_edges() nounwind {
+bb.nph19:
+ br label %bb4
+
+bb4: ; preds = %bb4, %bb.nph19
+ %e.118 = phi i32 [ 0, %bb.nph19 ], [ %tmp23, %bb4 ] ; <i32> [#uses=1]
+ %i.017 = phi i32 [ 0, %bb.nph19 ], [ %0, %bb4 ] ; <i32> [#uses=1]
+ %tmp23 = add i32 %e.118, 8 ; <i32> [#uses=2]
+ %0 = add nsw i32 %i.017, 1 ; <i32> [#uses=2]
+ %exitcond42 = icmp eq i32 %0, 6 ; <i1> [#uses=1]
+ br i1 %exitcond42, label %bb.nph, label %bb4
+
+bb.nph: ; preds = %bb4
+ %tmp = sext i32 %tmp23 to i64 ; <i64> [#uses=1]
+ br label %bb7
+
+bb7: ; preds = %bb7, %bb.nph
+ %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb7 ] ; <i64> [#uses=2]
+ %tmp21 = add i64 %tmp, %indvar ; <i64> [#uses=1]
+ %scevgep = getelementptr [72 x i32]* @edge.8265, i64 0, i64 %tmp21 ; <i32*> [#uses=1]
+ store i32 undef, i32* %scevgep, align 4
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=1]
+ br i1 undef, label %bb10, label %bb7
+
+bb10: ; preds = %bb7
+ ret void
+}
+
+; CHECK: SCOP:
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+;void f(long a[], long N, long M) {
+; long i, j, k;
+; for (j = 0; j < M; ++j)
+; ((long*)j)[(long)a] = j;
+
+; for (j = 0; j < N; ++j)
+; a[j] = (char)(M + j);
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = icmp sgt i64 %M, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb.nph8, label %bb4.loopexit
+
+bb.nph8: ; preds = %entry
+ %1 = ptrtoint i64* %a to i64 ; <i64> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph8
+ %2 = phi i64 [ 0, %bb.nph8 ], [ %5, %bb ] ; <i64> [#uses=3]
+ %3 = inttoptr i64 %2 to i64* ; <i64*> [#uses=1]
+ %4 = getelementptr inbounds i64* %3, i64 %1 ; <i64*> [#uses=1]
+ store i64 %2, i64* %4, align 8
+ %5 = add nsw i64 %2, 1 ; <i64> [#uses=2]
+ %exitcond10 = icmp eq i64 %5, %M ; <i1> [#uses=1]
+ br i1 %exitcond10, label %bb4.loopexit, label %bb
+
+bb3: ; preds = %bb4.loopexit, %bb3
+ %j.16 = phi i64 [ 0, %bb4.loopexit ], [ %7, %bb3 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %j.16 ; <i64*> [#uses=1]
+ %tmp = add i64 %j.16, %M ; <i64> [#uses=1]
+ %tmp9 = trunc i64 %tmp to i8 ; <i8> [#uses=1]
+ %6 = sext i8 %tmp9 to i64 ; <i64> [#uses=1]
+ store i64 %6, i64* %scevgep, align 8
+ %7 = add nsw i64 %j.16, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %7, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb3
+
+bb4.loopexit: ; preds = %bb, %entry
+ %8 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ br i1 %8, label %bb3, label %return
+
+return: ; preds = %bb4.loopexit, %bb3
+ ret void
+}
+
+; CHECK: Scop: bb4.loopexit => return Parameters: (%N, ), Max Loop Depth: 1
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | not FileCheck %s
+
+;void f(long a[], long N, long M) {
+; long i, j, k;
+; for (j = 0; j < M; ++j)
+; if (N > j)
+; a[j] = j;
+; else {
+; a[j] = M;
+; a[j - N] = 0;
+; }
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = icmp sgt i64 %M, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb, label %return
+
+bb: ; preds = %bb3, %entry
+ %1 = phi i64 [ 0, %entry ], [ %3, %bb3 ] ; <i64> [#uses=5]
+ %scevgep = getelementptr i64* %a, i64 %1 ; <i64*> [#uses=2]
+ %2 = icmp slt i64 %1, %N ; <i1> [#uses=1]
+ br i1 %2, label %bb1, label %bb2
+
+bb1: ; preds = %bb
+ store i64 %1, i64* %scevgep, align 8
+ br label %bb3
+
+bb2: ; preds = %bb
+ %tmp7 = sub i64 %1, %N ; <i64> [#uses=1]
+ %scevgep8 = getelementptr i64* %a, i64 %tmp7 ; <i64*> [#uses=1]
+ store i64 %M, i64* %scevgep, align 8
+ store i64 0, i64* %scevgep8, align 8
+ br label %bb3
+
+bb3: ; preds = %bb2, %bb1
+ %3 = add nsw i64 %1, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %3, %M ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb3, %entry
+ ret void
+}
+
+; CHECK: Scop!
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+
+;void f(long a[], long N) {
+; long i;
+; for (i = 0; i < N; ++i)
+; a[i] = i;
+
+; a[2 *i + 5 ] = 0;
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N) nounwind {
+entry:
+ %0 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb, label %bb2
+
+bb: ; preds = %bb, %entry
+ %1 = phi i64 [ 0, %entry ], [ %2, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %1 ; <i64*> [#uses=1]
+ store i64 %1, i64* %scevgep, align 8
+ %2 = add nsw i64 %1, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb1.bb2_crit_edge, label %bb
+
+bb1.bb2_crit_edge: ; preds = %bb
+ %phitmp = shl i64 %N, 1 ; <i64> [#uses=1]
+ %phitmp5 = add i64 %phitmp, 5 ; <i64> [#uses=1]
+ br label %bb2
+
+bb2: ; preds = %bb1.bb2_crit_edge, %entry
+ %i.0.lcssa = phi i64 [ %phitmp5, %bb1.bb2_crit_edge ], [ 5, %entry ] ; <i64> [#uses=1]
+ %3 = getelementptr inbounds i64* %a, i64 %i.0.lcssa ; <i64*> [#uses=1]
+ store i64 0, i64* %3, align 8
+ ret void
+}
+
+; CHECK: Scop: entry => <Function Return> Parameters: (%N, )
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+;void f(long a[], long N) {
+; long i;
+; for (i = 0; i < N; ++i)
+; a[i] = i;
+
+; if (N > 0)
+; a[2 * N + 5 ] = 0;
+; else
+; a[5] = 0;
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N) nounwind {
+entry:
+ %0 = icmp sgt i64 %N, 0 ; <i1> [#uses=2]
+ br i1 %0, label %bb, label %bb4
+
+bb: ; preds = %bb, %entry
+ %1 = phi i64 [ 0, %entry ], [ %2, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %1 ; <i64*> [#uses=1]
+ store i64 %1, i64* %scevgep, align 8
+ %2 = add nsw i64 %1, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb
+
+bb2: ; preds = %bb
+ br i1 %0, label %bb3, label %bb4
+
+bb3: ; preds = %bb2
+ %3 = shl i64 %N, 1 ; <i64> [#uses=1]
+ %4 = add nsw i64 %3, 5 ; <i64> [#uses=1]
+ %5 = getelementptr inbounds i64* %a, i64 %4 ; <i64*> [#uses=1]
+ store i64 0, i64* %5, align 8
+ ret void
+
+bb4: ; preds = %bb2, %entry
+ %6 = getelementptr inbounds i64* %a, i64 5 ; <i64*> [#uses=1]
+ store i64 0, i64* %6, align 8
+ ret void
+}
+
+; CHECK: Scop: entry => <Function Return> Parameters: (%N, )
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+
+;void f(long a[], long N, long M) {
+; long i;
+
+; if (N > M)
+; for (i = 0; i < N; ++i)
+; a[i] = i;
+; else
+; i = M + 3;
+
+; a[2 *i + 5 ] = 0;
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N) nounwind {
+entry:
+ %0 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb, label %bb2
+
+bb: ; preds = %bb, %entry
+ %1 = phi i64 [ 0, %entry ], [ %2, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %1 ; <i64*> [#uses=1]
+ store i64 %1, i64* %scevgep, align 8
+ %2 = add nsw i64 %1, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb1.bb2_crit_edge, label %bb
+
+bb1.bb2_crit_edge: ; preds = %bb
+ %phitmp = shl i64 %N, 1 ; <i64> [#uses=1]
+ %phitmp5 = add i64 %phitmp, 5 ; <i64> [#uses=1]
+ br label %bb2
+
+bb2: ; preds = %bb1.bb2_crit_edge, %entry
+ %i.0.lcssa = phi i64 [ %phitmp5, %bb1.bb2_crit_edge ], [ 5, %entry ] ; <i64> [#uses=1]
+ %3 = getelementptr inbounds i64* %a, i64 %i.0.lcssa ; <i64*> [#uses=1]
+ store i64 0, i64* %3, align 8
+ ret void
+}
+
+; CHECK: Scop: entry => <Function Return> Parameters: (%N, %M )
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-prepare -polly-analyze-ir -analyze %s | FileCheck %s
+
+;void f(long a[], long n, long m) {
+; long i0, i1;
+; for (i0 = 0; i0 < 2 * n + m; ++i0)//loop0
+; a[i0] = n;
+
+; for (i1 = 0; i1 < i0 + m; ++i1)//loop1
+; a[i1] += 2;
+;}
+
+
+; ModuleID = '/tmp/webcompile/_19162_0.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define void @_Z1fPlll(i64* nocapture %a, i64 %n, i64 %m) nounwind {
+entry:
+ %0 = shl i64 %n, 1 ; <i64> [#uses=1]
+ %1 = add nsw i64 %0, %m ; <i64> [#uses=3]
+ %2 = icmp sgt i64 %1, 0 ; <i1> [#uses=1]
+ br i1 %2, label %bb, label %bb4.preheader
+
+bb: ; preds = %bb, %entry
+ %i0.07 = phi i64 [ %3, %bb ], [ 0, %entry ] ; <i64> [#uses=2]
+ %scevgep11 = getelementptr i64* %a, i64 %i0.07 ; <i64*> [#uses=1]
+ store i64 %n, i64* %scevgep11, align 8
+ %3 = add nsw i64 %i0.07, 1 ; <i64> [#uses=2]
+ %exitcond10 = icmp eq i64 %3, %1 ; <i1> [#uses=1]
+ br i1 %exitcond10, label %bb4.preheader, label %bb
+
+bb4.preheader: ; preds = %bb, %entry
+ %i0.0.lcssa = phi i64 [ 0, %entry ], [ %1, %bb ] ; <i64> [#uses=1]
+ %4 = add nsw i64 %i0.0.lcssa, %m ; <i64> [#uses=2]
+ %5 = icmp sgt i64 %4, 0 ; <i1> [#uses=1]
+ br i1 %5, label %bb3, label %return
+
+bb3: ; preds = %bb3, %bb4.preheader
+ %i1.06 = phi i64 [ %8, %bb3 ], [ 0, %bb4.preheader ] ; <i64> [#uses=2]
+ %scevgep = getelementptr i64* %a, i64 %i1.06 ; <i64*> [#uses=2]
+ %6 = load i64* %scevgep, align 8 ; <i64> [#uses=1]
+ %7 = add nsw i64 %6, 2 ; <i64> [#uses=1]
+ store i64 %7, i64* %scevgep, align 8
+ %8 = add nsw i64 %i1.06, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %8, %4 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb3
+
+return: ; preds = %bb3, %bb4.preheader
+ ret void
+}
+
+
+; CHECK: Scop: entry.split => bb4.preheader.region Parameters: (%m, %n, ), Max Loop
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+
+;void f(long a[][128], long N, long M) {
+; long i, j;
+; for (j = 0; j < (4*N + 7*M +3); ++j)
+; for (i = 0; i < (5*N + 2); ++i)
+; ...
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = shl i64 %N, 2 ; <i64> [#uses=2]
+ %1 = mul i64 %M, 7 ; <i64> [#uses=2]
+ %2 = or i64 %0, 3 ; <i64> [#uses=1]
+ %3 = add nsw i64 %2, %1 ; <i64> [#uses=1]
+ %4 = icmp sgt i64 %3, 0 ; <i1> [#uses=1]
+ br i1 %4, label %bb.nph8, label %return
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %i.06 = phi i64 [ 0, %bb2.preheader ], [ %5, %bb1 ] ; <i64> [#uses=2]
+ %scevgep = getelementptr [128 x i64]* %a, i64 %i.06, i64 %10 ; <i64*> [#uses=1]
+ store i64 0, i64* %scevgep, align 8
+ %5 = add nsw i64 %i.06, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %5, %8 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %6 = add i64 %10, 1 ; <i64> [#uses=2]
+ %exitcond14 = icmp eq i64 %6, %tmp13 ; <i1> [#uses=1]
+ br i1 %exitcond14, label %return, label %bb2.preheader
+
+bb.nph8: ; preds = %entry
+ %7 = mul i64 %N, 5 ; <i64> [#uses=1]
+ %8 = add nsw i64 %7, 2 ; <i64> [#uses=2]
+ %9 = icmp sgt i64 %8, 0 ; <i1> [#uses=1]
+ br i1 %9, label %bb.nph8.split, label %return
+
+bb.nph8.split: ; preds = %bb.nph8
+ %tmp12 = add i64 %1, %0 ; <i64> [#uses=1]
+ %tmp13 = add i64 %tmp12, 3 ; <i64> [#uses=1]
+ br label %bb2.preheader
+
+bb2.preheader: ; preds = %bb.nph8.split, %bb3
+ %10 = phi i64 [ 0, %bb.nph8.split ], [ %6, %bb3 ] ; <i64> [#uses=2]
+ br label %bb1
+
+return: ; preds = %bb.nph8, %bb3, %entry
+ ret void
+}
+
+; CHECK: entry => <Function Return> Parameters: (%N, %M, )
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+;void f(long a[][128], long N, long M) {
+; long i, j;
+; for (j = 0; j < (4*N + 7*M +3); ++j)
+; for (i = j; i < (5*N + 2); ++i)
+; ...
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = shl i64 %N, 2 ; <i64> [#uses=2]
+ %1 = mul i64 %M, 7 ; <i64> [#uses=2]
+ %2 = or i64 %0, 3 ; <i64> [#uses=1]
+ %3 = add nsw i64 %2, %1 ; <i64> [#uses=1]
+ %4 = icmp sgt i64 %3, 0 ; <i1> [#uses=1]
+ br i1 %4, label %bb.nph8, label %return
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %indvar = phi i64 [ 0, %bb2.preheader ], [ %indvar.next, %bb1 ] ; <i64> [#uses=2]
+ %scevgep = getelementptr [128 x i64]* %a, i64 %indvar, i64 %tmp10 ; <i64*> [#uses=1]
+ store i64 0, i64* %scevgep, align 8
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %indvar.next, %tmp9 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb3, label %bb1
+
+bb3: ; preds = %bb2.preheader, %bb1
+ %5 = add i64 %8, 1 ; <i64> [#uses=2]
+ %exitcond14 = icmp eq i64 %5, %tmp13 ; <i1> [#uses=1]
+ br i1 %exitcond14, label %return, label %bb2.preheader
+
+bb.nph8: ; preds = %entry
+ %6 = mul i64 %N, 5 ; <i64> [#uses=1]
+ %7 = add nsw i64 %6, 2 ; <i64> [#uses=2]
+ %tmp12 = add i64 %1, %0 ; <i64> [#uses=1]
+ %tmp13 = add i64 %tmp12, 3 ; <i64> [#uses=1]
+ br label %bb2.preheader
+
+bb2.preheader: ; preds = %bb.nph8, %bb3
+ %8 = phi i64 [ 0, %bb.nph8 ], [ %5, %bb3 ] ; <i64> [#uses=4]
+ %tmp10 = mul i64 %8, 129 ; <i64> [#uses=1]
+ %tmp9 = sub i64 %7, %8 ; <i64> [#uses=1]
+ %9 = icmp sgt i64 %7, %8 ; <i1> [#uses=1]
+ br i1 %9, label %bb1, label %bb3
+
+return: ; preds = %bb3, %entry
+ ret void
+}
+
+; CHECK: entry => <Function Return> Parameters: (%N, %M, )
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+;void f(long a[][128], long N, long M) {
+; long i, j;
+; for (j = 0; j < (4*N + 7*M +3); ++j)
+; for (i = (7*j + 6*M -9); i < (3*j + 5*N + 2) ; ++i)
+; a[i][j] = 0;
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = shl i64 %N, 2 ; <i64> [#uses=2]
+ %1 = mul i64 %M, 7 ; <i64> [#uses=2]
+ %2 = or i64 %0, 3 ; <i64> [#uses=1]
+ %3 = add nsw i64 %2, %1 ; <i64> [#uses=1]
+ %4 = icmp sgt i64 %3, 0 ; <i1> [#uses=1]
+ br i1 %4, label %bb.nph8, label %return
+
+bb.nph8: ; preds = %entry
+ %tmp14 = mul i64 %M, 6 ; <i64> [#uses=1]
+ %tmp15 = add i64 %tmp14, -9 ; <i64> [#uses=2]
+ %tmp20 = add i64 %1, %0 ; <i64> [#uses=1]
+ %tmp21 = add i64 %tmp20, 3 ; <i64> [#uses=1]
+ %tmp25 = mul i64 %M, -6 ; <i64> [#uses=1]
+ %tmp26 = mul i64 %N, 5 ; <i64> [#uses=2]
+ %tmp27 = add i64 %tmp25, %tmp26 ; <i64> [#uses=1]
+ %tmp28 = add i64 %tmp27, 11 ; <i64> [#uses=1]
+ %tmp35 = add i64 %tmp26, 2 ; <i64> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb3, %bb.nph8
+ %j.07 = phi i64 [ 0, %bb.nph8 ], [ %6, %bb3 ] ; <i64> [#uses=5]
+ %tmp17 = mul i64 %j.07, 897 ; <i64> [#uses=1]
+ %tmp24 = mul i64 %j.07, -4 ; <i64> [#uses=1]
+ %tmp13 = add i64 %tmp24, %tmp28 ; <i64> [#uses=1]
+ %tmp30 = mul i64 %j.07, 7 ; <i64> [#uses=1]
+ %tmp33 = add i64 %tmp30, %tmp15 ; <i64> [#uses=1]
+ %tmp34 = mul i64 %j.07, 3 ; <i64> [#uses=1]
+ %tmp36 = add i64 %tmp34, %tmp35 ; <i64> [#uses=1]
+ %5 = icmp sgt i64 %tmp36, %tmp33 ; <i1> [#uses=1]
+ br i1 %5, label %bb1, label %bb3
+
+bb1: ; preds = %bb1, %bb
+ %indvar = phi i64 [ 0, %bb ], [ %indvar.next, %bb1 ] ; <i64> [#uses=2]
+ %tmp16 = add i64 %indvar, %tmp15 ; <i64> [#uses=1]
+ %scevgep = getelementptr [128 x i64]* %a, i64 %tmp16, i64 %tmp17 ; <i64*> [#uses=1]
+ store i64 0, i64* %scevgep, align 8
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %indvar.next, %tmp13 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb3, label %bb1
+
+bb3: ; preds = %bb1, %bb
+ %6 = add nsw i64 %j.07, 1 ; <i64> [#uses=2]
+ %exitcond22 = icmp eq i64 %6, %tmp21 ; <i1> [#uses=1]
+ br i1 %exitcond22, label %return, label %bb
+
+return: ; preds = %bb3, %entry
+ ret void
+}
+
+; CHECK: Scop: entry => <Function Return> Parameters: (%M, %N, ), Max Loop Depth: 2
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-prepare -polly-scops -analyze %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+;long f(long a[], long n) {
+; long i, k;
+; k = 1;
+; for (i = 1; i < n; ++i) {
+; a[i] = k * a[i - 1];
+; k = a[i + 3] + a[2 * i];
+; }
+; return 0;
+;}
+
+define i64 @f(i64* nocapture %a, i64 %n) nounwind {
+entry:
+ %0 = icmp sgt i64 %n, 1 ; <i1> [#uses=1]
+ br i1 %0, label %bb.nph, label %bb2
+
+bb.nph: ; preds = %entry
+ %tmp = add i64 %n, -1 ; <i64> [#uses=1]
+ %.pre = load i64* %a, align 8 ; <i64> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph
+ %1 = phi i64 [ %.pre, %bb.nph ], [ %2, %bb ] ; <i64> [#uses=1]
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp6, %bb ] ; <i64> [#uses=3]
+ %k.05 = phi i64 [ 1, %bb.nph ], [ %5, %bb ] ; <i64> [#uses=1]
+ %tmp6 = add i64 %indvar, 1 ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %tmp6 ; <i64*> [#uses=1]
+ %2 = mul nsw i64 %1, %k.05 ; <i64> [#uses=2]
+ store i64 %2, i64* %scevgep, align 8
+ %tmp7 = shl i64 %indvar, 1 ; <i64> [#uses=1]
+ %tmp11 = add i64 %indvar, 4 ; <i64> [#uses=1]
+ %tmp8 = add i64 %tmp7, 2 ; <i64> [#uses=1]
+ %scevgep12 = getelementptr i64* %a, i64 %tmp11 ; <i64*> [#uses=1]
+ %scevgep9 = getelementptr i64* %a, i64 %tmp8 ; <i64*> [#uses=1]
+ %3 = load i64* %scevgep9, align 8 ; <i64> [#uses=1]
+ %4 = load i64* %scevgep12, align 8 ; <i64> [#uses=1]
+ %5 = add nsw i64 %3, %4 ; <i64> [#uses=1]
+ %exitcond = icmp eq i64 %tmp6, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb
+
+bb2: ; preds = %bb, %entry
+ ret i64 0
+}
+
+; CHECK: Context:
+; CHECK: [p0] -> { [] }
+; CHECK: Statements {
+; CHECK: Stmt_bb_nph
+; CHECK: Domain :=
+; CHECK: [p0] -> { Stmt_bb_nph[] : p0 >= 2 };
+; CHECK: Scattering :=
+; CHECK: [p0] -> { Stmt_bb_nph[] -> scattering[0, 0, 0] };
+; CHECK: ReadAccess :=
+; CHECK: [p0] -> { Stmt_bb_nph[] -> MemRef_a[0] };
+; CHECK: WriteAccess :=
+; CHECK: [p0] -> { Stmt_bb_nph[] -> MemRef_k_05_reg2mem[0] };
+; CHECK: WriteAccess :=
+; CHECK: [p0] -> { Stmt_bb_nph[] -> MemRef__reg2mem[0] };
+; CHECK: Stmt_bb
+; CHECK: Domain :=
+; CHECK: [p0] -> { Stmt_bb[i0] : i0 >= 0 and i0 <= -2 + p0 and p0 >= 2 };
+; CHECK: Scattering :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> scattering[1, i0, 0] };
+; CHECK: ReadAccess :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> MemRef__reg2mem[0] };
+; CHECK: ReadAccess :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> MemRef_k_05_reg2mem[0] };
+; CHECK: WriteAccess :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> MemRef_a[1 + i0] };
+; CHECK: ReadAccess :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> MemRef_a[2 + 2i0] };
+; CHECK: ReadAccess :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> MemRef_a[4 + i0] };
+; CHECK: WriteAccess :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> MemRef_k_05_reg2mem[0] };
+; CHECK: WriteAccess :=
+; CHECK: [p0] -> { Stmt_bb[i0] -> MemRef__reg2mem[0] };
+; CHECK: FinalRead
+; CHECK: Domain :=
+; CHECK: [p0] -> { FinalRead[0] };
+; CHECK: Scattering :=
+; CHECK: [p0] -> { FinalRead[i0] -> scattering[200000000, o1, o2] };
+; CHECK: ReadAccess :=
+; CHECK: [p0] -> { FinalRead[i0] -> MemRef_a[o0] };
+; CHECK: ReadAccess :=
+; CHECK: [p0] -> { FinalRead[i0] -> MemRef_k_05_reg2mem[o0] };
+; CHECK: ReadAccess :=
+; CHECK: -> { FinalRead[i0] -> MemRef__reg2mem[o0] };
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+
+;void f(long a[][128], long N, long M) {
+; long i, j;
+; for (j = 0; j < (4*N + 7*M +3); ++j)
+; for (i = 0; i < (5*N*M + 2); ++i)
+; ...
+;}
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = shl i64 %N, 2 ; <i64> [#uses=2]
+ %1 = mul i64 %M, 7 ; <i64> [#uses=2]
+ %2 = or i64 %0, 3 ; <i64> [#uses=1]
+ %3 = add nsw i64 %2, %1 ; <i64> [#uses=1]
+ %4 = icmp sgt i64 %3, 0 ; <i1> [#uses=1]
+ br i1 %4, label %bb.nph8, label %return
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %i.06 = phi i64 [ 0, %bb2.preheader ], [ %5, %bb1 ] ; <i64> [#uses=2]
+ %scevgep = getelementptr [128 x i64]* %a, i64 %i.06, i64 %11 ; <i64*> [#uses=1]
+ store i64 0, i64* %scevgep, align 8
+ %5 = add nsw i64 %i.06, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %5, %tmp10 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %6 = add i64 %11, 1 ; <i64> [#uses=2]
+ %exitcond15 = icmp eq i64 %6, %tmp14 ; <i1> [#uses=1]
+ br i1 %exitcond15, label %return, label %bb2.preheader
+
+bb.nph8: ; preds = %entry
+ %7 = mul i64 %N, 5 ; <i64> [#uses=1]
+ %8 = mul i64 %7, %M ; <i64> [#uses=1]
+ %9 = add nsw i64 %8, 2 ; <i64> [#uses=1]
+ %10 = icmp sgt i64 %9, 0 ; <i1> [#uses=1]
+ br i1 %10, label %bb.nph8.split, label %return
+
+bb.nph8.split: ; preds = %bb.nph8
+ %tmp = mul i64 %M, %N ; <i64> [#uses=1]
+ %tmp9 = mul i64 %tmp, 5 ; <i64> [#uses=1]
+ %tmp10 = add i64 %tmp9, 2 ; <i64> [#uses=1]
+ %tmp13 = add i64 %1, %0 ; <i64> [#uses=1]
+ %tmp14 = add i64 %tmp13, 3 ; <i64> [#uses=1]
+ br label %bb2.preheader
+
+bb2.preheader: ; preds = %bb.nph8.split, %bb3
+ %11 = phi i64 [ 0, %bb.nph8.split ], [ %6, %bb3 ] ; <i64> [#uses=2]
+ br label %bb1
+
+return: ; preds = %bb.nph8, %bb3, %entry
+ ret void
+}
+
+; CHECK: TO BE WRITTEN
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+;void f(long a[][128], long N, long M) {
+; long i, j, k;
+; for (j = 0; j < M; ++j)
+; for (i = 0; i < N; ++i)
+; a[i][j] = 4*i+5;
+
+; for (k = 0; k < 64; ++k)
+; a[4][k] = a[k][4];
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = icmp sgt i64 %M, 0 ; <i1> [#uses=1]
+ %1 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ %or.cond = and i1 %0, %1 ; <i1> [#uses=1]
+ br i1 %or.cond, label %bb2.preheader, label %bb6
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %i.010 = phi i64 [ 0, %bb2.preheader ], [ %2, %bb1 ] ; <i64> [#uses=3]
+ %tmp = shl i64 %i.010, 2 ; <i64> [#uses=1]
+ %tmp16 = add i64 %tmp, 5 ; <i64> [#uses=1]
+ %scevgep17 = getelementptr [128 x i64]* %a, i64 %i.010, i64 %4 ; <i64*> [#uses=1]
+ store i64 %tmp16, i64* %scevgep17, align 8
+ %2 = add nsw i64 %i.010, 1 ; <i64> [#uses=2]
+ %exitcond15 = icmp eq i64 %2, %N ; <i1> [#uses=1]
+ br i1 %exitcond15, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %3 = add i64 %4, 1 ; <i64> [#uses=2]
+ %exitcond18 = icmp eq i64 %3, %M ; <i1> [#uses=1]
+ br i1 %exitcond18, label %bb6, label %bb2.preheader
+
+bb2.preheader: ; preds = %bb3, %entry
+ %4 = phi i64 [ %3, %bb3 ], [ 0, %entry ] ; <i64> [#uses=2]
+ br label %bb1
+
+bb6: ; preds = %bb6, %bb3, %entry
+ %k.09 = phi i64 [ %6, %bb6 ], [ 0, %bb3 ], [ 0, %entry ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [128 x i64]* %a, i64 4, i64 %k.09 ; <i64*> [#uses=1]
+ %scevgep14 = getelementptr [128 x i64]* %a, i64 %k.09, i64 4 ; <i64*> [#uses=1]
+ %5 = load i64* %scevgep14, align 8 ; <i64> [#uses=1]
+ store i64 %5, i64* %scevgep, align 8
+ %6 = add nsw i64 %k.09, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %6, 64 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb6
+
+return: ; preds = %bb6
+ ret void
+}
+
+; CHECK: Scop: entry => <Function Return> Parameters: (%N, %M, ), Max Loop Depth: 2
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s -check-prefix=INDVAR
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+;From pollybench.
+;void f(long A[][128], long n) {
+; long k, i, j;
+; for (k = 0; k < n; k++) {
+; for (j = k + 1; j < n; j++)
+; A[k][j] = A[k][j] / A[k][k];
+; for(i = k + 1; i < n; i++)
+; for (j = k + 1; j < n; j++)
+; A[i][j] = A[i][j] - A[i][k] * A[k][j];
+; }
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define void @f([128 x i64]* nocapture %A, i64 %n) nounwind {
+entry:
+ %0 = icmp sgt i64 %n, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb.nph30, label %return
+
+bb.nph: ; preds = %bb2.preheader
+ %1 = getelementptr inbounds [128 x i64]* %A, i64 %k.023, i64 %k.023 ; <i64*> [#uses=1]
+ %tmp31 = sub i64 %tmp, %k.023 ; <i64> [#uses=1]
+ %tmp32 = mul i64 %k.023, 129 ; <i64> [#uses=1]
+ %tmp33 = add i64 %tmp32, 1 ; <i64> [#uses=1]
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb.nph
+ %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb1 ] ; <i64> [#uses=2]
+ %tmp34 = add i64 %tmp33, %indvar ; <i64> [#uses=1]
+ %scevgep = getelementptr [128 x i64]* %A, i64 0, i64 %tmp34 ; <i64*> [#uses=2]
+ %2 = load i64* %scevgep, align 8 ; <i64> [#uses=1]
+ %3 = load i64* %1, align 8 ; <i64> [#uses=1]
+ %4 = sdiv i64 %2, %3 ; <i64> [#uses=1]
+ store i64 %4, i64* %scevgep, align 8
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %indvar.next, %tmp31 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb8.loopexit, label %bb1
+
+bb.nph16: ; preds = %bb.nph22, %bb8.loopexit12
+ %indvar39 = phi i64 [ 0, %bb.nph22 ], [ %tmp51, %bb8.loopexit12 ] ; <i64> [#uses=2]
+ %tmp48 = add i64 %j.013, %indvar39 ; <i64> [#uses=1]
+ %tmp51 = add i64 %indvar39, 1 ; <i64> [#uses=3]
+ %scevgep53 = getelementptr [128 x i64]* %A, i64 %tmp51, i64 %tmp52 ; <i64*> [#uses=1]
+ %tmp37 = sub i64 %n, %j.013 ; <i64> [#uses=1]
+ br label %bb5
+
+bb5: ; preds = %bb5, %bb.nph16
+ %indvar35 = phi i64 [ 0, %bb.nph16 ], [ %indvar.next36, %bb5 ] ; <i64> [#uses=2]
+ %tmp49 = add i64 %j.013, %indvar35 ; <i64> [#uses=2]
+ %scevgep43 = getelementptr [128 x i64]* %A, i64 %tmp48, i64 %tmp49 ; <i64*> [#uses=2]
+ %scevgep44 = getelementptr [128 x i64]* %A, i64 %k.023, i64 %tmp49 ; <i64*> [#uses=1]
+ %5 = load i64* %scevgep43, align 8 ; <i64> [#uses=1]
+ %6 = load i64* %scevgep53, align 8 ; <i64> [#uses=1]
+ %7 = load i64* %scevgep44, align 8 ; <i64> [#uses=1]
+ %8 = mul nsw i64 %7, %6 ; <i64> [#uses=1]
+ %9 = sub nsw i64 %5, %8 ; <i64> [#uses=1]
+ store i64 %9, i64* %scevgep43, align 8
+ %indvar.next36 = add i64 %indvar35, 1 ; <i64> [#uses=2]
+ %exitcond38 = icmp eq i64 %indvar.next36, %tmp37 ; <i1> [#uses=1]
+ br i1 %exitcond38, label %bb8.loopexit12, label %bb5
+
+bb8.loopexit: ; preds = %bb1
+ br i1 %10, label %bb.nph22, label %return
+
+bb8.loopexit12: ; preds = %bb5
+ %exitcond47 = icmp eq i64 %tmp51, %tmp46 ; <i1> [#uses=1]
+ br i1 %exitcond47, label %bb10.loopexit, label %bb.nph16
+
+bb.nph22: ; preds = %bb8.loopexit
+ %tmp46 = sub i64 %tmp, %k.023 ; <i64> [#uses=1]
+ %tmp52 = mul i64 %k.023, 129 ; <i64> [#uses=1]
+ br label %bb.nph16
+
+bb10.loopexit: ; preds = %bb8.loopexit12
+ br i1 %10, label %bb2.preheader, label %return
+
+bb.nph30: ; preds = %entry
+ %tmp = add i64 %n, -1 ; <i64> [#uses=2]
+ br label %bb2.preheader
+
+bb2.preheader: ; preds = %bb.nph30, %bb10.loopexit
+ %k.023 = phi i64 [ 0, %bb.nph30 ], [ %j.013, %bb10.loopexit ] ; <i64> [#uses=8]
+ %j.013 = add i64 %k.023, 1 ; <i64> [#uses=5]
+ %10 = icmp slt i64 %j.013, %n ; <i1> [#uses=3]
+ br i1 %10, label %bb.nph, label %return
+
+return: ; preds = %bb2.preheader, %bb10.loopexit, %bb8.loopexit, %entry
+ ret void
+}
+
+; CHECK: Scop: bb5 => bb8.loopexit12 Parameters: ({0,+,1}<%bb2.preheader>, %n, {0,+,1}<%bb.nph16>, ), Max Loop Depth: 1
+; CHECK: Scop: bb.nph16 => bb10.loopexit Parameters: ({0,+,1}<%bb2.preheader>, %n, ), Max Loop Depth: 2
+; CHECK: Scop: bb1 => bb8.loopexit Parameters: ({0,+,1}<%bb2.preheader>, %n, ), Max Loop Depth: 1
+
+; INDVAR: Scop: bb1 => bb8.loopexit Parameters: ({0,+,1}<%bb2.preheader>, %n, ), Max Loop Depth: 1
+; INDVAR: Scop: bb.nph16 => bb10.loopexit Parameters: ({0,+,1}<%bb2.preheader>, %n, ), Max Loop Depth: 2
+; INDVAR: Scop: bb5 => bb8.loopexit12 Parameters: ({0,+,1}<%bb2.preheader>, %n, {0,+,1}<%bb.nph16>, ), Max Loop Depth: 1
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+
+;void f(long a[][128], long N, long M) {
+; long i, j;
+; for (j = 0; j < M; ++j)
+; for (i = 0; i < N; ++i)
+; ...
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f([128 x i64]* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = icmp sgt i64 %M, 0 ; <i1> [#uses=1]
+ %1 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ %or.cond = and i1 %0, %1 ; <i1> [#uses=1]
+ br i1 %or.cond, label %bb2.preheader, label %return
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %i.06 = phi i64 [ 0, %bb2.preheader ], [ %2, %bb1 ] ; <i64> [#uses=3]
+ %scevgep = getelementptr [128 x i64]* %a, i64 %i.06, i64 %4 ; <i64*> [#uses=1]
+ %tmp = add i64 %i.06, %N ; <i64> [#uses=1]
+ store i64 %tmp, i64* %scevgep, align 8
+ %2 = add nsw i64 %i.06, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %3 = add i64 %4, 1 ; <i64> [#uses=2]
+ %exitcond9 = icmp eq i64 %3, %M ; <i1> [#uses=1]
+ br i1 %exitcond9, label %return, label %bb2.preheader
+
+bb2.preheader: ; preds = %bb3, %entry
+ %4 = phi i64 [ %3, %bb3 ], [ 0, %entry ] ; <i64> [#uses=2]
+ br label %bb1
+
+return: ; preds = %bb3, %entry
+ ret void
+}
+
+; CHECK: Scop: bb2.preheader => return.single_exit Parameters: (%M, %N, ), Max Loop Depth: 2
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+;void f(long a[], long N, long M) {
+; long i;
+
+; for (i = 0; i < N; ++i)
+; a[i] = i;
+
+; a[M] = 0;
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N, i64 %M) nounwind {
+entry:
+ %0 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb, label %bb2
+
+bb: ; preds = %bb, %entry
+ %1 = phi i64 [ 0, %entry ], [ %2, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %1 ; <i64*> [#uses=1]
+ store i64 %1, i64* %scevgep, align 8
+ %2 = add nsw i64 %1, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb
+
+bb2: ; preds = %bb, %entry
+ %3 = getelementptr inbounds i64* %a, i64 %M ; <i64*> [#uses=1]
+ store i64 0, i64* %3, align 8
+ ret void
+}
+
+; CHECK: Scop: entry => <Function Return> Parameters: (%N, %M, )
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-prepare -analyze %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+declare i32 @funa() align 2
+
+define void @funb() align 2 {
+entry:
+ br label %bb117
+
+bb117: ; preds = %bb56
+ %0 = invoke i32 @funa()
+ to label %bb121 unwind label %invcont118 ; <%struct.btHullTriangle*> [#uses=1]
+
+invcont118: ; preds = %bb117
+ br label %bb121
+
+bb121: ; preds = %bb120, %invcont118
+ %iftmp.82.0 = phi i32 [ 0, %bb117 ], [ 1, %invcont118 ] ; <i8> [#uses=1]
+ %te.1 = phi i32 [ undef, %invcont118 ], [ %0, %bb117 ] ;
+ %cnd = icmp ne i32 %iftmp.82.0, %te.1 ; <i1> [#uses=1]
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-prepare -polly-detect -analyze %s
+; ModuleID = '/tmp/invoke_edge_not_supported.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+
+define i16 @v() {
+entry:
+ br i1 undef, label %bb16, label %invcont12
+
+invcont12: ; preds = %invcont11
+ %a = invoke i16 @v() to label %return unwind label %lpad22 ; <i16*> [#uses=1]
+
+bb16: ; preds = %bb7
+ br i1 undef, label %bb9, label %return
+
+return: ; preds = %bb16, %invcont12
+ %b = phi i16 [ %a, %invcont12 ], [ 0, %bb16 ] ; <i16*> [#uses=1]
+ ret i16 %b
+
+bb9: ; preds = %bb3
+ ret i16 0
+
+lpad22: ; preds = %invcont12
+ unreachable
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s -check-prefix=WITHAF
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+
+;void f(long a[], long N) {
+; long i;
+; for (i = 0; i < 128; ++i)
+; a[i] = a[i] - a[i + 2];
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N) nounwind {
+entry:
+ br label %bb
+
+bb: ; preds = %bb, %entry
+ %i.03 = phi i64 [ 0, %entry ], [ %3, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %i.03 ; <i64*> [#uses=2]
+ %tmp = add i64 %i.03, 2 ; <i64> [#uses=1]
+ %scevgep4 = getelementptr i64* %a, i64 %tmp ; <i64*> [#uses=1]
+ %0 = load i64* %scevgep, align 8 ; <i64> [#uses=1]
+ %1 = load i64* %scevgep4, align 8 ; <i64> [#uses=1]
+ %2 = sub i64 %0, %1 ; <i64> [#uses=1]
+ store i64 %2, i64* %scevgep, align 8
+ %3 = add nsw i64 %i.03, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %3, 128 ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb
+ ret void
+}
+
+; CHECK: Scop: bb => return Parameters: ()
+; WITHAF: Scop: bb => return Parameters: (), Max Loop Depth: 1
+; WITHAF: Bounds of Loop: bb: { 127 }
+; WITHAF: BB: bb{
+; WITHAF: Reads %a[8 * {0,+,1}<nuw><nsw><%bb> + 0]
+; WITHAF: Reads %a[8 * {0,+,1}<nuw><nsw><%bb> + 16]
+; WITHAF: Writes %a[8 * {0,+,1}<nuw><nsw><%bb> + 0]
+; WITHAF: }
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+; XFAIL: *
+;void f(int a[], int N) {
+; int i;
+; for (i = 0; i < N; ++i)
+; ...
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N) nounwind {
+entry:
+ %0 = icmp sgt i64 %N, 0 ; <i1> [#uses=1]
+ br i1 %0, label %bb, label %return
+
+bb: ; preds = %bb, %entry
+ %1 = phi i64 [ 0, %entry ], [ %2, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %1 ; <i64*> [#uses=1]
+ store i64 %1, i64* %scevgep, align 8
+ %2 = add nsw i64 %1, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %2, %N ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb, %entry
+ ret void
+}
+
+; CHECK: Scop: entry => <Function Return> Parameters: (%N, )
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze %s | FileCheck %s
+
+
+;void f(long a[], long N) {
+; long M = rnd();
+; long i;
+
+; for (i = 0; i < M; ++i)
+; a[i] = i;
+
+; a[N] = 0;
+;}
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* nocapture %a, i64 %N) nounwind {
+entry:
+ %0 = tail call i64 (...)* @rnd() nounwind ; <i64> [#uses=2]
+ %1 = icmp sgt i64 %0, 0 ; <i1> [#uses=1]
+ br i1 %1, label %bb, label %bb2
+
+bb: ; preds = %bb, %entry
+ %2 = phi i64 [ 0, %entry ], [ %3, %bb ] ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %2 ; <i64*> [#uses=1]
+ store i64 %2, i64* %scevgep, align 8
+ %3 = add nsw i64 %2, 1 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %3, %0 ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb
+
+bb2: ; preds = %bb, %entry
+ %4 = getelementptr inbounds i64* %a, i64 %N ; <i64*> [#uses=1]
+ store i64 0, i64* %4, align 8
+ ret void
+}
+
+declare i64 @rnd(...)
+
+; CHECK: Scop: bb => bb2.single_exit Parameters: (%0, ), Max Loop Depth: 1
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-prepare -polly-analyze-ir -analyze %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+;long f(long a[], long n) {
+; long i, k;
+; k = 0;
+; for (i = 1; i < n; ++i) {
+; k += a[i];
+; }
+; return k;
+;}
+
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-linux-gnu"
+
+define i64 @f(i64* nocapture %a, i64 %n) nounwind readonly {
+entry:
+ %0 = icmp sgt i64 %n, 1 ; <i1> [#uses=1]
+ br i1 %0, label %bb.nph, label %bb2
+
+bb.nph: ; preds = %entry
+ %tmp = add i64 %n, -1 ; <i64> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp6, %bb ] ; <i64> [#uses=1]
+ %k.05 = phi i64 [ 0, %bb.nph ], [ %2, %bb ] ; <i64> [#uses=1]
+ %tmp6 = add i64 %indvar, 1 ; <i64> [#uses=3]
+ %scevgep = getelementptr i64* %a, i64 %tmp6 ; <i64*> [#uses=1]
+ %1 = load i64* %scevgep, align 8 ; <i64> [#uses=1]
+ %2 = add nsw i64 %1, %k.05 ; <i64> [#uses=2]
+ %exitcond = icmp eq i64 %tmp6, %tmp ; <i1> [#uses=1]
+ br i1 %exitcond, label %bb2, label %bb
+
+bb2: ; preds = %bb, %entry
+ %k.0.lcssa = phi i64 [ 0, %entry ], [ %2, %bb ] ; <i64> [#uses=1]
+ ret i64 %k.0.lcssa
+}
+
+; CHECK: Bounds of Loop: bb: { 1 * %n + -2 }
+; CHECK: BB: bb{
+; CHECK: Reads %k.05.reg2mem[0] Refs: Must alias {%k.05.reg2mem, } May alias {},
+; CHECK: Reads %a[8 * {0,+,1}<%bb> + 8] Refs: Must alias {%a, } May alias {},
+; CHECK: Writes %k.0.lcssa.reg2mem[0] Refs: Must alias {%k.0.lcssa.reg2mem, } May alias {},
+; CHECK: Writes %k.05.reg2mem[0] Refs: Must alias {%k.05.reg2mem, } May alias {},
+; CHECK: }
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-scops %s -analyze %s | not FileCheck %s
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define fastcc void @fix_operands() nounwind {
+entry:
+ br i1 undef, label %bb3, label %bb1
+
+bb1: ; preds = %bb
+ %0 = icmp eq i32 0, undef ; <i1> [#uses=1]
+ br i1 %0, label %bb3, label %bb2
+
+bb2: ; preds = %bb1
+ br label %bb3
+
+bb3: ; preds = %bb2, %bb1, %bb
+ br label %bb14
+
+bb14: ; preds = %bb5, %bb4, %bb3, %entry
+ ret void
+}
+
+; CHECK: Scop!
--- /dev/null
+#define TYPE float
+#define NUM 4
+
+TYPE A[NUM];
+TYPE B[NUM];
+TYPE C[NUM];
+
+void vector_multiply(void) {
+ int i;
+ for (i = 0; i < NUM; i++) {
+ A[i] = B[i] * C[i];
+ }
+}
--- /dev/null
+; RUN: opt -polly-analyze-ir -analyze < %s 2>&1 | not FileCheck %s
+; ModuleID = 'not-a-reduction.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@B = common global [4 x float] zeroinitializer, align 16
+@C = common global [4 x float] zeroinitializer, align 16
+@A = common global [4 x float] zeroinitializer, align 16
+
+define void @vector_multiply() nounwind {
+bb:
+ br label %bb3
+
+bb3: ; preds = %bb7, %bb
+ %indvar = phi i64 [ %indvar.next, %bb7 ], [ 0, %bb ]
+ %scevgep = getelementptr [4 x float]* @A, i64 0, i64 %indvar
+ %scevgep1 = getelementptr [4 x float]* @C, i64 0, i64 %indvar
+ %scevgep2 = getelementptr [4 x float]* @B, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 4
+ br i1 %exitcond, label %bb4, label %bb8
+
+bb4: ; preds = %bb3
+ %tmp = load float* %scevgep2, align 4
+ %tmp5 = load float* %scevgep1, align 4
+ %tmp6 = fmul float %tmp, %tmp5
+ store float %tmp6, float* %scevgep, align 4
+ br label %bb7
+
+bb7: ; preds = %bb4
+ %indvar.next = add i64 %indvar, 1
+ br label %bb3
+
+bb8: ; preds = %bb3
+ ret void
+}
+
+; CHECK: Reduction
--- /dev/null
+#define NUM 128
+
+int A[NUM];
+int R;
+
+int reduction(void) {
+ int i;
+ for (i = 0; i < NUM; i++) {
+ R += A[i];
+ }
+ return R;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze < %s 2>&1 | FileCheck %s
+; ModuleID = 'reduction-add.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [128 x i32] zeroinitializer, align 16
+@R = common global i32 0, align 4
+
+define i32 @reduction() nounwind {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb5, %bb
+ %indvar = phi i64 [ %indvar.next, %bb5 ], [ 0, %bb ]
+ %scevgep = getelementptr [128 x i32]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 128
+ br i1 %exitcond, label %bb2, label %bb6
+
+bb2: ; preds = %bb1
+ %tmp = load i32* %scevgep, align 4
+ %tmp3 = load i32* @R, align 4
+ %tmp4 = add nsw i32 %tmp3, %tmp
+ store i32 %tmp4, i32* @R, align 4
+ br label %bb5
+
+bb5: ; preds = %bb2
+ %indvar.next = add i64 %indvar, 1
+ br label %bb1
+
+bb6: ; preds = %bb1
+ %tmp7 = load i32* @R, align 4
+ ret i32 %tmp7
+}
+
+; CHECK: Reduction
--- /dev/null
+#define NUM 128
+
+int A[NUM];
+int R;
+
+int reduction(void) {
+ int i;
+ for (i = 0; i < NUM; i++) {
+ R -= A[i];
+ }
+ return R;
+}
--- /dev/null
+; RUN: opt -polly-analyze-ir -analyze < %s 2>&1 | not FileCheck %s
+; ModuleID = 'reduction-sub.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [128 x i32] zeroinitializer, align 16
+@R = common global i32 0, align 4
+
+define i32 @reduction() nounwind {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb5, %bb
+ %indvar = phi i64 [ %indvar.next, %bb5 ], [ 0, %bb ]
+ %scevgep = getelementptr [128 x i32]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 128
+ br i1 %exitcond, label %bb2, label %bb6
+
+bb2: ; preds = %bb1
+ %tmp = load i32* %scevgep, align 4
+ %tmp3 = load i32* @R, align 4
+ %tmp4 = sub nsw i32 %tmp3, %tmp
+ store i32 %tmp4, i32* @R, align 4
+ br label %bb5
+
+bb5: ; preds = %bb2
+ %indvar.next = add i64 %indvar, 1
+ br label %bb1
+
+bb6: ; preds = %bb1
+ %tmp7 = load i32* @R, align 4
+ ret i32 %tmp7
+}
+
+; CHECK: Reduction
--- /dev/null
+#define NUM 128
+
+int A[NUM];
+int R;
+
+int not_a_reduction(void) {
+ int i;
+ for (i = 0; i < NUM; i++) {
+ R += 1 + A[i];
+ }
+ return R;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -analyze < %s 2>&1 | FileCheck %s
+; ModuleID = 'reduction-with-added-immediate.s'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@A = common global [128 x i32] zeroinitializer, align 16
+@R = common global i32 0, align 4
+
+define i32 @not_a_reduction() nounwind {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb6, %bb
+ %indvar = phi i64 [ %indvar.next, %bb6 ], [ 0, %bb ]
+ %scevgep = getelementptr [128 x i32]* @A, i64 0, i64 %indvar
+ %exitcond = icmp ne i64 %indvar, 128
+ br i1 %exitcond, label %bb2, label %bb7
+
+bb2: ; preds = %bb1
+ %tmp = load i32* %scevgep, align 4
+ %tmp3 = add nsw i32 %tmp, 1
+ %tmp4 = load i32* @R, align 4
+ %tmp5 = add nsw i32 %tmp4, %tmp3
+ store i32 %tmp5, i32* @R, align 4
+ br label %bb6
+
+bb6: ; preds = %bb2
+ %indvar.next = add i64 %indvar, 1
+ br label %bb1
+
+bb7: ; preds = %bb1
+ %tmp8 = load i32* @R, align 4
+ ret i32 %tmp8
+}
+
+; CHECK: Reduction
--- /dev/null
+#!/bin/sh
+
+clang -S -emit-llvm -O0 $1
+
+SFILE=`echo $1 | sed -e 's/\.c/.s/g'`
+LLFILE=`echo $1 | sed -e 's/\.c/.ll/g'`
+
+opt -correlated-propagation -mem2reg -instcombine -loop-simplify -indvars \
+-instnamer ${SFILE} -S > ${LLFILE}
+
+rm ${SFILE}
--- /dev/null
+# -*clang- Python -*-
+
+import os
+import platform
+
+# Configuration file for the 'lit' test runner.
+
+# name: The name of this test suite.
+config.name = 'Polly'
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+execute_external = platform.system() != 'Windows'
+config.test_format = lit.formats.ShTest(execute_external)
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes = ['.ll']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+polly_obj_root = getattr(config, 'polly_obj_root', None)
+if polly_obj_root is not None:
+ config.test_exec_root = os.path.join(polly_obj_root, 'test')
+
+# Set llvm_{src,obj}_root for use by others.
+config.llvm_src_root = getattr(config, 'llvm_src_root', None)
+config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
+
+# Tweak the PATH to include the tools dir and the scripts dir.
+if polly_obj_root is not None:
+ llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
+ if not llvm_tools_dir:
+ lit.fatal('No LLVM tools dir set!')
+ path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
+ config.environment['PATH'] = path
+
+ llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
+ if not llvm_libs_dir:
+ lit.fatal('No LLVM libs dir set!')
+ path = os.path.pathsep.join((llvm_libs_dir,
+ config.environment.get('LD_LIBRARY_PATH','')))
+ config.environment['LD_LIBRARY_PATH'] = path
+
+###
+
+# Check that the object root is known.
+if config.test_exec_root is None:
+ # Otherwise, we haven't loaded the site specific configuration (the user is
+ # probably trying to run on a test file directly, and either the site
+ # configuration hasn't been created by the build system, or we are in an
+ # out-of-tree build situation).
+
+ # Check for 'polly_site_config' user parameter, and use that if available.
+ site_cfg = lit.params.get('polly_site_config', None)
+ if site_cfg and os.path.exists(site_cfg):
+ lit.load_config(config, site_cfg)
+ raise SystemExit
+
+ # Try to detect the situation where we are using an out-of-tree build by
+ # looking for 'llvm-config'.
+ #
+ # FIXME: I debated (i.e., wrote and threw away) adding logic to
+ # automagically generate the lit.site.cfg if we are in some kind of fresh
+ # build situation. This means knowing how to invoke the build system though,
+ # and I decided it was too much magic. We should solve this by just having
+ # the .cfg files generated during the configuration step.
+
+ llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
+ if not llvm_config:
+ lit.fatal('No site specific configuration available!')
+
+ # Get the source and object roots.
+ llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
+ llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
+ polly_src_root = os.path.join(llvm_src_root, "tools", "polly")
+ polly_obj_root = os.path.join(llvm_obj_root, "tools", "polly")
+
+ # Validate that we got a tree which points to here, using the standard
+ # tools/polly layout.
+ this_src_root = os.path.dirname(config.test_source_root)
+ if os.path.realpath(polly_src_root) != os.path.realpath(this_src_root):
+ lit.fatal('No site specific configuration available!')
+
+ # Check that the site specific configuration exists.
+ site_cfg = os.path.join(polly_obj_root, 'test', 'lit.site.cfg')
+ if not os.path.exists(site_cfg):
+ lit.fatal('No site specific configuration available!')
+
+ # Okay, that worked. Notify the user of the automagic, and reconfigure.
+ lit.note('using out-of-tree build at %r' % polly_obj_root)
+ lit.load_config(config, site_cfg)
+ raise SystemExit
+
--- /dev/null
+## Autogenerated by LLVM/Polly configuration.
+# Do not edit!
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.polly_obj_root = "@POLLY_BINARY_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+lit.params['build_config'] = "@POLLY_SOURCE_DIR@/test"
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+ config.llvm_tools_dir = config.llvm_tools_dir % lit.params
+ config.llvm_libs_dir = config.llvm_libs_dir % lit.params
+except KeyError,e:
+ key, = e.args
+ lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+config.substitutions.append(('%loadPolly', '-load '
+ + config.llvm_libs_dir + '/LLVMPolly.so '))
+config.substitutions.append(('%defaultOpts', ' -basicaa -polly-prepare -polly-region-simplify -scev-aa '))
+config.substitutions.append(('%polybenchOpts', ' -O3 -loop-simplify -indvars '))
+
+# Let the main config do the real work.
+lit.load_config(config, "@POLLY_SOURCE_DIR@/test/lit.cfg")
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-scops -S < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+define void @foo() nounwind {
+start:
+ br label %end
+
+end:
+ ret void
+}
+
+; CHECK: foo
--- /dev/null
+* * * * * * * * * *
+* PolyBenchs 1.0 *
+* * * * * * * * * *
+
+
+* Available benchmarks:
+
+::linear-algebra::
+linear-algebra/kernels:
+linear-algebra/kernels/atax/2mm.c
+linear-algebra/kernels/atax/3mm.c
+linear-algebra/kernels/atax/atax.c
+linear-algebra/kernels/bicg/bicg.c
+linear-algebra/kernels/doitgen/doitgen.c
+linear-algebra/kernels/gemm/gemm.c
+linear-algebra/kernels/gemver/gemver.c
+linear-algebra/kernels/gesummv/gesummv.c
+
+linear-algebra/solvers:
+linear-algebra/solvers/gramschmidt/gramschmidt.c
+linear-algebra/solvers/lu/lu.c
+linear-algebra/solvers/ludcmp/ludcmp.c
+
+::datamining::
+datamining/correlation/correlation.c
+datamining/covariance/covariance.c
+
+::stencils::
+stencils/adi/adi.c
+stencils/jacobi-2d-imper/jacobi-2d-imper.c
+stencils/seidel/seidel.c
+
+
+* To compile a benchmark without any monitoring:
+
+$> gcc -I utilities utilities/instrument.c linear-algebra/kernels/atax/atax.c
+
+
+
+* To compile a benchmark with execution time reporting:
+
+$> gcc -I utilities utilities/instrument.c linear-algebra/kernels/atax/atax.c -DPOLYBENCH_TIME
+
+
+* Available options
+
+They are all passed as macro definitions during compilation time. The
+current list is:
+- POLYBENCH_TIME: output execution time (gettimeofday) [default: off]
+- POLYBENCH_NO_FLUSH_CACHE: don't flush the cache before calling the
+ timer [default: flush the cache]
+- POLYBENCH_LINUX_FIFO_SCHEDULER: use FIFO real-time scheduler for the
+ kernel execution, the program must be run as root, under linux only,
+ and compiled with -lc [default: off]
+- POLYBENCH_CACHE_SIZE_KB: cache size to flush, in kB [default: 8192]
+- POLYBENCH_TEST_MALLOC: use malloc instead of stack allocation [default: off]
+- POLYBENCH_DUMP_ARRAYS: dump all live-out arrays on stderr [default: off]
+
+- Nxx: override the default dataset values
+
+
+* Collecting the execution time of all files
+
+$> scripts/runall.sh <machine-name>
+
+Note: the script runall must be run from the root directory of the archive.
+
+
+** Specifying different dataset size for one file in particular
+
+- Create a compiler.opts file under the directory of the benchmark
+- Specify a set of options, e.g. -DX=1024 -DY=1024 (see gemm for an example)
+
+
+** To specify another compiler
+
+- Simplest is to edit scripts/runall.sh, and change the
+ COMPILER_COMMAND variable. One can also export the adequate
+ COMPILER_COMMAND variable in the shell environment.
+
+
+
+* Author
+Louis-Noel Pouchet <pouchet@cse.ohio-state.edu>
+
+* Contributors
+Uday Bondhugula <ubondhug@us.ibm.com>
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef M
+# define M 500
+#endif
+#ifndef N
+# define N 500
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE float_n = 321414134.01;
+DATA_TYPE eps = 0.005;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE data[M + 1][N + 1];
+DATA_TYPE symmat[M + 1][M + 1];
+DATA_TYPE stddev[M + 1];
+DATA_TYPE mean[M + 1];
+#else
+DATA_TYPE** data = (DATA_TYPE**)malloc((M + 1) * sizeof(DATA_TYPE*));
+DATA_TYPE** symmat = (DATA_TYPE**)malloc((M + 1) * sizeof(DATA_TYPE*));
+DATA_TYPE* stddev = (DATA_TYPE*)malloc((M + 1) * sizeof(DATA_TYPE));
+DATA_TYPE* mean = (DATA_TYPE*)malloc((M + 1) * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i <= M; ++i)
+ {
+ data[i] = (DATA_TYPE*)malloc((N + 1) * sizeof(DATA_TYPE));
+ symmat[i] = (DATA_TYPE*)malloc((M + 1) * sizeof(DATA_TYPE));
+ }
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i <= M; i++)
+ for (j = 0; j <= N; j++)
+ data[i][j] = ((DATA_TYPE) i*j) / M;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i <= M; i++)
+ for (j = 0; j <= M; j++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, symmat[i][j]);
+ if ((i * M + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long m = M;
+ long n = N;
+#else
+void scop_func(long m, long n) {
+#endif
+
+ int i, j, j1, j2;
+#pragma scop
+#pragma live-out symmat
+
+ /* Center and reduce the column vectors. */
+ for (i = 1; i <= n; i++)
+ for (j = 1; j <= m; j++)
+ {
+ data[i][j] -= mean[j];
+ data[i][j] /= sqrt(float_n) * stddev[j];
+ }
+
+ /* Calculate the m * m correlation matrix. */
+ for (j1 = 1; j1 <= m-1; j1++)
+ {
+ symmat[j1][j1] = 1.0;
+ for (j2 = j1+1; j2 <= m; j2++)
+ {
+ symmat[j1][j2] = 0.0;
+ for (i = 1; i <= n; i++)
+ symmat[j1][j2] += (data[i][j1] * data[i][j2]);
+ symmat[j2][j1] = symmat[j1][j2];
+ }
+ }
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, j1, j2;
+ int m = M;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+
+#define sqrt_of_array_cell(x,j) sqrt(x[j])
+
+
+ /* Determine mean of column vectors of input data matrix */
+ for (j = 1; j <= m; j++)
+ {
+ mean[j] = 0.0;
+ for (i = 1; i <= n; i++)
+ mean[j] += data[i][j];
+ mean[j] /= float_n;
+ }
+
+/* Determine standard deviations of column vectors of data matrix. */
+ for (j = 1; j <= m; j++)
+ {
+ stddev[j] = 0.0;
+ for (i = 1; i <= n; i++)
+ stddev[j] += (data[i][j] - mean[j]) * (data[i][j] - mean[j]);
+ stddev[j] /= float_n;
+ stddev[j] = sqrt_of_array_cell(stddev, j);
+ /* The following in an inelegant but usual way to handle
+ near-zero std. dev. values, which below would cause a zero-
+ divide. */
+ stddev[j] = stddev[j] <= eps ? 1.0 : stddev[j];
+ }
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(m, n);
+#endif
+ symmat[m][m] = 1.0;
+
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -print-top-scop-only -analyze %s | FileCheck %s
+; XFAIL: *
+; ModuleID = './datamining/correlation/correlation_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@float_n = global double 0x41B32863F6028F5C
+@eps = global double 5.000000e-03
+@data = common global [501 x [501 x double]] zeroinitializer, align 32
+@symmat = common global [501 x [501 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@mean = common global [501 x double] zeroinitializer, align 32
+@stddev = common global [501 x double] zeroinitializer, align 32
+
+define void @scop_func(i64 %m, i64 %n) nounwind {
+entry:
+ %0 = icmp slt i64 %n, 1
+ %1 = icmp slt i64 %m, 1
+ %or.cond = or i1 %0, %1
+ br i1 %or.cond, label %bb13.preheader, label %bb2.preheader.preheader
+
+bb2.preheader.preheader: ; preds = %entry
+ br label %bb2.preheader
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %indvar52 = phi i64 [ %tmp63, %bb1 ], [ 0, %bb2.preheader ]
+ %tmp9 = add i64 %indvar52, 1
+ %scevgep59 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp8, i64 %tmp9
+ %tmp61 = add i64 %indvar52, 2
+ %tmp3 = add i64 %indvar52, 1
+ %scevgep60 = getelementptr [501 x double]* @mean, i64 0, i64 %tmp3
+ %scevgep55 = getelementptr [501 x double]* @stddev, i64 0, i64 %tmp3
+ %tmp63 = add i64 %indvar52, 1
+ %2 = load double* %scevgep59, align 8
+ %3 = load double* %scevgep60, align 8
+ %4 = fsub double %2, %3
+ store double %4, double* %scevgep59, align 8
+ %5 = load double* @float_n, align 8
+ %6 = tail call double @sqrt(double %5) nounwind readonly
+ %7 = load double* %scevgep55, align 8
+ %8 = fmul double %6, %7
+ %9 = fdiv double %4, %8
+ store double %9, double* %scevgep59, align 8
+ %10 = icmp sgt i64 %tmp61, %m
+ br i1 %10, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %11 = icmp sgt i64 %tmp65, %n
+ br i1 %11, label %bb13.preheader.loopexit, label %bb2.preheader
+
+bb2.preheader: ; preds = %bb2.preheader.preheader, %bb3
+ %indvar56 = phi i64 [ %tmp62, %bb3 ], [ 0, %bb2.preheader.preheader ]
+ %tmp8 = add i64 %indvar56, 1
+ %tmp65 = add i64 %indvar56, 2
+ %tmp62 = add i64 %indvar56, 1
+ br label %bb1
+
+bb13.preheader.loopexit: ; preds = %bb3
+ br label %bb13.preheader
+
+bb13.preheader: ; preds = %bb13.preheader.loopexit, %entry
+ %12 = add nsw i64 %m, -1
+ %13 = icmp slt i64 %12, 1
+ br i1 %13, label %return, label %bb6.preheader
+
+bb6.preheader: ; preds = %bb13.preheader
+ %tmp = add i64 %m, -1
+ br label %bb6
+
+bb6: ; preds = %bb6.preheader, %bb12
+ %indvar14 = phi i64 [ 0, %bb6.preheader ], [ %indvar.next15, %bb12 ]
+ %tmp35 = add i64 %indvar14, 3
+ %tmp36 = trunc i64 %tmp35 to i32
+ %tmp38 = add i64 %indvar14, 2
+ %tmp39 = trunc i64 %tmp38 to i32
+ %tmp46 = add i64 %indvar14, 1
+ %scevgep49 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 0, i64 %tmp46
+ %scevgep53 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 %tmp46, i64 0
+ %tmp59 = mul i64 %indvar14, 502
+ %tmp60 = add i64 %tmp59, 1
+ %scevgep61 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 1, i64 %tmp60
+ store double 1.000000e+00, double* %scevgep61, align 8
+ %14 = icmp sgt i64 %tmp38, %m
+ br i1 %14, label %bb12, label %bb.nph12
+
+bb.nph12: ; preds = %bb6
+ br i1 %0, label %bb10.us.preheader, label %bb.nph.preheader
+
+bb10.us.preheader: ; preds = %bb.nph12
+ br label %bb10.us
+
+bb.nph.preheader: ; preds = %bb.nph12
+ br label %bb.nph
+
+bb10.us: ; preds = %bb10.us.preheader, %bb10.us
+ %indvar = phi i32 [ %indvar.next, %bb10.us ], [ 0, %bb10.us.preheader ]
+ %storemerge2.us = add i32 %tmp36, %indvar
+ %storemerge28.us = add i32 %tmp39, %indvar
+ %tmp55 = sext i32 %storemerge28.us to i64
+ %tmp56 = mul i64 %tmp55, 501
+ %scevgep57 = getelementptr double* %scevgep49, i64 %tmp56
+ %scevgep58 = getelementptr double* %scevgep53, i64 %tmp55
+ store double 0.000000e+00, double* %scevgep58, align 8
+ store double 0.000000e+00, double* %scevgep57, align 8
+ %15 = sext i32 %storemerge2.us to i64
+ %16 = icmp sgt i64 %15, %m
+ %indvar.next = add i32 %indvar, 1
+ br i1 %16, label %bb12.loopexit1, label %bb10.us
+
+bb.nph: ; preds = %bb.nph.preheader, %bb10
+ %indvar41 = phi i32 [ %indvar.next42, %bb10 ], [ 0, %bb.nph.preheader ]
+ %storemerge2 = add i32 %tmp36, %indvar41
+ %storemerge28 = add i32 %tmp39, %indvar41
+ %tmp50 = sext i32 %storemerge28 to i64
+ %tmp51 = mul i64 %tmp50, 501
+ %scevgep52 = getelementptr double* %scevgep49, i64 %tmp51
+ %scevgep54 = getelementptr double* %scevgep53, i64 %tmp50
+ %tmp21 = sext i32 %storemerge28 to i64
+ store double 0.000000e+00, double* %scevgep54, align 8
+ br label %bb8
+
+bb8: ; preds = %bb8, %bb.nph
+ %indvar38 = phi i64 [ 0, %bb.nph ], [ %tmp40, %bb8 ]
+ %17 = phi double [ 0.000000e+00, %bb.nph ], [ %21, %bb8 ]
+ %tmp44 = add i64 %indvar38, 1
+ %scevgep47 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp44, i64 %tmp46
+ %tmp48 = add i64 %indvar38, 2
+ %tmp13 = add i64 %indvar38, 1
+ %scevgep = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp13, i64 %tmp21
+ %tmp40 = add i64 %indvar38, 1
+ %18 = load double* %scevgep47, align 8
+ %19 = load double* %scevgep, align 8
+ %20 = fmul double %18, %19
+ %21 = fadd double %17, %20
+ %22 = icmp sgt i64 %tmp48, %n
+ br i1 %22, label %bb10, label %bb8
+
+bb10: ; preds = %bb8
+ %.lcssa = phi double [ %21, %bb8 ]
+ store double %.lcssa, double* %scevgep54
+ store double %.lcssa, double* %scevgep52, align 8
+ %23 = sext i32 %storemerge2 to i64
+ %24 = icmp sgt i64 %23, %m
+ %indvar.next42 = add i32 %indvar41, 1
+ br i1 %24, label %bb12.loopexit, label %bb.nph
+
+bb12.loopexit: ; preds = %bb10
+ br label %bb12
+
+bb12.loopexit1: ; preds = %bb10.us
+ br label %bb12
+
+bb12: ; preds = %bb12.loopexit1, %bb12.loopexit, %bb6
+ %indvar.next15 = add i64 %indvar14, 1
+ %exitcond = icmp eq i64 %indvar.next15, %tmp
+ br i1 %exitcond, label %return.loopexit, label %bb6
+
+return.loopexit: ; preds = %bb12
+ br label %return
+
+return: ; preds = %return.loopexit, %bb13.preheader
+ ret void
+}
+
+declare double @sqrt(double) nounwind readonly
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -print-top-scop-only -analyze %s | FileCheck %s
+; XFAIL: *
+; ModuleID = './datamining/correlation/correlation_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@float_n = global double 0x41B32863F6028F5C
+@eps = global double 5.000000e-03
+@data = common global [501 x [501 x double]] zeroinitializer, align 32
+@symmat = common global [501 x [501 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@mean = common global [501 x double] zeroinitializer, align 32
+@stddev = common global [501 x double] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph33.bb.nph33.split_crit_edge:
+ br label %bb2.preheader
+
+bb1: ; preds = %bb2.preheader, %bb1
+ %indvar45 = phi i64 [ %tmp57, %bb1 ], [ 0, %bb2.preheader ]
+ %tmp51 = add i64 %indvar45, 1
+ %scevgep53 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp50, i64 %tmp51
+ %tmp44 = add i64 %indvar45, 1
+ %scevgep54 = getelementptr [501 x double]* @mean, i64 0, i64 %tmp44
+ %scevgep49 = getelementptr [501 x double]* @stddev, i64 0, i64 %tmp44
+ %tmp57 = add i64 %indvar45, 1
+ %0 = load double* %scevgep53, align 8
+ %1 = load double* %scevgep54, align 8
+ %2 = fsub double %0, %1
+ store double %2, double* %scevgep53, align 8
+ %3 = load double* @float_n, align 8
+ %4 = tail call double @sqrt(double %3) nounwind readonly
+ %5 = load double* %scevgep49, align 8
+ %6 = fmul double %4, %5
+ %7 = fdiv double %2, %6
+ store double %7, double* %scevgep53, align 8
+ %exitcond43 = icmp eq i64 %tmp57, 500
+ br i1 %exitcond43, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %tmp56 = add i64 %indvar50, 1
+ %exitcond49 = icmp eq i64 %tmp56, 500
+ br i1 %exitcond49, label %bb6.preheader, label %bb2.preheader
+
+bb6.preheader: ; preds = %bb3
+ br label %bb6
+
+bb2.preheader: ; preds = %bb3, %bb.nph33.bb.nph33.split_crit_edge
+ %indvar50 = phi i64 [ 0, %bb.nph33.bb.nph33.split_crit_edge ], [ %tmp56, %bb3 ]
+ %tmp50 = add i64 %indvar50, 1
+ br label %bb1
+
+bb6: ; preds = %bb6.preheader, %bb12
+ %indvar3 = phi i64 [ 0, %bb6.preheader ], [ %indvar.next, %bb12 ]
+ %tmp25 = mul i64 %indvar3, 502
+ %tmp26 = add i64 %tmp25, 2
+ %tmp30 = add i64 %tmp25, 1
+ %tmp33 = add i64 %indvar3, 2
+ %tmp36 = mul i64 %indvar3, -1
+ %tmp12 = add i64 %tmp36, 499
+ %tmp38 = add i64 %indvar3, 1
+ %scevgep42 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 1, i64 %tmp30
+ store double 1.000000e+00, double* %scevgep42, align 8
+ br i1 false, label %bb12, label %bb.nph12.bb.nph12.split_crit_edge
+
+bb.nph12.bb.nph12.split_crit_edge: ; preds = %bb6
+ br label %bb.nph
+
+bb.nph: ; preds = %bb10, %bb.nph12.bb.nph12.split_crit_edge
+ %indvar6 = phi i64 [ %indvar.next7, %bb10 ], [ 0, %bb.nph12.bb.nph12.split_crit_edge ]
+ %tmp27 = add i64 %tmp26, %indvar6
+ %scevgep23 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 1, i64 %tmp27
+ %tmp29 = add i64 %indvar6, 2
+ %scevgep20 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 %tmp29, i64 %tmp30
+ %tmp34 = add i64 %tmp33, %indvar6
+ store double 0.000000e+00, double* %scevgep23, align 8
+ br label %bb8
+
+bb8: ; preds = %bb8, %bb.nph
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp, %bb8 ]
+ %8 = phi double [ 0.000000e+00, %bb.nph ], [ %12, %bb8 ]
+ %tmp32 = add i64 %indvar, 1
+ %scevgep = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp32, i64 %tmp34
+ %scevgep41 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp32, i64 %tmp38
+ %tmp = add i64 %indvar, 1
+ %9 = load double* %scevgep41, align 8
+ %10 = load double* %scevgep, align 8
+ %11 = fmul double %9, %10
+ %12 = fadd double %8, %11
+ %exitcond1 = icmp eq i64 %tmp, 500
+ br i1 %exitcond1, label %bb10, label %bb8
+
+bb10: ; preds = %bb8
+ %.lcssa = phi double [ %12, %bb8 ]
+ store double %.lcssa, double* %scevgep23
+ store double %.lcssa, double* %scevgep20, align 8
+ %indvar.next7 = add i64 %indvar6, 1
+ %exitcond = icmp eq i64 %indvar.next7, %tmp12
+ br i1 %exitcond, label %bb12.loopexit, label %bb.nph
+
+bb12.loopexit: ; preds = %bb10
+ br label %bb12
+
+bb12: ; preds = %bb12.loopexit, %bb6
+ %indvar.next = add i64 %indvar3, 1
+ %exitcond24 = icmp eq i64 %indvar.next, 499
+ br i1 %exitcond24, label %return, label %bb6
+
+return: ; preds = %bb12
+ ret void
+}
+
+declare double @sqrt(double) nounwind readonly
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef M
+# define M 500
+#endif
+#ifndef N
+# define N 500
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE float_n = 321414134.01;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE data[M + 1][N + 1];
+DATA_TYPE symmat[M + 1][M + 1];
+DATA_TYPE mean[M + 1];
+#else
+DATA_TYPE** data = (DATA_TYPE**)malloc((M + 1) * sizeof(DATA_TYPE*));
+DATA_TYPE** symmat = (DATA_TYPE**)malloc((M + 1) * sizeof(DATA_TYPE*));
+DATA_TYPE* mean = (DATA_TYPE*)malloc((M + 1) * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i <= M; ++i)
+ {
+ data[i] = (DATA_TYPE*)malloc((N + 1) * sizeof(DATA_TYPE));
+ symmat[i] = (DATA_TYPE*)malloc((M + 1) * sizeof(DATA_TYPE));
+ }
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i <= M; i++)
+ for (j = 0; j <= N; j++)
+ data[i][j] = ((DATA_TYPE) i*j) / M;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i <= M; i++)
+ for (j = 0; j <= M; j++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, symmat[i][j]);
+ if ((i * M + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ int m = M;
+ int n = N;
+#else
+void scop_func(long m, long n) {
+#endif
+ long i, j, j1, j2;
+#pragma scop
+#pragma live-out symmat
+
+ /* Determine mean of column vectors of input data matrix */
+ for (j = 1; j <= m; j++)
+ {
+ mean[j] = 0.0;
+ for (i = 1; i <= n; i++)
+ mean[j] += data[i][j];
+ mean[j] /= float_n;
+ }
+
+ /* Center the column vectors. */
+ for (i = 1; i <= n; i++)
+ for (j = 1; j <= m; j++)
+ data[i][j] -= mean[j];
+
+ /* Calculate the m * m covariance matrix. */
+ for (j1 = 1; j1 <= m; j1++)
+ for (j2 = j1; j2 <= m; j2++)
+ {
+ symmat[j1][j2] = 0.0;
+ for (i = 1; i <= n; i++)
+ symmat[j1][j2] += data[i][j1] * data[i][j2];
+ symmat[j2][j1] = symmat[j1][j2];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, j1, j2;
+ int m = M;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(m, n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -print-top-scop-only -analyze %s | FileCheck %s
+; XFAIL: *
+; ModuleID = './datamining/covariance/covariance_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@float_n = global double 0x41B32863F6028F5C
+@data = common global [501 x [501 x double]] zeroinitializer, align 32
+@symmat = common global [501 x [501 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@mean = common global [501 x double] zeroinitializer, align 32
+
+define void @scop_func(i64 %m, i64 %n) nounwind {
+entry:
+ %0 = icmp slt i64 %m, 1
+ br i1 %0, label %bb10.preheader, label %bb.nph44
+
+bb.nph44: ; preds = %entry
+ %1 = icmp slt i64 %n, 1
+ %2 = load double* @float_n, align 8
+ br i1 %1, label %bb3.us.preheader, label %bb.nph36.preheader
+
+bb3.us.preheader: ; preds = %bb.nph44
+ br label %bb3.us
+
+bb.nph36.preheader: ; preds = %bb.nph44
+ br label %bb.nph36
+
+bb3.us: ; preds = %bb3.us.preheader, %bb3.us
+ %indvar = phi i64 [ %tmp, %bb3.us ], [ 0, %bb3.us.preheader ]
+ %tmp45 = add i64 %indvar, 2
+ %tmp13 = add i64 %indvar, 1
+ %scevgep = getelementptr [501 x double]* @mean, i64 0, i64 %tmp13
+ %tmp = add i64 %indvar, 1
+ %3 = fdiv double 0.000000e+00, %2
+ store double %3, double* %scevgep, align 8
+ %4 = icmp sgt i64 %tmp45, %m
+ br i1 %4, label %bb10.preheader.loopexit1, label %bb3.us
+
+bb.nph36: ; preds = %bb.nph36.preheader, %bb3
+ %indvar94 = phi i64 [ %tmp100, %bb3 ], [ 0, %bb.nph36.preheader ]
+ %tmp8 = add i64 %indvar94, 1
+ %tmp102 = add i64 %indvar94, 2
+ %scevgep103 = getelementptr [501 x double]* @mean, i64 0, i64 %tmp8
+ %tmp100 = add i64 %indvar94, 1
+ store double 0.000000e+00, double* %scevgep103, align 8
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb.nph36
+ %indvar91 = phi i64 [ 0, %bb.nph36 ], [ %tmp99, %bb1 ]
+ %5 = phi double [ 0.000000e+00, %bb.nph36 ], [ %7, %bb1 ]
+ %tmp7 = add i64 %indvar91, 1
+ %scevgep97 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp7, i64 %tmp8
+ %tmp98 = add i64 %indvar91, 2
+ %tmp99 = add i64 %indvar91, 1
+ %6 = load double* %scevgep97, align 8
+ %7 = fadd double %5, %6
+ %8 = icmp sgt i64 %tmp98, %n
+ br i1 %8, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %.lcssa = phi double [ %7, %bb1 ]
+ %9 = fdiv double %.lcssa, %2
+ store double %9, double* %scevgep103, align 8
+ %10 = icmp sgt i64 %tmp102, %m
+ br i1 %10, label %bb10.preheader.loopexit, label %bb.nph36
+
+bb10.preheader.loopexit: ; preds = %bb3
+ br label %bb10.preheader
+
+bb10.preheader.loopexit1: ; preds = %bb3.us
+ br label %bb10.preheader
+
+bb10.preheader: ; preds = %bb10.preheader.loopexit1, %bb10.preheader.loopexit, %entry
+ %11 = icmp slt i64 %n, 1
+ br i1 %11, label %bb19.preheader, label %bb.nph33
+
+bb7: ; preds = %bb8.preheader, %bb7
+ %indvar77 = phi i64 [ %tmp87, %bb7 ], [ 0, %bb8.preheader ]
+ %tmp21 = add i64 %indvar77, 1
+ %scevgep83 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp20, i64 %tmp21
+ %tmp85 = add i64 %indvar77, 2
+ %tmp16 = add i64 %indvar77, 1
+ %scevgep84 = getelementptr [501 x double]* @mean, i64 0, i64 %tmp16
+ %tmp87 = add i64 %indvar77, 1
+ %12 = load double* %scevgep83, align 8
+ %13 = load double* %scevgep84, align 8
+ %14 = fsub double %12, %13
+ store double %14, double* %scevgep83, align 8
+ %15 = icmp sgt i64 %tmp85, %m
+ br i1 %15, label %bb9, label %bb7
+
+bb9: ; preds = %bb7
+ %16 = icmp sgt i64 %tmp89, %n
+ br i1 %16, label %bb19.preheader.loopexit, label %bb8.preheader
+
+bb.nph33: ; preds = %bb10.preheader
+ br i1 %0, label %return, label %bb8.preheader.preheader
+
+bb8.preheader.preheader: ; preds = %bb.nph33
+ br label %bb8.preheader
+
+bb8.preheader: ; preds = %bb8.preheader.preheader, %bb9
+ %indvar79 = phi i64 [ %tmp86, %bb9 ], [ 0, %bb8.preheader.preheader ]
+ %tmp20 = add i64 %indvar79, 1
+ %tmp89 = add i64 %indvar79, 2
+ %tmp86 = add i64 %indvar79, 1
+ br label %bb7
+
+bb19.preheader.loopexit: ; preds = %bb9
+ br label %bb19.preheader
+
+bb19.preheader: ; preds = %bb19.preheader.loopexit, %bb10.preheader
+ br i1 %0, label %return, label %bb17.preheader.preheader
+
+bb17.preheader.preheader: ; preds = %bb19.preheader
+ br label %bb17.preheader
+
+bb.nph13: ; preds = %bb17.preheader
+ br i1 %11, label %bb16.us.preheader, label %bb.nph13.bb.nph13.split_crit_edge
+
+bb16.us.preheader: ; preds = %bb.nph13
+ br label %bb16.us
+
+bb.nph13.bb.nph13.split_crit_edge: ; preds = %bb.nph13
+ br label %bb.nph
+
+bb16.us: ; preds = %bb16.us.preheader, %bb16.us
+ %indvar48 = phi i64 [ %indvar.next49, %bb16.us ], [ 0, %bb16.us.preheader ]
+ %tmp57 = add i64 %tmp56, %indvar48
+ %scevgep57 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 1, i64 %tmp57
+ %tmp59 = add i64 %indvar48, 1
+ %scevgep52 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 %tmp59, i64 %tmp56
+ %tmp54 = add i64 %tmp61, %indvar48
+ store double 0.000000e+00, double* %scevgep57, align 8
+ store double 0.000000e+00, double* %scevgep52, align 8
+ %17 = icmp sgt i64 %tmp54, %m
+ %indvar.next49 = add i64 %indvar48, 1
+ br i1 %17, label %bb18.loopexit2, label %bb16.us
+
+bb.nph: ; preds = %bb16, %bb.nph13.bb.nph13.split_crit_edge
+ %indvar62 = phi i64 [ 0, %bb.nph13.bb.nph13.split_crit_edge ], [ %indvar.next63, %bb16 ]
+ %tmp72 = add i64 %tmp61, %indvar62
+ %tmp64 = add i64 %indvar62, 1
+ %scevgep74 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 %tmp64, i64 %tmp56
+ %tmp69 = add i64 %tmp56, %indvar62
+ %scevgep76 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 1, i64 %tmp69
+ %tmp74 = add i64 %storemerge214, %indvar62
+ store double 0.000000e+00, double* %scevgep76, align 8
+ br label %bb14
+
+bb14: ; preds = %bb14, %bb.nph
+ %indvar59 = phi i64 [ 0, %bb.nph ], [ %tmp68, %bb14 ]
+ %18 = phi double [ 0.000000e+00, %bb.nph ], [ %22, %bb14 ]
+ %tmp71 = add i64 %indvar59, 1
+ %scevgep65 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp71, i64 %tmp74
+ %scevgep66 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp71, i64 %storemerge214
+ %tmp67 = add i64 %indvar59, 2
+ %tmp68 = add i64 %indvar59, 1
+ %19 = load double* %scevgep66, align 8
+ %20 = load double* %scevgep65, align 8
+ %21 = fmul double %19, %20
+ %22 = fadd double %18, %21
+ %23 = icmp sgt i64 %tmp67, %n
+ br i1 %23, label %bb16, label %bb14
+
+bb16: ; preds = %bb14
+ %.lcssa24 = phi double [ %22, %bb14 ]
+ store double %.lcssa24, double* %scevgep76
+ store double %.lcssa24, double* %scevgep74, align 8
+ %24 = icmp sgt i64 %tmp72, %m
+ %indvar.next63 = add i64 %indvar62, 1
+ br i1 %24, label %bb18.loopexit, label %bb.nph
+
+bb18.loopexit: ; preds = %bb16
+ br label %bb18
+
+bb18.loopexit2: ; preds = %bb16.us
+ br label %bb18
+
+bb18: ; preds = %bb18.loopexit2, %bb18.loopexit, %bb17.preheader
+ %indvar.next = add i64 %indvar27, 1
+ %exitcond = icmp eq i64 %indvar.next, %m
+ br i1 %exitcond, label %return.loopexit, label %bb17.preheader
+
+bb17.preheader: ; preds = %bb17.preheader.preheader, %bb18
+ %indvar27 = phi i64 [ 0, %bb17.preheader.preheader ], [ %indvar.next, %bb18 ]
+ %tmp55 = mul i64 %indvar27, 502
+ %tmp56 = add i64 %tmp55, 1
+ %tmp61 = add i64 %indvar27, 2
+ %storemerge214 = add i64 %indvar27, 1
+ br i1 false, label %bb18, label %bb.nph13
+
+return.loopexit: ; preds = %bb18
+ br label %return
+
+return: ; preds = %return.loopexit, %bb19.preheader, %bb.nph33
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -polly-cloog -analyze %s | FileCheck %s
+; region-simplify make polly fail to detect the canonical induction variable.
+; XFAIL:*
+
+; ModuleID = './datamining/covariance/covariance_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@float_n = global double 0x41B32863F6028F5C
+@data = common global [501 x [501 x double]] zeroinitializer, align 32
+@symmat = common global [501 x [501 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@mean = common global [501 x double] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph44.bb.nph44.split_crit_edge:
+ %0 = load double* @float_n, align 8
+ br label %bb.nph36
+
+bb.nph36: ; preds = %bb3, %bb.nph44.bb.nph44.split_crit_edge
+ %indvar77 = phi i64 [ 0, %bb.nph44.bb.nph44.split_crit_edge ], [ %tmp83, %bb3 ]
+ %tmp48 = add i64 %indvar77, 1
+ %scevgep85 = getelementptr [501 x double]* @mean, i64 0, i64 %tmp48
+ %tmp83 = add i64 %indvar77, 1
+ store double 0.000000e+00, double* %scevgep85, align 8
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb.nph36
+ %indvar73 = phi i64 [ 0, %bb.nph36 ], [ %tmp82, %bb1 ]
+ %1 = phi double [ 0.000000e+00, %bb.nph36 ], [ %3, %bb1 ]
+ %tmp47 = add i64 %indvar73, 1
+ %scevgep80 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp47, i64 %tmp48
+ %tmp82 = add i64 %indvar73, 1
+ %2 = load double* %scevgep80, align 8
+ %3 = fadd double %1, %2
+ %exitcond42 = icmp eq i64 %tmp82, 500
+ br i1 %exitcond42, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %.lcssa41 = phi double [ %3, %bb1 ]
+ %4 = fdiv double %.lcssa41, %0
+ store double %4, double* %scevgep85, align 8
+ %exitcond46 = icmp eq i64 %tmp83, 500
+ br i1 %exitcond46, label %bb8.preheader.preheader, label %bb.nph36
+
+bb8.preheader.preheader: ; preds = %bb3
+ br label %bb8.preheader
+
+bb7: ; preds = %bb8.preheader, %bb7
+ %indvar59 = phi i64 [ %tmp70, %bb7 ], [ 0, %bb8.preheader ]
+ %tmp39 = add i64 %indvar59, 1
+ %scevgep66 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp38, i64 %tmp39
+ %tmp = add i64 %indvar59, 1
+ %scevgep67 = getelementptr [501 x double]* @mean, i64 0, i64 %tmp
+ %tmp70 = add i64 %indvar59, 1
+ %5 = load double* %scevgep66, align 8
+ %6 = load double* %scevgep67, align 8
+ %7 = fsub double %5, %6
+ store double %7, double* %scevgep66, align 8
+ %exitcond33 = icmp eq i64 %tmp70, 500
+ br i1 %exitcond33, label %bb9, label %bb7
+
+bb9: ; preds = %bb7
+ %tmp69 = add i64 %indvar62, 1
+ %exitcond37 = icmp eq i64 %tmp69, 500
+ br i1 %exitcond37, label %bb17.preheader.preheader, label %bb8.preheader
+
+bb17.preheader.preheader: ; preds = %bb9
+ br label %bb17.preheader
+
+bb8.preheader: ; preds = %bb8.preheader.preheader, %bb9
+ %indvar62 = phi i64 [ %tmp69, %bb9 ], [ 0, %bb8.preheader.preheader ]
+ %tmp38 = add i64 %indvar62, 1
+ br label %bb7
+
+bb.nph13.bb.nph13.split_crit_edge: ; preds = %bb17.preheader
+ br label %bb.nph
+
+bb.nph: ; preds = %bb16, %bb.nph13.bb.nph13.split_crit_edge
+ %indvar46 = phi i64 [ 0, %bb.nph13.bb.nph13.split_crit_edge ], [ %indvar.next47, %bb16 ]
+ %tmp20 = add i64 %indvar46, 1
+ %scevgep56 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 %tmp20, i64 %tmp22
+ %tmp24 = add i64 %tmp22, %indvar46
+ %scevgep58 = getelementptr [501 x [501 x double]]* @symmat, i64 0, i64 1, i64 %tmp24
+ %tmp28 = add i64 %storemerge214, %indvar46
+ store double 0.000000e+00, double* %scevgep58, align 8
+ br label %bb14
+
+bb14: ; preds = %bb14, %bb.nph
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp50, %bb14 ]
+ %8 = phi double [ 0.000000e+00, %bb.nph ], [ %12, %bb14 ]
+ %tmp26 = add i64 %indvar, 1
+ %scevgep = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp26, i64 %tmp28
+ %scevgep49 = getelementptr [501 x [501 x double]]* @data, i64 0, i64 %tmp26, i64 %storemerge214
+ %tmp50 = add i64 %indvar, 1
+ %9 = load double* %scevgep49, align 8
+ %10 = load double* %scevgep, align 8
+ %11 = fmul double %9, %10
+ %12 = fadd double %8, %11
+ %exitcond1 = icmp eq i64 %tmp50, 500
+ br i1 %exitcond1, label %bb16, label %bb14
+
+bb16: ; preds = %bb14
+ %.lcssa = phi double [ %12, %bb14 ]
+ store double %.lcssa, double* %scevgep58
+ store double %.lcssa, double* %scevgep56, align 8
+ %indvar.next47 = add i64 %indvar46, 1
+ %exitcond = icmp eq i64 %indvar.next47, %tmp8
+ br i1 %exitcond, label %bb18.loopexit, label %bb.nph
+
+bb18.loopexit: ; preds = %bb16
+ br label %bb18
+
+bb18: ; preds = %bb18.loopexit, %bb17.preheader
+ %indvar.next = add i64 %indvar2, 1
+ %exitcond19 = icmp eq i64 %indvar.next, 500
+ br i1 %exitcond19, label %return, label %bb17.preheader
+
+bb17.preheader: ; preds = %bb17.preheader.preheader, %bb18
+ %indvar2 = phi i64 [ 0, %bb17.preheader.preheader ], [ %indvar.next, %bb18 ]
+ %tmp21 = mul i64 %indvar2, 502
+ %tmp22 = add i64 %tmp21, 1
+ %storemerge214 = add i64 %indvar2, 1
+ %tmp30 = mul i64 %indvar2, -1
+ %tmp8 = add i64 %tmp30, 500
+ br i1 false, label %bb18, label %bb.nph13.bb.nph13.split_crit_edge
+
+return: ; preds = %bb18
+ ret void
+}
+; CHECK: for region: 'bb.nph36 => return' in function 'scop_func':
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef NI
+# define NI 512
+#endif
+#ifndef NJ
+# define NJ 512
+#endif
+#ifndef NK
+# define NK 512
+#endif
+#ifndef NL
+# define NL 512
+#endif
+
+
+/* Default data type is double (dgemm). */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE alpha1;
+DATA_TYPE beta1;
+DATA_TYPE alpha2;
+DATA_TYPE beta2;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE C[NI][NJ];
+DATA_TYPE A[NI][NK];
+DATA_TYPE B[NK][NJ];
+DATA_TYPE D[NJ][NL];
+DATA_TYPE E[NI][NL];
+#else
+DATA_TYPE** C = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+DATA_TYPE** A = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+DATA_TYPE** B = (DATA_TYPE**)malloc(NK * sizeof(DATA_TYPE*));
+DATA_TYPE** D = (DATA_TYPE**)malloc(NJ * sizeof(DATA_TYPE*));
+DATA_TYPE** E = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < NI; ++i)
+ {
+ C[i] = (DATA_TYPE*)malloc(NJ * sizeof(DATA_TYPE));
+ A[i] = (DATA_TYPE*)malloc(NK * sizeof(DATA_TYPE));
+ E[i] = (DATA_TYPE*)malloc(NL * sizeof(DATA_TYPE));
+ }
+ for (i = 0; i < NK; ++i)
+ B[i] = (DATA_TYPE*)malloc(NJ * sizeof(DATA_TYPE));
+ for (i = 0; i < NJ; ++i)
+ D[i] = (DATA_TYPE*)malloc(NL * sizeof(DATA_TYPE));
+}
+#endif
+
+
+inline
+void init_array()
+{
+ int i, j;
+
+ alpha1 = 32412;
+ beta1 = 2123;
+ alpha2 = 132412;
+ beta2 = 92123;
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NK; j++)
+ A[i][j] = ((DATA_TYPE) i*j)/NI;
+ for (i = 0; i < NK; i++)
+ for (j = 0; j < NJ; j++)
+ B[i][j] = ((DATA_TYPE) i*j + 1)/NJ;
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NJ; j++)
+ C[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+ for (i = 0; i < NJ; i++)
+ for (j = 0; j < NL; j++)
+ D[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NL; j++)
+ E[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < NI; i++) {
+ for (j = 0; j < NL; j++) {
+ fprintf(stderr, "%0.2lf ", E[i][j]);
+ if ((i * NI + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long ni = NI;
+ long nj = NJ;
+ long nk = NK;
+ long nl = NL;
+#else
+void scop_func(long ni, long nj, long nk, long nl) {
+#endif
+ long i, j, k;
+#pragma scop
+#pragma live-out E
+
+ /* E := A*B*C */
+ for (i = 0; i < ni; i++)
+ for (j = 0; j < nj; j++)
+ {
+ C[i][j] = 0;
+ for (k = 0; k < nk; ++k)
+ C[i][j] += A[i][k] * B[k][j];
+ }
+ for (i = 0; i < ni; i++)
+ for (j = 0; j < nl; j++)
+ {
+ E[i][j] = 0;
+ for (k = 0; k < nj; ++k)
+ E[i][j] += C[i][k] * D[k][j];
+ }
+
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, k;
+ int ni = NI;
+ int nj = NJ;
+ int nk = NK;
+ int nl = NL;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(ni, nj, nk, nl);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s| FileCheck %s
+; ModuleID = './linear-algebra/kernels/2mm/2mm_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha1 = common global double 0.000000e+00
+@beta1 = common global double 0.000000e+00
+@alpha2 = common global double 0.000000e+00
+@beta2 = common global double 0.000000e+00
+@A = common global [512 x [512 x double]] zeroinitializer, align 32
+@B = common global [512 x [512 x double]] zeroinitializer, align 32
+@C = common global [512 x [512 x double]] zeroinitializer, align 32
+@D = common global [512 x [512 x double]] zeroinitializer, align 32
+@E = common global [512 x [512 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func(i64 %ni, i64 %nj, i64 %nk, i64 %nl) nounwind {
+entry:
+ %0 = icmp sgt i64 %ni, 0
+ br i1 %0, label %bb.nph50, label %return
+
+bb.nph35: ; preds = %bb.nph35.preheader, %bb6
+ %indvar17 = phi i64 [ 0, %bb.nph35.preheader ], [ %indvar.next18, %bb6 ]
+ br i1 %8, label %bb.nph27.us.preheader, label %bb4.preheader
+
+bb.nph27.us.preheader: ; preds = %bb.nph35
+ br label %bb.nph27.us
+
+bb4.preheader: ; preds = %bb.nph35
+ br label %bb4
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa20 = phi double [ %5, %bb2.us ]
+ store double %.lcssa20, double* %scevgep64
+ %1 = add nsw i64 %storemerge431.us, 1
+ %exitcond24 = icmp eq i64 %1, %nj
+ br i1 %exitcond24, label %bb6.loopexit2, label %bb.nph27.us
+
+bb2.us: ; preds = %bb.nph27.us, %bb2.us
+ %.tmp.029.us = phi double [ 0.000000e+00, %bb.nph27.us ], [ %5, %bb2.us ]
+ %storemerge526.us = phi i64 [ 0, %bb.nph27.us ], [ %6, %bb2.us ]
+ %scevgep61 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %indvar17, i64 %storemerge526.us
+ %scevgep60 = getelementptr [512 x [512 x double]]* @B, i64 0, i64 %storemerge526.us, i64 %storemerge431.us
+ %2 = load double* %scevgep61, align 8
+ %3 = load double* %scevgep60, align 8
+ %4 = fmul double %2, %3
+ %5 = fadd double %.tmp.029.us, %4
+ %6 = add nsw i64 %storemerge526.us, 1
+ %exitcond21 = icmp eq i64 %6, %nk
+ br i1 %exitcond21, label %bb4.us, label %bb2.us
+
+bb.nph27.us: ; preds = %bb.nph27.us.preheader, %bb4.us
+ %storemerge431.us = phi i64 [ %1, %bb4.us ], [ 0, %bb.nph27.us.preheader ]
+ %scevgep64 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %indvar17, i64 %storemerge431.us
+ store double 0.000000e+00, double* %scevgep64, align 8
+ br label %bb2.us
+
+bb4: ; preds = %bb4.preheader, %bb4
+ %indvar67 = phi i64 [ %indvar.next68, %bb4 ], [ 0, %bb4.preheader ]
+ %scevgep72 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %indvar17, i64 %indvar67
+ store double 0.000000e+00, double* %scevgep72, align 8
+ %indvar.next68 = add i64 %indvar67, 1
+ %exitcond16 = icmp eq i64 %indvar.next68, %nj
+ br i1 %exitcond16, label %bb6.loopexit, label %bb4
+
+bb6.loopexit: ; preds = %bb4
+ br label %bb6
+
+bb6.loopexit2: ; preds = %bb4.us
+ br label %bb6
+
+bb6: ; preds = %bb6.loopexit2, %bb6.loopexit
+ %indvar.next18 = add i64 %indvar17, 1
+ %exitcond27 = icmp ne i64 %indvar.next18, %ni
+ br i1 %exitcond27, label %bb.nph35, label %bb16.preheader.loopexit
+
+bb.nph50: ; preds = %entry
+ %7 = icmp sgt i64 %nj, 0
+ %8 = icmp sgt i64 %nk, 0
+ br i1 %7, label %bb.nph35.preheader, label %bb16.preheader
+
+bb.nph35.preheader: ; preds = %bb.nph50
+ br label %bb.nph35
+
+bb16.preheader.loopexit: ; preds = %bb6
+ br label %bb16.preheader
+
+bb16.preheader: ; preds = %bb16.preheader.loopexit, %bb.nph50
+ br i1 %0, label %bb.nph25, label %return
+
+bb.nph11: ; preds = %bb.nph11.preheader, %bb15
+ %indvar4 = phi i64 [ 0, %bb.nph11.preheader ], [ %indvar.next5, %bb15 ]
+ br i1 %16, label %bb.nph.us.preheader, label %bb13.preheader
+
+bb.nph.us.preheader: ; preds = %bb.nph11
+ br label %bb.nph.us
+
+bb13.preheader: ; preds = %bb.nph11
+ br label %bb13
+
+bb13.us: ; preds = %bb11.us
+ %.lcssa = phi double [ %13, %bb11.us ]
+ store double %.lcssa, double* %scevgep54
+ %9 = add nsw i64 %storemerge27.us, 1
+ %exitcond = icmp eq i64 %9, %nl
+ br i1 %exitcond, label %bb15.loopexit1, label %bb.nph.us
+
+bb11.us: ; preds = %bb.nph.us, %bb11.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %13, %bb11.us ]
+ %storemerge36.us = phi i64 [ 0, %bb.nph.us ], [ %14, %bb11.us ]
+ %scevgep51 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %indvar4, i64 %storemerge36.us
+ %scevgep = getelementptr [512 x [512 x double]]* @D, i64 0, i64 %storemerge36.us, i64 %storemerge27.us
+ %10 = load double* %scevgep51, align 8
+ %11 = load double* %scevgep, align 8
+ %12 = fmul double %10, %11
+ %13 = fadd double %.tmp.0.us, %12
+ %14 = add nsw i64 %storemerge36.us, 1
+ %exitcond7 = icmp eq i64 %14, %nj
+ br i1 %exitcond7, label %bb13.us, label %bb11.us
+
+bb.nph.us: ; preds = %bb.nph.us.preheader, %bb13.us
+ %storemerge27.us = phi i64 [ %9, %bb13.us ], [ 0, %bb.nph.us.preheader ]
+ %scevgep54 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %indvar4, i64 %storemerge27.us
+ store double 0.000000e+00, double* %scevgep54, align 8
+ br label %bb11.us
+
+bb13: ; preds = %bb13.preheader, %bb13
+ %indvar = phi i64 [ %indvar.next, %bb13 ], [ 0, %bb13.preheader ]
+ %scevgep57 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %indvar4, i64 %indvar
+ store double 0.000000e+00, double* %scevgep57, align 8
+ %indvar.next = add i64 %indvar, 1
+ %exitcond3 = icmp eq i64 %indvar.next, %nl
+ br i1 %exitcond3, label %bb15.loopexit, label %bb13
+
+bb15.loopexit: ; preds = %bb13
+ br label %bb15
+
+bb15.loopexit1: ; preds = %bb13.us
+ br label %bb15
+
+bb15: ; preds = %bb15.loopexit1, %bb15.loopexit
+ %indvar.next5 = add i64 %indvar4, 1
+ %exitcond12 = icmp ne i64 %indvar.next5, %ni
+ br i1 %exitcond12, label %bb.nph11, label %return.loopexit
+
+bb.nph25: ; preds = %bb16.preheader
+ %15 = icmp sgt i64 %nl, 0
+ %16 = icmp sgt i64 %nj, 0
+ br i1 %15, label %bb.nph11.preheader, label %return
+
+bb.nph11.preheader: ; preds = %bb.nph25
+ br label %bb.nph11
+
+return.loopexit: ; preds = %bb15
+ br label %return
+
+return: ; preds = %return.loopexit, %bb.nph25, %bb16.preheader, %entry
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/2mm/2mm_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha1 = common global double 0.000000e+00
+@beta1 = common global double 0.000000e+00
+@alpha2 = common global double 0.000000e+00
+@beta2 = common global double 0.000000e+00
+@A = common global [512 x [512 x double]] zeroinitializer, align 32
+@B = common global [512 x [512 x double]] zeroinitializer, align 32
+@C = common global [512 x [512 x double]] zeroinitializer, align 32
+@D = common global [512 x [512 x double]] zeroinitializer, align 32
+@E = common global [512 x [512 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func() nounwind {
+bb.nph50.bb.nph50.split_crit_edge:
+ br label %bb5.preheader
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa9 = phi double [ %4, %bb2.us ]
+ store double %.lcssa9, double* %scevgep61
+ %0 = add nsw i64 %storemerge431.us, 1
+ %exitcond13 = icmp eq i64 %0, 512
+ br i1 %exitcond13, label %bb6, label %bb.nph27.us
+
+bb2.us: ; preds = %bb.nph27.us, %bb2.us
+ %.tmp.029.us = phi double [ 0.000000e+00, %bb.nph27.us ], [ %4, %bb2.us ]
+ %storemerge526.us = phi i64 [ 0, %bb.nph27.us ], [ %5, %bb2.us ]
+ %scevgep58 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %storemerge37, i64 %storemerge526.us
+ %scevgep57 = getelementptr [512 x [512 x double]]* @B, i64 0, i64 %storemerge526.us, i64 %storemerge431.us
+ %1 = load double* %scevgep58, align 8
+ %2 = load double* %scevgep57, align 8
+ %3 = fmul double %1, %2
+ %4 = fadd double %.tmp.029.us, %3
+ %5 = add nsw i64 %storemerge526.us, 1
+ %exitcond10 = icmp eq i64 %5, 512
+ br i1 %exitcond10, label %bb4.us, label %bb2.us
+
+bb.nph27.us: ; preds = %bb5.preheader, %bb4.us
+ %storemerge431.us = phi i64 [ %0, %bb4.us ], [ 0, %bb5.preheader ]
+ %scevgep61 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %storemerge37, i64 %storemerge431.us
+ store double 0.000000e+00, double* %scevgep61, align 8
+ br label %bb2.us
+
+bb6: ; preds = %bb4.us
+ %6 = add nsw i64 %storemerge37, 1
+ %exitcond16 = icmp ne i64 %6, 512
+ br i1 %exitcond16, label %bb5.preheader, label %bb14.preheader.preheader
+
+bb14.preheader.preheader: ; preds = %bb6
+ br label %bb14.preheader
+
+bb5.preheader: ; preds = %bb6, %bb.nph50.bb.nph50.split_crit_edge
+ %storemerge37 = phi i64 [ 0, %bb.nph50.bb.nph50.split_crit_edge ], [ %6, %bb6 ]
+ br label %bb.nph27.us
+
+bb13.us: ; preds = %bb11.us
+ %.lcssa = phi double [ %11, %bb11.us ]
+ store double %.lcssa, double* %scevgep54
+ %7 = add nsw i64 %storemerge27.us, 1
+ %exitcond = icmp eq i64 %7, 512
+ br i1 %exitcond, label %bb15, label %bb.nph.us
+
+bb11.us: ; preds = %bb.nph.us, %bb11.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %11, %bb11.us ]
+ %storemerge36.us = phi i64 [ 0, %bb.nph.us ], [ %12, %bb11.us ]
+ %scevgep51 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %storemerge112, i64 %storemerge36.us
+ %scevgep = getelementptr [512 x [512 x double]]* @D, i64 0, i64 %storemerge36.us, i64 %storemerge27.us
+ %8 = load double* %scevgep51, align 8
+ %9 = load double* %scevgep, align 8
+ %10 = fmul double %8, %9
+ %11 = fadd double %.tmp.0.us, %10
+ %12 = add nsw i64 %storemerge36.us, 1
+ %exitcond1 = icmp eq i64 %12, 512
+ br i1 %exitcond1, label %bb13.us, label %bb11.us
+
+bb.nph.us: ; preds = %bb14.preheader, %bb13.us
+ %storemerge27.us = phi i64 [ %7, %bb13.us ], [ 0, %bb14.preheader ]
+ %scevgep54 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %storemerge112, i64 %storemerge27.us
+ store double 0.000000e+00, double* %scevgep54, align 8
+ br label %bb11.us
+
+bb15: ; preds = %bb13.us
+ %13 = add nsw i64 %storemerge112, 1
+ %exitcond6 = icmp ne i64 %13, 512
+ br i1 %exitcond6, label %bb14.preheader, label %return
+
+bb14.preheader: ; preds = %bb14.preheader.preheader, %bb15
+ %storemerge112 = phi i64 [ %13, %bb15 ], [ 0, %bb14.preheader.preheader ]
+ br label %bb.nph.us
+
+return: ; preds = %bb15
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
--- /dev/null
+-DNI=1024 -DNJ=1024 -DNK=1024 -DNL=1024
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef NI
+# define NI 512
+#endif
+#ifndef NJ
+# define NJ 512
+#endif
+#ifndef NK
+# define NK 512
+#endif
+#ifndef NL
+# define NL 512
+#endif
+#ifndef NM
+# define NM 512
+#endif
+
+
+/* Default data type is double (dgemm). */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[NI][NK];
+DATA_TYPE B[NK][NJ];
+DATA_TYPE C[NJ][NM];
+DATA_TYPE D[NM][NL];
+DATA_TYPE E[NI][NJ];
+DATA_TYPE F[NJ][NL];
+DATA_TYPE G[NI][NL];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+DATA_TYPE** B = (DATA_TYPE**)malloc(NK * sizeof(DATA_TYPE*));
+DATA_TYPE** C = (DATA_TYPE**)malloc(NJ * sizeof(DATA_TYPE*));
+DATA_TYPE** D = (DATA_TYPE**)malloc(NM * sizeof(DATA_TYPE*));
+DATA_TYPE** E = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+DATA_TYPE** F = (DATA_TYPE**)malloc(NJ * sizeof(DATA_TYPE*));
+DATA_TYPE** G = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < NI; ++i)
+ {
+ A[i] = (DATA_TYPE*)malloc(NK * sizeof(DATA_TYPE));
+ E[i] = (DATA_TYPE*)malloc(NJ * sizeof(DATA_TYPE));
+ G[i] = (DATA_TYPE*)malloc(NL * sizeof(DATA_TYPE));
+ }
+ for (i = 0; i < NK; ++i)
+ B[i] = (DATA_TYPE*)malloc(NJ * sizeof(DATA_TYPE));
+ for (i = 0; i < NJ; ++i)
+ {
+ C[i] = (DATA_TYPE*)malloc(NM * sizeof(DATA_TYPE));
+ F[i] = (DATA_TYPE*)malloc(NL * sizeof(DATA_TYPE));
+ }
+ for (i = 0; i < NM; ++i)
+ D[i] = (DATA_TYPE*)malloc(NL * sizeof(DATA_TYPE));
+}
+#endif
+
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NK; j++)
+ A[i][j] = ((DATA_TYPE) i*j)/NI;
+ for (i = 0; i < NK; i++)
+ for (j = 0; j < NJ; j++)
+ B[i][j] = ((DATA_TYPE) i*j + 1)/NJ;
+ for (i = 0; i < NJ; i++)
+ for (j = 0; j < NM; j++)
+ C[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+ for (i = 0; i < NM; i++)
+ for (j = 0; j < NL; j++)
+ D[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NJ; j++)
+ E[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+ for (i = 0; i < NJ; i++)
+ for (j = 0; j < NL; j++)
+ F[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NL; j++)
+ G[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < NI; i++) {
+ for (j = 0; j < NL; j++) {
+ fprintf(stderr, "%0.2lf ", G[i][j]);
+ if ((i * NI + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long ni = NI;
+ long nj = NJ;
+ long nk = NK;
+ long nl = NL;
+ long nm = NM;
+#else
+void scop_func(long ni, long nj, long nk, long nl, long nm) {
+#endif
+ long i, j, k;
+
+#pragma scop
+#pragma live-out G
+
+ /* /\* E := A*B *\/ */
+ /* for (i = 0; i < ni; i++) */
+ /* for (j = 0; j < nj; j++) */
+ /* { */
+ /* E[i][j] = 0; */
+ /* for (k = 0; k < nk; ++k) */
+ /* E[i][j] += A[i][k] * B[k][j]; */
+ /* } */
+
+ /* /\* F := C*D *\/ */
+ /* for (i = 0; i < nj; i++) */
+ /* for (j = 0; j < nl; j++) */
+ /* { */
+ /* F[i][j] = 0; */
+ /* for (k = 0; k < nm; ++k) */
+ /* F[i][j] += C[i][k] * D[k][j]; */
+ /* } */
+ /* /\* G := E*F *\/ */
+ /* for (i = 0; i < ni; i++) */
+ /* for (j = 0; j < nl; j++) */
+ /* { */
+ /* G[i][j] = 0; */
+ /* for (k = 0; k < nj; ++k) */
+ /* G[i][j] += E[i][k] * F[k][j]; */
+ /* } */
+
+ /// FIXME: Remove some parameters, CLooG-ISL crashes...
+
+ /* E := A*B */
+ for (i = 0; i < ni; i++)
+ for (j = 0; j < ni; j++)
+ {
+ E[i][j] = 0;
+ for (k = 0; k < nk; ++k)
+ E[i][j] += A[i][k] * B[k][j];
+ }
+
+ /* F := C*D */
+ for (i = 0; i < ni; i++)
+ for (j = 0; j < ni; j++)
+ {
+ F[i][j] = 0;
+ for (k = 0; k < nk; ++k)
+ F[i][j] += C[i][k] * D[k][j];
+ }
+ /* G := E*F */
+ for (i = 0; i < ni; i++)
+ for (j = 0; j < ni; j++)
+ {
+ G[i][j] = 0;
+ for (k = 0; k < nk; ++k)
+ G[i][j] += E[i][k] * F[k][j];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, k;
+ int ni = NI;
+ int nj = NJ;
+ int nk = NK;
+ int nl = NL;
+ int nm = NM;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(ni, nj, nk, nl, nm);
+#endif
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s| FileCheck %s
+; ModuleID = './linear-algebra/kernels/3mm/3mm_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [512 x [512 x double]] zeroinitializer, align 32
+@B = common global [512 x [512 x double]] zeroinitializer, align 32
+@C = common global [512 x [512 x double]] zeroinitializer, align 32
+@D = common global [512 x [512 x double]] zeroinitializer, align 32
+@E = common global [512 x [512 x double]] zeroinitializer, align 32
+@F = common global [512 x [512 x double]] zeroinitializer, align 32
+@G = common global [512 x [512 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func(i64 %ni, i64 %nj, i64 %nk, i64 %nl, i64 %nm) nounwind {
+entry:
+ %0 = icmp sgt i64 %ni, 0
+ br i1 %0, label %bb.nph76.bb.nph76.split_crit_edge, label %return
+
+bb.nph62: ; preds = %bb.nph76.bb.nph76.split_crit_edge, %bb6
+ %indvar33 = phi i64 [ 0, %bb.nph76.bb.nph76.split_crit_edge ], [ %indvar.next34, %bb6 ]
+ br i1 %7, label %bb.nph54.us.preheader, label %bb4.preheader
+
+bb.nph54.us.preheader: ; preds = %bb.nph62
+ br label %bb.nph54.us
+
+bb4.preheader: ; preds = %bb.nph62
+ br label %bb4
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa36 = phi double [ %5, %bb2.us ]
+ store double %.lcssa36, double* %scevgep105
+ %1 = add nsw i64 %storemerge758.us, 1
+ %exitcond40 = icmp eq i64 %1, %ni
+ br i1 %exitcond40, label %bb6.loopexit3, label %bb.nph54.us
+
+bb2.us: ; preds = %bb.nph54.us, %bb2.us
+ %.tmp.056.us = phi double [ 0.000000e+00, %bb.nph54.us ], [ %5, %bb2.us ]
+ %storemerge853.us = phi i64 [ 0, %bb.nph54.us ], [ %6, %bb2.us ]
+ %scevgep102 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %indvar33, i64 %storemerge853.us
+ %scevgep101 = getelementptr [512 x [512 x double]]* @B, i64 0, i64 %storemerge853.us, i64 %storemerge758.us
+ %2 = load double* %scevgep102, align 8
+ %3 = load double* %scevgep101, align 8
+ %4 = fmul double %2, %3
+ %5 = fadd double %.tmp.056.us, %4
+ %6 = add nsw i64 %storemerge853.us, 1
+ %exitcond37 = icmp eq i64 %6, %nk
+ br i1 %exitcond37, label %bb4.us, label %bb2.us
+
+bb.nph54.us: ; preds = %bb.nph54.us.preheader, %bb4.us
+ %storemerge758.us = phi i64 [ %1, %bb4.us ], [ 0, %bb.nph54.us.preheader ]
+ %scevgep105 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %indvar33, i64 %storemerge758.us
+ store double 0.000000e+00, double* %scevgep105, align 8
+ br label %bb2.us
+
+bb4: ; preds = %bb4.preheader, %bb4
+ %indvar108 = phi i64 [ %indvar.next109, %bb4 ], [ 0, %bb4.preheader ]
+ %scevgep113 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %indvar33, i64 %indvar108
+ store double 0.000000e+00, double* %scevgep113, align 8
+ %indvar.next109 = add i64 %indvar108, 1
+ %exitcond32 = icmp eq i64 %indvar.next109, %ni
+ br i1 %exitcond32, label %bb6.loopexit, label %bb4
+
+bb6.loopexit: ; preds = %bb4
+ br label %bb6
+
+bb6.loopexit3: ; preds = %bb4.us
+ br label %bb6
+
+bb6: ; preds = %bb6.loopexit3, %bb6.loopexit
+ %indvar.next34 = add i64 %indvar33, 1
+ %exitcond43 = icmp ne i64 %indvar.next34, %ni
+ br i1 %exitcond43, label %bb.nph62, label %bb16.preheader
+
+bb.nph76.bb.nph76.split_crit_edge: ; preds = %entry
+ %7 = icmp sgt i64 %nk, 0
+ br label %bb.nph62
+
+bb16.preheader: ; preds = %bb6
+ br i1 %0, label %bb.nph52.bb.nph52.split_crit_edge, label %return
+
+bb.nph38: ; preds = %bb.nph52.bb.nph52.split_crit_edge, %bb15
+ %indvar18 = phi i64 [ 0, %bb.nph52.bb.nph52.split_crit_edge ], [ %indvar.next19, %bb15 ]
+ br i1 %14, label %bb.nph30.us.preheader, label %bb13.preheader
+
+bb.nph30.us.preheader: ; preds = %bb.nph38
+ br label %bb.nph30.us
+
+bb13.preheader: ; preds = %bb.nph38
+ br label %bb13
+
+bb13.us: ; preds = %bb11.us
+ %.lcssa21 = phi double [ %12, %bb11.us ]
+ store double %.lcssa21, double* %scevgep90
+ %8 = add nsw i64 %storemerge534.us, 1
+ %exitcond25 = icmp eq i64 %8, %ni
+ br i1 %exitcond25, label %bb15.loopexit2, label %bb.nph30.us
+
+bb11.us: ; preds = %bb.nph30.us, %bb11.us
+ %.tmp.032.us = phi double [ 0.000000e+00, %bb.nph30.us ], [ %12, %bb11.us ]
+ %storemerge629.us = phi i64 [ 0, %bb.nph30.us ], [ %13, %bb11.us ]
+ %scevgep87 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %indvar18, i64 %storemerge629.us
+ %scevgep86 = getelementptr [512 x [512 x double]]* @D, i64 0, i64 %storemerge629.us, i64 %storemerge534.us
+ %9 = load double* %scevgep87, align 8
+ %10 = load double* %scevgep86, align 8
+ %11 = fmul double %9, %10
+ %12 = fadd double %.tmp.032.us, %11
+ %13 = add nsw i64 %storemerge629.us, 1
+ %exitcond22 = icmp eq i64 %13, %nk
+ br i1 %exitcond22, label %bb13.us, label %bb11.us
+
+bb.nph30.us: ; preds = %bb.nph30.us.preheader, %bb13.us
+ %storemerge534.us = phi i64 [ %8, %bb13.us ], [ 0, %bb.nph30.us.preheader ]
+ %scevgep90 = getelementptr [512 x [512 x double]]* @F, i64 0, i64 %indvar18, i64 %storemerge534.us
+ store double 0.000000e+00, double* %scevgep90, align 8
+ br label %bb11.us
+
+bb13: ; preds = %bb13.preheader, %bb13
+ %indvar93 = phi i64 [ %indvar.next94, %bb13 ], [ 0, %bb13.preheader ]
+ %scevgep98 = getelementptr [512 x [512 x double]]* @F, i64 0, i64 %indvar18, i64 %indvar93
+ store double 0.000000e+00, double* %scevgep98, align 8
+ %indvar.next94 = add i64 %indvar93, 1
+ %exitcond17 = icmp eq i64 %indvar.next94, %ni
+ br i1 %exitcond17, label %bb15.loopexit, label %bb13
+
+bb15.loopexit: ; preds = %bb13
+ br label %bb15
+
+bb15.loopexit2: ; preds = %bb13.us
+ br label %bb15
+
+bb15: ; preds = %bb15.loopexit2, %bb15.loopexit
+ %indvar.next19 = add i64 %indvar18, 1
+ %exitcond28 = icmp ne i64 %indvar.next19, %ni
+ br i1 %exitcond28, label %bb.nph38, label %bb25.preheader
+
+bb.nph52.bb.nph52.split_crit_edge: ; preds = %bb16.preheader
+ %14 = icmp sgt i64 %nk, 0
+ br label %bb.nph38
+
+bb25.preheader: ; preds = %bb15
+ br i1 %0, label %bb.nph28.bb.nph28.split_crit_edge, label %return
+
+bb.nph14: ; preds = %bb.nph28.bb.nph28.split_crit_edge, %bb24
+ %indvar5 = phi i64 [ 0, %bb.nph28.bb.nph28.split_crit_edge ], [ %indvar.next6, %bb24 ]
+ br i1 %21, label %bb.nph.us.preheader, label %bb22.preheader
+
+bb.nph.us.preheader: ; preds = %bb.nph14
+ br label %bb.nph.us
+
+bb22.preheader: ; preds = %bb.nph14
+ br label %bb22
+
+bb22.us: ; preds = %bb20.us
+ %.lcssa = phi double [ %19, %bb20.us ]
+ store double %.lcssa, double* %scevgep80
+ %15 = add nsw i64 %storemerge310.us, 1
+ %exitcond = icmp eq i64 %15, %ni
+ br i1 %exitcond, label %bb24.loopexit1, label %bb.nph.us
+
+bb20.us: ; preds = %bb.nph.us, %bb20.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %19, %bb20.us ]
+ %storemerge49.us = phi i64 [ 0, %bb.nph.us ], [ %20, %bb20.us ]
+ %scevgep77 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %indvar5, i64 %storemerge49.us
+ %scevgep = getelementptr [512 x [512 x double]]* @F, i64 0, i64 %storemerge49.us, i64 %storemerge310.us
+ %16 = load double* %scevgep77, align 8
+ %17 = load double* %scevgep, align 8
+ %18 = fmul double %16, %17
+ %19 = fadd double %.tmp.0.us, %18
+ %20 = add nsw i64 %storemerge49.us, 1
+ %exitcond8 = icmp eq i64 %20, %nk
+ br i1 %exitcond8, label %bb22.us, label %bb20.us
+
+bb.nph.us: ; preds = %bb.nph.us.preheader, %bb22.us
+ %storemerge310.us = phi i64 [ %15, %bb22.us ], [ 0, %bb.nph.us.preheader ]
+ %scevgep80 = getelementptr [512 x [512 x double]]* @G, i64 0, i64 %indvar5, i64 %storemerge310.us
+ store double 0.000000e+00, double* %scevgep80, align 8
+ br label %bb20.us
+
+bb22: ; preds = %bb22.preheader, %bb22
+ %indvar = phi i64 [ %indvar.next, %bb22 ], [ 0, %bb22.preheader ]
+ %scevgep83 = getelementptr [512 x [512 x double]]* @G, i64 0, i64 %indvar5, i64 %indvar
+ store double 0.000000e+00, double* %scevgep83, align 8
+ %indvar.next = add i64 %indvar, 1
+ %exitcond4 = icmp eq i64 %indvar.next, %ni
+ br i1 %exitcond4, label %bb24.loopexit, label %bb22
+
+bb24.loopexit: ; preds = %bb22
+ br label %bb24
+
+bb24.loopexit1: ; preds = %bb22.us
+ br label %bb24
+
+bb24: ; preds = %bb24.loopexit1, %bb24.loopexit
+ %indvar.next6 = add i64 %indvar5, 1
+ %exitcond13 = icmp ne i64 %indvar.next6, %ni
+ br i1 %exitcond13, label %bb.nph14, label %return.loopexit
+
+bb.nph28.bb.nph28.split_crit_edge: ; preds = %bb25.preheader
+ %21 = icmp sgt i64 %nk, 0
+ br label %bb.nph14
+
+return.loopexit: ; preds = %bb24
+ br label %return
+
+return: ; preds = %return.loopexit, %bb25.preheader, %bb16.preheader, %entry
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/3mm/3mm_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [512 x [512 x double]] zeroinitializer, align 32
+@B = common global [512 x [512 x double]] zeroinitializer, align 32
+@C = common global [512 x [512 x double]] zeroinitializer, align 32
+@D = common global [512 x [512 x double]] zeroinitializer, align 32
+@E = common global [512 x [512 x double]] zeroinitializer, align 32
+@F = common global [512 x [512 x double]] zeroinitializer, align 32
+@G = common global [512 x [512 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func() nounwind {
+bb.nph76.bb.nph76.split_crit_edge:
+ br label %bb5.preheader
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa19 = phi double [ %4, %bb2.us ]
+ store double %.lcssa19, double* %scevgep94
+ %0 = add nsw i64 %storemerge758.us, 1
+ %exitcond23 = icmp eq i64 %0, 512
+ br i1 %exitcond23, label %bb6, label %bb.nph54.us
+
+bb2.us: ; preds = %bb.nph54.us, %bb2.us
+ %.tmp.056.us = phi double [ 0.000000e+00, %bb.nph54.us ], [ %4, %bb2.us ]
+ %storemerge853.us = phi i64 [ 0, %bb.nph54.us ], [ %5, %bb2.us ]
+ %scevgep91 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %storemerge63, i64 %storemerge853.us
+ %scevgep90 = getelementptr [512 x [512 x double]]* @B, i64 0, i64 %storemerge853.us, i64 %storemerge758.us
+ %1 = load double* %scevgep91, align 8
+ %2 = load double* %scevgep90, align 8
+ %3 = fmul double %1, %2
+ %4 = fadd double %.tmp.056.us, %3
+ %5 = add nsw i64 %storemerge853.us, 1
+ %exitcond20 = icmp eq i64 %5, 512
+ br i1 %exitcond20, label %bb4.us, label %bb2.us
+
+bb.nph54.us: ; preds = %bb5.preheader, %bb4.us
+ %storemerge758.us = phi i64 [ %0, %bb4.us ], [ 0, %bb5.preheader ]
+ %scevgep94 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %storemerge63, i64 %storemerge758.us
+ store double 0.000000e+00, double* %scevgep94, align 8
+ br label %bb2.us
+
+bb6: ; preds = %bb4.us
+ %6 = add nsw i64 %storemerge63, 1
+ %exitcond26 = icmp ne i64 %6, 512
+ br i1 %exitcond26, label %bb5.preheader, label %bb14.preheader.preheader
+
+bb14.preheader.preheader: ; preds = %bb6
+ br label %bb14.preheader
+
+bb5.preheader: ; preds = %bb6, %bb.nph76.bb.nph76.split_crit_edge
+ %storemerge63 = phi i64 [ 0, %bb.nph76.bb.nph76.split_crit_edge ], [ %6, %bb6 ]
+ br label %bb.nph54.us
+
+bb13.us: ; preds = %bb11.us
+ %.lcssa9 = phi double [ %11, %bb11.us ]
+ store double %.lcssa9, double* %scevgep87
+ %7 = add nsw i64 %storemerge534.us, 1
+ %exitcond13 = icmp eq i64 %7, 512
+ br i1 %exitcond13, label %bb15, label %bb.nph30.us
+
+bb11.us: ; preds = %bb.nph30.us, %bb11.us
+ %.tmp.032.us = phi double [ 0.000000e+00, %bb.nph30.us ], [ %11, %bb11.us ]
+ %storemerge629.us = phi i64 [ 0, %bb.nph30.us ], [ %12, %bb11.us ]
+ %scevgep84 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %storemerge139, i64 %storemerge629.us
+ %scevgep83 = getelementptr [512 x [512 x double]]* @D, i64 0, i64 %storemerge629.us, i64 %storemerge534.us
+ %8 = load double* %scevgep84, align 8
+ %9 = load double* %scevgep83, align 8
+ %10 = fmul double %8, %9
+ %11 = fadd double %.tmp.032.us, %10
+ %12 = add nsw i64 %storemerge629.us, 1
+ %exitcond10 = icmp eq i64 %12, 512
+ br i1 %exitcond10, label %bb13.us, label %bb11.us
+
+bb.nph30.us: ; preds = %bb14.preheader, %bb13.us
+ %storemerge534.us = phi i64 [ %7, %bb13.us ], [ 0, %bb14.preheader ]
+ %scevgep87 = getelementptr [512 x [512 x double]]* @F, i64 0, i64 %storemerge139, i64 %storemerge534.us
+ store double 0.000000e+00, double* %scevgep87, align 8
+ br label %bb11.us
+
+bb15: ; preds = %bb13.us
+ %13 = add nsw i64 %storemerge139, 1
+ %exitcond16 = icmp ne i64 %13, 512
+ br i1 %exitcond16, label %bb14.preheader, label %bb23.preheader.preheader
+
+bb23.preheader.preheader: ; preds = %bb15
+ br label %bb23.preheader
+
+bb14.preheader: ; preds = %bb14.preheader.preheader, %bb15
+ %storemerge139 = phi i64 [ %13, %bb15 ], [ 0, %bb14.preheader.preheader ]
+ br label %bb.nph30.us
+
+bb22.us: ; preds = %bb20.us
+ %.lcssa = phi double [ %18, %bb20.us ]
+ store double %.lcssa, double* %scevgep80
+ %14 = add nsw i64 %storemerge310.us, 1
+ %exitcond = icmp eq i64 %14, 512
+ br i1 %exitcond, label %bb24, label %bb.nph.us
+
+bb20.us: ; preds = %bb.nph.us, %bb20.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %18, %bb20.us ]
+ %storemerge49.us = phi i64 [ 0, %bb.nph.us ], [ %19, %bb20.us ]
+ %scevgep77 = getelementptr [512 x [512 x double]]* @E, i64 0, i64 %storemerge215, i64 %storemerge49.us
+ %scevgep = getelementptr [512 x [512 x double]]* @F, i64 0, i64 %storemerge49.us, i64 %storemerge310.us
+ %15 = load double* %scevgep77, align 8
+ %16 = load double* %scevgep, align 8
+ %17 = fmul double %15, %16
+ %18 = fadd double %.tmp.0.us, %17
+ %19 = add nsw i64 %storemerge49.us, 1
+ %exitcond1 = icmp eq i64 %19, 512
+ br i1 %exitcond1, label %bb22.us, label %bb20.us
+
+bb.nph.us: ; preds = %bb23.preheader, %bb22.us
+ %storemerge310.us = phi i64 [ %14, %bb22.us ], [ 0, %bb23.preheader ]
+ %scevgep80 = getelementptr [512 x [512 x double]]* @G, i64 0, i64 %storemerge215, i64 %storemerge310.us
+ store double 0.000000e+00, double* %scevgep80, align 8
+ br label %bb20.us
+
+bb24: ; preds = %bb22.us
+ %20 = add nsw i64 %storemerge215, 1
+ %exitcond6 = icmp ne i64 %20, 512
+ br i1 %exitcond6, label %bb23.preheader, label %return
+
+bb23.preheader: ; preds = %bb23.preheader.preheader, %bb24
+ %storemerge215 = phi i64 [ %20, %bb24 ], [ 0, %bb23.preheader.preheader ]
+ br label %bb.nph.us
+
+return: ; preds = %bb24
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
--- /dev/null
+-DNI=1024 -DNJ=1024 -DNK=1024 -DNL=1024 -DNM=1024
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+/* Default problem size. */
+#ifndef NX
+# define NX 8000
+#endif
+#ifndef NY
+# define NY 8000
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[NX][NY];
+DATA_TYPE x[NY];
+DATA_TYPE y[NY];
+DATA_TYPE tmp[NX];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(NX * sizeof(DATA_TYPE*));
+DATA_TYPE* x = (DATA_TYPE*)malloc(NY * sizeof(DATA_TYPE));
+DATA_TYPE* y = (DATA_TYPE*)malloc(NY * sizeof(DATA_TYPE));
+DATA_TYPE* tmp = (DATA_TYPE*)malloc(NX * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i < NX; ++i)
+ A[i] = (DATA_TYPE*)malloc(NY * sizeof(DATA_TYPE));
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < NX; i++)
+ {
+ x[i] = i * M_PI;
+ for (j = 0; j < NY; j++)
+ A[i][j] = ((DATA_TYPE) i*j) / NX;
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < NX; i++) {
+ fprintf(stderr, "%0.2lf ", y[i]);
+ if (i%80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long nx = NX;
+ long ny = NY;
+#else
+void scop_func(long nx, long ny) {
+#endif
+ long i, j;
+
+#pragma scop
+#pragma live-out y
+ for (i= 0; i < nx; i++)
+ y[i] = 0;
+ for (i = 0; i < ny; i++)
+ {
+ tmp[i] = 0;
+ for (j = 0; j < ny; j++)
+ tmp[i] = tmp[i] + A[i][j] * x[j];
+ for (j = 0; j < ny; j++)
+ y[j] = y[j] + A[i][j] * tmp[i];
+ }
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j;
+ int nx = NX;
+ int ny = NY;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(nx, ny);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/atax/atax_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@x = common global [8000 x double] zeroinitializer, align 32
+@A = common global [8000 x [8000 x double]] zeroinitializer, align 32
+@y = common global [8000 x double] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@tmp = common global [8000 x double] zeroinitializer, align 32
+
+define void @scop_func(i64 %nx, i64 %ny) nounwind {
+entry:
+ %0 = icmp sgt i64 %nx, 0
+ br i1 %0, label %bb.preheader, label %bb10.preheader
+
+bb.preheader: ; preds = %entry
+ br label %bb
+
+bb: ; preds = %bb.preheader, %bb
+ %storemerge15 = phi i64 [ %1, %bb ], [ 0, %bb.preheader ]
+ %scevgep26 = getelementptr [8000 x double]* @y, i64 0, i64 %storemerge15
+ store double 0.000000e+00, double* %scevgep26, align 8
+ %1 = add nsw i64 %storemerge15, 1
+ %exitcond10 = icmp eq i64 %1, %nx
+ br i1 %exitcond10, label %bb10.preheader.loopexit, label %bb
+
+bb10.preheader.loopexit: ; preds = %bb
+ br label %bb10.preheader
+
+bb10.preheader: ; preds = %bb10.preheader.loopexit, %entry
+ %2 = icmp sgt i64 %ny, 0
+ br i1 %2, label %bb.nph.preheader, label %return
+
+bb.nph.preheader: ; preds = %bb10.preheader
+ br label %bb.nph
+
+bb.nph: ; preds = %bb.nph.preheader, %bb9
+ %storemerge17 = phi i64 [ %13, %bb9 ], [ 0, %bb.nph.preheader ]
+ %scevgep24 = getelementptr [8000 x double]* @tmp, i64 0, i64 %storemerge17
+ store double 0.000000e+00, double* %scevgep24, align 8
+ br label %bb4
+
+bb4: ; preds = %bb4, %bb.nph
+ %.tmp.0 = phi double [ 0.000000e+00, %bb.nph ], [ %6, %bb4 ]
+ %storemerge24 = phi i64 [ 0, %bb.nph ], [ %7, %bb4 ]
+ %scevgep17 = getelementptr [8000 x [8000 x double]]* @A, i64 0, i64 %storemerge17, i64 %storemerge24
+ %scevgep = getelementptr [8000 x double]* @x, i64 0, i64 %storemerge24
+ %3 = load double* %scevgep17, align 8
+ %4 = load double* %scevgep, align 8
+ %5 = fmul double %3, %4
+ %6 = fadd double %.tmp.0, %5
+ %7 = add nsw i64 %storemerge24, 1
+ %exitcond1 = icmp eq i64 %7, %ny
+ br i1 %exitcond1, label %bb8.loopexit, label %bb4
+
+bb7: ; preds = %bb8.loopexit, %bb7
+ %storemerge35 = phi i64 [ %12, %bb7 ], [ 0, %bb8.loopexit ]
+ %scevgep19 = getelementptr [8000 x [8000 x double]]* @A, i64 0, i64 %storemerge17, i64 %storemerge35
+ %scevgep20 = getelementptr [8000 x double]* @y, i64 0, i64 %storemerge35
+ %8 = load double* %scevgep20, align 8
+ %9 = load double* %scevgep19, align 8
+ %10 = fmul double %9, %.lcssa
+ %11 = fadd double %8, %10
+ store double %11, double* %scevgep20, align 8
+ %12 = add nsw i64 %storemerge35, 1
+ %exitcond = icmp eq i64 %12, %ny
+ br i1 %exitcond, label %bb9, label %bb7
+
+bb8.loopexit: ; preds = %bb4
+ %.lcssa = phi double [ %6, %bb4 ]
+ store double %.lcssa, double* %scevgep24
+ br label %bb7
+
+bb9: ; preds = %bb7
+ %13 = add nsw i64 %storemerge17, 1
+ %exitcond6 = icmp eq i64 %13, %ny
+ br i1 %exitcond6, label %return.loopexit, label %bb.nph
+
+return.loopexit: ; preds = %bb9
+ br label %return
+
+return: ; preds = %return.loopexit, %bb10.preheader
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
+; CHECK-NEXT: scop_func():
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/atax/atax_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@x = common global [8000 x double] zeroinitializer, align 32
+@A = common global [8000 x [8000 x double]] zeroinitializer, align 32
+@y = common global [8000 x double] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@tmp = common global [8000 x double] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph16:
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph16
+ %storemerge15 = phi i64 [ 0, %bb.nph16 ], [ %0, %bb ]
+ %scevgep26 = getelementptr [8000 x double]* @y, i64 0, i64 %storemerge15
+ store double 0.000000e+00, double* %scevgep26, align 8
+ %0 = add nsw i64 %storemerge15, 1
+ %exitcond10 = icmp eq i64 %0, 8000
+ br i1 %exitcond10, label %bb.nph.preheader, label %bb
+
+bb.nph.preheader: ; preds = %bb
+ br label %bb.nph
+
+bb.nph: ; preds = %bb.nph.preheader, %bb9
+ %storemerge17 = phi i64 [ %11, %bb9 ], [ 0, %bb.nph.preheader ]
+ %scevgep24 = getelementptr [8000 x double]* @tmp, i64 0, i64 %storemerge17
+ store double 0.000000e+00, double* %scevgep24, align 8
+ br label %bb4
+
+bb4: ; preds = %bb4, %bb.nph
+ %.tmp.0 = phi double [ 0.000000e+00, %bb.nph ], [ %4, %bb4 ]
+ %storemerge24 = phi i64 [ 0, %bb.nph ], [ %5, %bb4 ]
+ %scevgep17 = getelementptr [8000 x [8000 x double]]* @A, i64 0, i64 %storemerge17, i64 %storemerge24
+ %scevgep = getelementptr [8000 x double]* @x, i64 0, i64 %storemerge24
+ %1 = load double* %scevgep17, align 8
+ %2 = load double* %scevgep, align 8
+ %3 = fmul double %1, %2
+ %4 = fadd double %.tmp.0, %3
+ %5 = add nsw i64 %storemerge24, 1
+ %exitcond1 = icmp eq i64 %5, 8000
+ br i1 %exitcond1, label %bb8.loopexit, label %bb4
+
+bb7: ; preds = %bb8.loopexit, %bb7
+ %storemerge35 = phi i64 [ %10, %bb7 ], [ 0, %bb8.loopexit ]
+ %scevgep19 = getelementptr [8000 x [8000 x double]]* @A, i64 0, i64 %storemerge17, i64 %storemerge35
+ %scevgep20 = getelementptr [8000 x double]* @y, i64 0, i64 %storemerge35
+ %6 = load double* %scevgep20, align 8
+ %7 = load double* %scevgep19, align 8
+ %8 = fmul double %7, %.lcssa
+ %9 = fadd double %6, %8
+ store double %9, double* %scevgep20, align 8
+ %10 = add nsw i64 %storemerge35, 1
+ %exitcond = icmp eq i64 %10, 8000
+ br i1 %exitcond, label %bb9, label %bb7
+
+bb8.loopexit: ; preds = %bb4
+ %.lcssa = phi double [ %4, %bb4 ]
+ store double %.lcssa, double* %scevgep24
+ br label %bb7
+
+bb9: ; preds = %bb7
+ %11 = add nsw i64 %storemerge17, 1
+ %exitcond6 = icmp eq i64 %11, 8000
+ br i1 %exitcond6, label %return, label %bb.nph
+
+return: ; preds = %bb9
+ ret void
+}
+; CHECK: for region: 'bb => return' in function 'scop_func':
+; CHECK-NEXT: scop_func():
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+/* Default problem size. */
+#ifndef NX
+# define NX 8000
+#endif
+#ifndef NY
+# define NY 8000
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[NX][NY];
+DATA_TYPE r[NX];
+DATA_TYPE s[NX];
+DATA_TYPE p[NX];
+DATA_TYPE q[NX];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(NX * sizeof(DATA_TYPE*));
+DATA_TYPE* r = (DATA_TYPE*)malloc(NX * sizeof(DATA_TYPE));
+DATA_TYPE* s = (DATA_TYPE*)malloc(NX * sizeof(DATA_TYPE));
+DATA_TYPE* p = (DATA_TYPE*)malloc(NX * sizeof(DATA_TYPE));
+DATA_TYPE* q = (DATA_TYPE*)malloc(NX * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i < NX; ++i)
+ A[i] = (DATA_TYPE*)malloc(NY * sizeof(DATA_TYPE));
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < NX; i++) {
+ r[i] = i * M_PI;
+ p[i] = i * M_PI;
+ for (j = 0; j < NY; j++) {
+ A[i][j] = ((DATA_TYPE) i*j)/NX;
+ }
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < NX; i++) {
+ fprintf(stderr, "%0.2lf ", s[i]);
+ fprintf(stderr, "%0.2lf ", q[i]);
+ if (i%80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long nx = NX;
+ long ny = NY;
+#else
+void scop_func(long nx, long ny) {
+#endif
+ long i, j;
+
+#pragma scop
+#pragma live-out s, q
+
+ for (i = 0; i < ny; i++)
+ s[i] = 0;
+
+ for (i = 0; i < nx; i++)
+ {
+ q[i] = 0;
+ for (j = 0; j < ny; j++)
+ {
+ s[j] = s[j] + r[i] * A[i][j];
+ q[i] = q[i] + A[i][j] * p[j];
+ }
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j;
+ int nx = NX;
+ int ny = NY;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(nx, ny);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/bicg/bicg_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@r = common global [8000 x double] zeroinitializer, align 32
+@p = common global [8000 x double] zeroinitializer, align 32
+@A = common global [8000 x [8000 x double]] zeroinitializer, align 32
+@s = common global [8000 x double] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@q = common global [8000 x double] zeroinitializer, align 32
+
+define void @scop_func(i64 %nx, i64 %ny) nounwind {
+entry:
+ %0 = icmp sgt i64 %ny, 0
+ br i1 %0, label %bb.preheader, label %bb7.preheader
+
+bb.preheader: ; preds = %entry
+ br label %bb
+
+bb: ; preds = %bb.preheader, %bb
+ %storemerge9 = phi i64 [ %1, %bb ], [ 0, %bb.preheader ]
+ %scevgep20 = getelementptr [8000 x double]* @s, i64 0, i64 %storemerge9
+ store double 0.000000e+00, double* %scevgep20, align 8
+ %1 = add nsw i64 %storemerge9, 1
+ %exitcond11 = icmp eq i64 %1, %ny
+ br i1 %exitcond11, label %bb7.preheader.loopexit, label %bb
+
+bb7.preheader.loopexit: ; preds = %bb
+ br label %bb7.preheader
+
+bb7.preheader: ; preds = %bb7.preheader.loopexit, %entry
+ %2 = icmp sgt i64 %nx, 0
+ br i1 %2, label %bb.nph8, label %return
+
+bb.nph8: ; preds = %bb7.preheader
+ br i1 %0, label %bb.nph.us.preheader, label %bb6.preheader
+
+bb.nph.us.preheader: ; preds = %bb.nph8
+ br label %bb.nph.us
+
+bb6.preheader: ; preds = %bb.nph8
+ br label %bb6
+
+bb6.us: ; preds = %bb4.us
+ %.lcssa = phi double [ %10, %bb4.us ]
+ store double %.lcssa, double* %scevgep15
+ %3 = add nsw i64 %storemerge14.us, 1
+ %exitcond = icmp eq i64 %3, %nx
+ br i1 %exitcond, label %return.loopexit1, label %bb.nph.us
+
+bb4.us: ; preds = %bb.nph.us, %bb4.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %10, %bb4.us ]
+ %storemerge23.us = phi i64 [ 0, %bb.nph.us ], [ %11, %bb4.us ]
+ %scevgep11 = getelementptr [8000 x [8000 x double]]* @A, i64 0, i64 %storemerge14.us, i64 %storemerge23.us
+ %scevgep12 = getelementptr [8000 x double]* @s, i64 0, i64 %storemerge23.us
+ %scevgep = getelementptr [8000 x double]* @p, i64 0, i64 %storemerge23.us
+ %4 = load double* %scevgep12, align 8
+ %5 = load double* %scevgep11, align 8
+ %6 = fmul double %12, %5
+ %7 = fadd double %4, %6
+ store double %7, double* %scevgep12, align 8
+ %8 = load double* %scevgep, align 8
+ %9 = fmul double %5, %8
+ %10 = fadd double %.tmp.0.us, %9
+ %11 = add nsw i64 %storemerge23.us, 1
+ %exitcond4 = icmp eq i64 %11, %ny
+ br i1 %exitcond4, label %bb6.us, label %bb4.us
+
+bb.nph.us: ; preds = %bb.nph.us.preheader, %bb6.us
+ %storemerge14.us = phi i64 [ %3, %bb6.us ], [ 0, %bb.nph.us.preheader ]
+ %scevgep16 = getelementptr [8000 x double]* @r, i64 0, i64 %storemerge14.us
+ %scevgep15 = getelementptr [8000 x double]* @q, i64 0, i64 %storemerge14.us
+ store double 0.000000e+00, double* %scevgep15, align 8
+ %12 = load double* %scevgep16, align 8
+ br label %bb4.us
+
+bb6: ; preds = %bb6.preheader, %bb6
+ %indvar = phi i64 [ %indvar.next, %bb6 ], [ 0, %bb6.preheader ]
+ %scevgep18 = getelementptr [8000 x double]* @q, i64 0, i64 %indvar
+ store double 0.000000e+00, double* %scevgep18, align 8
+ %indvar.next = add i64 %indvar, 1
+ %exitcond2 = icmp eq i64 %indvar.next, %nx
+ br i1 %exitcond2, label %return.loopexit, label %bb6
+
+return.loopexit: ; preds = %bb6
+ br label %return
+
+return.loopexit1: ; preds = %bb6.us
+ br label %return
+
+return: ; preds = %return.loopexit1, %return.loopexit, %bb7.preheader
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
+; CHECK-NEXT: scop_func():
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/bicg/bicg_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@r = common global [8000 x double] zeroinitializer, align 32
+@p = common global [8000 x double] zeroinitializer, align 32
+@A = common global [8000 x [8000 x double]] zeroinitializer, align 32
+@s = common global [8000 x double] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@q = common global [8000 x double] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph10:
+ br label %bb
+
+bb: ; preds = %bb, %bb.nph10
+ %storemerge9 = phi i64 [ 0, %bb.nph10 ], [ %0, %bb ]
+ %scevgep18 = getelementptr [8000 x double]* @s, i64 0, i64 %storemerge9
+ store double 0.000000e+00, double* %scevgep18, align 8
+ %0 = add nsw i64 %storemerge9, 1
+ %exitcond8 = icmp eq i64 %0, 8000
+ br i1 %exitcond8, label %bb.nph.us.preheader, label %bb
+
+bb.nph.us.preheader: ; preds = %bb
+ br label %bb.nph.us
+
+bb6.us: ; preds = %bb4.us
+ %.lcssa = phi double [ %8, %bb4.us ]
+ store double %.lcssa, double* %scevgep15
+ %1 = add nsw i64 %storemerge14.us, 1
+ %exitcond = icmp eq i64 %1, 8000
+ br i1 %exitcond, label %return, label %bb.nph.us
+
+bb4.us: ; preds = %bb.nph.us, %bb4.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %8, %bb4.us ]
+ %storemerge23.us = phi i64 [ 0, %bb.nph.us ], [ %9, %bb4.us ]
+ %scevgep11 = getelementptr [8000 x [8000 x double]]* @A, i64 0, i64 %storemerge14.us, i64 %storemerge23.us
+ %scevgep12 = getelementptr [8000 x double]* @s, i64 0, i64 %storemerge23.us
+ %scevgep = getelementptr [8000 x double]* @p, i64 0, i64 %storemerge23.us
+ %2 = load double* %scevgep12, align 8
+ %3 = load double* %scevgep11, align 8
+ %4 = fmul double %10, %3
+ %5 = fadd double %2, %4
+ store double %5, double* %scevgep12, align 8
+ %6 = load double* %scevgep, align 8
+ %7 = fmul double %3, %6
+ %8 = fadd double %.tmp.0.us, %7
+ %9 = add nsw i64 %storemerge23.us, 1
+ %exitcond1 = icmp eq i64 %9, 8000
+ br i1 %exitcond1, label %bb6.us, label %bb4.us
+
+bb.nph.us: ; preds = %bb.nph.us.preheader, %bb6.us
+ %storemerge14.us = phi i64 [ %1, %bb6.us ], [ 0, %bb.nph.us.preheader ]
+ %scevgep16 = getelementptr [8000 x double]* @r, i64 0, i64 %storemerge14.us
+ %scevgep15 = getelementptr [8000 x double]* @q, i64 0, i64 %storemerge14.us
+ store double 0.000000e+00, double* %scevgep15, align 8
+ %10 = load double* %scevgep16, align 8
+ br label %bb4.us
+
+return: ; preds = %bb6.us
+ ret void
+}
+; CHECK: for region: 'bb => return' in function 'scop_func':
+; CHECK-NEXT: scop_func():
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef NR
+# define NR 128
+#endif
+#ifndef NQ
+# define NQ 128
+#endif
+#ifndef NP
+# define NP 128
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[NR][NQ][NP];
+DATA_TYPE sum[NR][NQ][NP];
+DATA_TYPE C4[NP][NP];
+#else
+DATA_TYPE*** A = (DATA_TYPE***)malloc(NR * sizeof(DATA_TYPE**));
+DATA_TYPE*** sum = (DATA_TYPE***)malloc(NR * sizeof(DATA_TYPE**));
+DATA_TYPE** C4 = (DATA_TYPE**)malloc(NP * sizeof(DATA_TYPE*));
+{
+ int i, j;
+ for (i = 0; i < NR; ++i)
+ {
+ A[i] = (DATA_TYPE**)malloc(NQ * sizeof(DATA_TYPE*));
+ sum[i] = (DATA_TYPE**)malloc(NQ * sizeof(DATA_TYPE*));
+ for (i = 0; i < NP; ++i)
+ {
+ A[i][j] = (DATA_TYPE*)malloc(NP * sizeof(DATA_TYPE));
+ sum[i][j] = (DATA_TYPE*)malloc(NP * sizeof(DATA_TYPE));
+ }
+ }
+ for (i = 0; i < NP; ++i)
+ C4[i] = (DATA_TYPE*)malloc(NP * sizeof(DATA_TYPE));
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j, k;
+
+ for (i = 0; i < NR; i++)
+ for (j = 0; j < NQ; j++)
+ for (k = 0; k < NP; k++)
+ A[i][j][k] = ((DATA_TYPE) i*j + k) / NP;
+ for (i = 0; i < NP; i++)
+ for (j = 0; j < NP; j++)
+ C4[i][j] = ((DATA_TYPE) i*j) / NP;
+}
+
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j, k;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < NR; i++)
+ for (j = 0; j < NQ; j++)
+ for (k = 0; k < NP; k++) {
+ fprintf(stderr, "%0.2lf ", A[i][j][k]);
+ if ((i * NR + j * NQ + k)% 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long nr = NR;
+ long nq = NQ;
+ long np = NP;
+#else
+void scop_func(long nr, long nq, long np) {
+#endif
+
+ long r, q, p, s;
+#pragma scop
+#pragma live-out A
+
+ for (r = 0; r < nr; r++)
+ for (q = 0; q < nq; q++) {
+ for (p = 0; p < np; p++) {
+ sum[r][q][p] = 0;
+ for (s = 0; s < np; s++)
+ sum[r][q][p] = sum[r][q][p] + A[r][q][s] * C4[s][p];
+ }
+ for (p = 0; p < np; p++)
+ A[r][q][p] = sum[r][q][p];
+ }
+
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int r, q, p, s;
+ int nr = NR;
+ int nq = NQ;
+ int np = NP;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(nr, nq, np);
+#endif
+
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly -correlated-propagation %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/doitgen/doitgen_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [128 x [128 x [128 x double]]] zeroinitializer, align 32
+@C4 = common global [128 x [128 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@sum = common global [128 x [128 x [128 x double]]] zeroinitializer, align 32
+
+define void @scop_func(i64 %nr, i64 %nq, i64 %np) nounwind {
+entry:
+ %0 = icmp sgt i64 %nr, 0
+ br i1 %0, label %bb.nph50, label %return
+
+bb5.us: ; preds = %bb3.us
+ %.lcssa = phi double [ %5, %bb3.us ]
+ store double %.lcssa, double* %scevgep54
+ %1 = add nsw i64 %storemerge26.us, 1
+ %exitcond = icmp eq i64 %1, %np
+ br i1 %exitcond, label %bb9.loopexit, label %bb.nph.us
+
+bb3.us: ; preds = %bb.nph.us, %bb3.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %5, %bb3.us ]
+ %storemerge45.us = phi i64 [ 0, %bb.nph.us ], [ %6, %bb3.us ]
+ %scevgep = getelementptr [128 x [128 x double]]* @C4, i64 0, i64 %storemerge45.us, i64 %storemerge26.us
+ %scevgep51 = getelementptr [128 x [128 x [128 x double]]]* @A, i64 0, i64 %storemerge43, i64 %storemerge113, i64 %storemerge45.us
+ %2 = load double* %scevgep51, align 8
+ %3 = load double* %scevgep, align 8
+ %4 = fmul double %2, %3
+ %5 = fadd double %.tmp.0.us, %4
+ %6 = add nsw i64 %storemerge45.us, 1
+ %exitcond1 = icmp eq i64 %6, %np
+ br i1 %exitcond1, label %bb5.us, label %bb3.us
+
+bb.nph.us: ; preds = %bb.nph.us.preheader, %bb5.us
+ %storemerge26.us = phi i64 [ %1, %bb5.us ], [ 0, %bb.nph.us.preheader ]
+ %scevgep54 = getelementptr [128 x [128 x [128 x double]]]* @sum, i64 0, i64 %storemerge43, i64 %storemerge113, i64 %storemerge26.us
+ store double 0.000000e+00, double* %scevgep54, align 8
+ br label %bb3.us
+
+bb8: ; preds = %bb8.preheader, %bb8
+ %storemerge311 = phi i64 [ %8, %bb8 ], [ 0, %bb8.preheader ]
+ %scevgep62 = getelementptr [128 x [128 x [128 x double]]]* @sum, i64 0, i64 %storemerge43, i64 %storemerge113, i64 %storemerge311
+ %scevgep61 = getelementptr [128 x [128 x [128 x double]]]* @A, i64 0, i64 %storemerge43, i64 %storemerge113, i64 %storemerge311
+ %7 = load double* %scevgep62, align 8
+ store double %7, double* %scevgep61, align 8
+ %8 = add nsw i64 %storemerge311, 1
+ %exitcond6 = icmp eq i64 %8, %np
+ br i1 %exitcond6, label %bb10.loopexit, label %bb8
+
+bb9.loopexit: ; preds = %bb5.us
+ br i1 %14, label %bb8.preheader, label %bb10
+
+bb8.preheader: ; preds = %bb9.loopexit
+ br label %bb8
+
+bb10.loopexit: ; preds = %bb8
+ br label %bb10
+
+bb10: ; preds = %bb10.loopexit, %bb6.preheader, %bb9.loopexit
+ %storemerge12566 = phi i64 [ %storemerge113, %bb9.loopexit ], [ %storemerge113, %bb6.preheader ], [ %storemerge113, %bb10.loopexit ]
+ %storemerge4464 = phi i64 [ %storemerge43, %bb9.loopexit ], [ %storemerge43, %bb6.preheader ], [ %storemerge43, %bb10.loopexit ]
+ %9 = add nsw i64 %storemerge12566, 1
+ %10 = icmp slt i64 %9, %nq
+ br i1 %10, label %bb6.preheader.backedge, label %bb12
+
+bb6.preheader.backedge: ; preds = %bb10, %bb12
+ %storemerge43.be = phi i64 [ %storemerge4464, %bb10 ], [ %11, %bb12 ]
+ %storemerge113.be = phi i64 [ %9, %bb10 ], [ 0, %bb12 ]
+ br label %bb6.preheader
+
+bb6.preheader: ; preds = %bb6.preheader.backedge, %bb6.preheader.preheader
+ %storemerge43 = phi i64 [ 0, %bb6.preheader.preheader ], [ %storemerge43.be, %bb6.preheader.backedge ]
+ %storemerge113 = phi i64 [ 0, %bb6.preheader.preheader ], [ %storemerge113.be, %bb6.preheader.backedge ]
+ br i1 %14, label %bb.nph.us.preheader, label %bb10
+
+bb.nph.us.preheader: ; preds = %bb6.preheader
+ br label %bb.nph.us
+
+bb12: ; preds = %bb10
+ %11 = add nsw i64 %storemerge4464, 1
+ %12 = icmp slt i64 %11, %nr
+ br i1 %12, label %bb6.preheader.backedge, label %return.loopexit
+
+bb.nph50: ; preds = %entry
+ %13 = icmp sgt i64 %nq, 0
+ %14 = icmp sgt i64 %np, 0
+ br i1 %13, label %bb6.preheader.preheader, label %return
+
+bb6.preheader.preheader: ; preds = %bb.nph50
+ br label %bb6.preheader
+
+return.loopexit: ; preds = %bb12
+ br label %return
+
+return: ; preds = %return.loopexit, %bb.nph50, %entry
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/doitgen/doitgen_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [128 x [128 x [128 x double]]] zeroinitializer, align 32
+@C4 = common global [128 x [128 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@sum = common global [128 x [128 x [128 x double]]] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph50.bb.nph50.split_crit_edge:
+ br label %bb11.preheader
+
+bb5.us: ; preds = %bb3.us
+ %.lcssa = phi double [ %4, %bb3.us ]
+ store double %.lcssa, double* %scevgep54
+ %0 = add nsw i64 %storemerge26.us, 1
+ %exitcond = icmp eq i64 %0, 128
+ br i1 %exitcond, label %bb8.loopexit, label %bb.nph.us
+
+bb3.us: ; preds = %bb.nph.us, %bb3.us
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %4, %bb3.us ]
+ %storemerge45.us = phi i64 [ 0, %bb.nph.us ], [ %5, %bb3.us ]
+ %scevgep51 = getelementptr [128 x [128 x [128 x double]]]* @A, i64 0, i64 %storemerge30, i64 %storemerge113, i64 %storemerge45.us
+ %scevgep = getelementptr [128 x [128 x double]]* @C4, i64 0, i64 %storemerge45.us, i64 %storemerge26.us
+ %1 = load double* %scevgep51, align 8
+ %2 = load double* %scevgep, align 8
+ %3 = fmul double %1, %2
+ %4 = fadd double %.tmp.0.us, %3
+ %5 = add nsw i64 %storemerge45.us, 1
+ %exitcond1 = icmp eq i64 %5, 128
+ br i1 %exitcond1, label %bb5.us, label %bb3.us
+
+bb.nph.us: ; preds = %bb6.preheader, %bb5.us
+ %storemerge26.us = phi i64 [ %0, %bb5.us ], [ 0, %bb6.preheader ]
+ %scevgep54 = getelementptr [128 x [128 x [128 x double]]]* @sum, i64 0, i64 %storemerge30, i64 %storemerge113, i64 %storemerge26.us
+ store double 0.000000e+00, double* %scevgep54, align 8
+ br label %bb3.us
+
+bb8.loopexit: ; preds = %bb5.us
+ br label %bb8
+
+bb8: ; preds = %bb8.loopexit, %bb8
+ %storemerge311 = phi i64 [ %7, %bb8 ], [ 0, %bb8.loopexit ]
+ %scevgep57 = getelementptr [128 x [128 x [128 x double]]]* @sum, i64 0, i64 %storemerge30, i64 %storemerge113, i64 %storemerge311
+ %scevgep56 = getelementptr [128 x [128 x [128 x double]]]* @A, i64 0, i64 %storemerge30, i64 %storemerge113, i64 %storemerge311
+ %6 = load double* %scevgep57, align 8
+ store double %6, double* %scevgep56, align 8
+ %7 = add nsw i64 %storemerge311, 1
+ %exitcond6 = icmp eq i64 %7, 128
+ br i1 %exitcond6, label %bb10, label %bb8
+
+bb10: ; preds = %bb8
+ %8 = add nsw i64 %storemerge113, 1
+ %exitcond9 = icmp ne i64 %8, 128
+ br i1 %exitcond9, label %bb6.preheader, label %bb12
+
+bb6.preheader: ; preds = %bb11.preheader, %bb10
+ %storemerge113 = phi i64 [ %8, %bb10 ], [ 0, %bb11.preheader ]
+ br label %bb.nph.us
+
+bb12: ; preds = %bb10
+ %9 = add nsw i64 %storemerge30, 1
+ %exitcond14 = icmp ne i64 %9, 128
+ br i1 %exitcond14, label %bb11.preheader, label %return
+
+bb11.preheader: ; preds = %bb12, %bb.nph50.bb.nph50.split_crit_edge
+ %storemerge30 = phi i64 [ 0, %bb.nph50.bb.nph50.split_crit_edge ], [ %9, %bb12 ]
+ br label %bb6.preheader
+
+return: ; preds = %bb12
+ ret void
+}
+; CHECK: Valid Region for Scop: bb11.preheader => return
--- /dev/null
+-DNI=1024 -DNJ=1024 -DNK=1024
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef NI
+# define NI 512
+#endif
+#ifndef NJ
+# define NJ 512
+#endif
+#ifndef NK
+# define NK 512
+#endif
+
+
+/* Default data type is double (dgemm). */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE alpha;
+DATA_TYPE beta;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE C[NI][NJ];
+DATA_TYPE A[NI][NK];
+DATA_TYPE B[NK][NJ];
+#else
+DATA_TYPE** C = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+DATA_TYPE** A = (DATA_TYPE**)malloc(NI * sizeof(DATA_TYPE*));
+DATA_TYPE** B = (DATA_TYPE**)malloc(NK * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < NI; ++i)
+ {
+ C[i] = (DATA_TYPE*)malloc(NJ * sizeof(DATA_TYPE));
+ A[i] = (DATA_TYPE*)malloc(NK * sizeof(DATA_TYPE));
+ }
+ for (i = 0; i < NK; ++i)
+ B[i] = (DATA_TYPE*)malloc(NJ * sizeof(DATA_TYPE));
+}
+#endif
+
+
+inline
+void init_array()
+{
+ int i, j;
+
+ alpha = 32412;
+ beta = 2123;
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NK; j++)
+ A[i][j] = ((DATA_TYPE) i*j)/NI;
+ for (i = 0; i < NK; i++)
+ for (j = 0; j < NJ; j++)
+ B[i][j] = ((DATA_TYPE) i*j + 1)/NJ;
+ for (i = 0; i < NI; i++)
+ for (j = 0; j < NJ; j++)
+ C[i][j] = ((DATA_TYPE) i*j + 2)/NJ;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < NI; i++) {
+ for (j = 0; j < NJ; j++) {
+ fprintf(stderr, "%0.2lf ", C[i][j]);
+ if ((i * NI + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long ni = NI;
+ long nj = NJ;
+ long nk = NK;
+#else
+void scop_func(long ni, long nj, long nk) {
+#endif
+ long i, j, k;
+
+#pragma scop
+#pragma live-out C
+
+ /* C := alpha*A*B + beta*C */
+ for (i = 0; i < ni; i++)
+ for (j = 0; j < nj; j++)
+ {
+ C[i][j] *= beta;
+ for (k = 0; k < nk; ++k)
+ C[i][j] += alpha * A[i][k] * B[k][j];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, k;
+ int ni = NI;
+ int nj = NJ;
+ int nk = NK;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(ni, nj, nk);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/gemm/gemm_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha = common global double 0.000000e+00
+@beta = common global double 0.000000e+00
+@A = common global [512 x [512 x double]] zeroinitializer, align 32
+@B = common global [512 x [512 x double]] zeroinitializer, align 32
+@C = common global [512 x [512 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func(i64 %ni, i64 %nj, i64 %nk) nounwind {
+entry:
+ %0 = icmp sgt i64 %ni, 0
+ br i1 %0, label %bb.nph26, label %return
+
+bb.nph8: ; preds = %bb.nph8.preheader, %bb6
+ %indvar3 = phi i64 [ 0, %bb.nph8.preheader ], [ %indvar.next4, %bb6 ]
+ br i1 %14, label %bb.nph.us.preheader, label %bb4.preheader
+
+bb.nph.us.preheader: ; preds = %bb.nph8
+ br label %bb.nph.us
+
+bb4.preheader: ; preds = %bb.nph8
+ br label %bb4
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa = phi double [ %6, %bb2.us ]
+ store double %.lcssa, double* %scevgep30
+ %1 = add nsw i64 %storemerge14.us, 1
+ %exitcond = icmp eq i64 %1, %nj
+ br i1 %exitcond, label %bb6.loopexit1, label %bb.nph.us
+
+bb2.us: ; preds = %bb.nph.us, %bb2.us
+ %.tmp.0.us = phi double [ %9, %bb.nph.us ], [ %6, %bb2.us ]
+ %storemerge23.us = phi i64 [ 0, %bb.nph.us ], [ %7, %bb2.us ]
+ %scevgep27 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %indvar3, i64 %storemerge23.us
+ %scevgep = getelementptr [512 x [512 x double]]* @B, i64 0, i64 %storemerge23.us, i64 %storemerge14.us
+ %2 = load double* %scevgep27, align 8
+ %3 = fmul double %2, %15
+ %4 = load double* %scevgep, align 8
+ %5 = fmul double %3, %4
+ %6 = fadd double %.tmp.0.us, %5
+ %7 = add nsw i64 %storemerge23.us, 1
+ %exitcond6 = icmp eq i64 %7, %nk
+ br i1 %exitcond6, label %bb4.us, label %bb2.us
+
+bb.nph.us: ; preds = %bb.nph.us.preheader, %bb4.us
+ %storemerge14.us = phi i64 [ %1, %bb4.us ], [ 0, %bb.nph.us.preheader ]
+ %scevgep30 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %indvar3, i64 %storemerge14.us
+ %8 = load double* %scevgep30, align 8
+ %9 = fmul double %8, %13
+ store double %9, double* %scevgep30, align 8
+ br label %bb2.us
+
+bb4: ; preds = %bb4.preheader, %bb4
+ %indvar = phi i64 [ %indvar.next, %bb4 ], [ 0, %bb4.preheader ]
+ %scevgep35 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %indvar3, i64 %indvar
+ %10 = load double* %scevgep35, align 8
+ %11 = fmul double %10, %13
+ store double %11, double* %scevgep35, align 8
+ %indvar.next = add i64 %indvar, 1
+ %exitcond2 = icmp eq i64 %indvar.next, %nj
+ br i1 %exitcond2, label %bb6.loopexit, label %bb4
+
+bb6.loopexit: ; preds = %bb4
+ br label %bb6
+
+bb6.loopexit1: ; preds = %bb4.us
+ br label %bb6
+
+bb6: ; preds = %bb6.loopexit1, %bb6.loopexit
+ %indvar.next4 = add i64 %indvar3, 1
+ %exitcond11 = icmp ne i64 %indvar.next4, %ni
+ br i1 %exitcond11, label %bb.nph8, label %return.loopexit
+
+bb.nph26: ; preds = %entry
+ %12 = icmp sgt i64 %nj, 0
+ %13 = load double* @beta, align 8
+ %14 = icmp sgt i64 %nk, 0
+ %15 = load double* @alpha, align 8
+ br i1 %12, label %bb.nph8.preheader, label %return
+
+bb.nph8.preheader: ; preds = %bb.nph26
+ br label %bb.nph8
+
+return.loopexit: ; preds = %bb6
+ br label %return
+
+return: ; preds = %return.loopexit, %bb.nph26, %entry
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/gemm/gemm_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha = common global double 0.000000e+00
+@beta = common global double 0.000000e+00
+@A = common global [512 x [512 x double]] zeroinitializer, align 32
+@B = common global [512 x [512 x double]] zeroinitializer, align 32
+@C = common global [512 x [512 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func() nounwind {
+bb.nph26.bb.nph26.split_crit_edge:
+ %0 = load double* @beta, align 8
+ %1 = load double* @alpha, align 8
+ br label %bb5.preheader
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa = phi double [ %7, %bb2.us ]
+ store double %.lcssa, double* %scevgep30
+ %2 = add nsw i64 %storemerge14.us, 1
+ %exitcond = icmp eq i64 %2, 512
+ br i1 %exitcond, label %bb6, label %bb.nph.us
+
+bb2.us: ; preds = %bb.nph.us, %bb2.us
+ %.tmp.0.us = phi double [ %10, %bb.nph.us ], [ %7, %bb2.us ]
+ %storemerge23.us = phi i64 [ 0, %bb.nph.us ], [ %8, %bb2.us ]
+ %scevgep27 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %storemerge9, i64 %storemerge23.us
+ %scevgep = getelementptr [512 x [512 x double]]* @B, i64 0, i64 %storemerge23.us, i64 %storemerge14.us
+ %3 = load double* %scevgep27, align 8
+ %4 = fmul double %3, %1
+ %5 = load double* %scevgep, align 8
+ %6 = fmul double %4, %5
+ %7 = fadd double %.tmp.0.us, %6
+ %8 = add nsw i64 %storemerge23.us, 1
+ %exitcond1 = icmp eq i64 %8, 512
+ br i1 %exitcond1, label %bb4.us, label %bb2.us
+
+bb.nph.us: ; preds = %bb5.preheader, %bb4.us
+ %storemerge14.us = phi i64 [ %2, %bb4.us ], [ 0, %bb5.preheader ]
+ %scevgep30 = getelementptr [512 x [512 x double]]* @C, i64 0, i64 %storemerge9, i64 %storemerge14.us
+ %9 = load double* %scevgep30, align 8
+ %10 = fmul double %9, %0
+ store double %10, double* %scevgep30, align 8
+ br label %bb2.us
+
+bb6: ; preds = %bb4.us
+ %11 = add nsw i64 %storemerge9, 1
+ %exitcond6 = icmp ne i64 %11, 512
+ br i1 %exitcond6, label %bb5.preheader, label %return
+
+bb5.preheader: ; preds = %bb6, %bb.nph26.bb.nph26.split_crit_edge
+ %storemerge9 = phi i64 [ 0, %bb.nph26.bb.nph26.split_crit_edge ], [ %11, %bb6 ]
+ br label %bb.nph.us
+
+return: ; preds = %bb6
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef N
+# define N 4000
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE alpha;
+DATA_TYPE beta;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[N][N];
+DATA_TYPE B[N][N];
+DATA_TYPE x[N];
+DATA_TYPE u1[N];
+DATA_TYPE u2[N];
+DATA_TYPE v2[N];
+DATA_TYPE v1[N];
+DATA_TYPE w[N];
+DATA_TYPE y[N];
+DATA_TYPE z[N];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+DATA_TYPE** B = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+DATA_TYPE* x = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* u1 = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* u2 = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* v1 = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* v2 = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* w = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* y = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* z = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ {
+ A[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ B[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ }
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ alpha = 43532;
+ beta = 12313;
+ for (i = 0; i < N; i++)
+ {
+ u1[i] = i;
+ u2[i] = (i+1)/N/2.0;
+ v1[i] = (i+1)/N/4.0;
+ v2[i] = (i+1)/N/6.0;
+ y[i] = (i+1)/N/8.0;
+ z[i] = (i+1)/N/9.0;
+ x[i] = 0.0;
+ w[i] = 0.0;
+ for (j = 0; j < N; j++)
+ A[i][j] = ((DATA_TYPE) i*j) / N;
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < N; i++) {
+ fprintf(stderr, "%0.2lf ", w[i]);
+ if (i%80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long n = N;
+#else
+void scop_func(long n) {
+#endif
+ long i, j;
+
+#pragma scop
+#pragma live-out w
+
+ for (i = 0; i < n; i++)
+ for (j = 0; j < n; j++)
+ A[i][j] = A[i][j] + u1[i] * v1[j] + u2[i] * v2[j];
+
+ for (i = 0; i < n; i++)
+ for (j = 0; j < n; j++)
+ x[i] = x[i] + beta * A[j][i] * y[j];
+
+ for (i = 0; i < n; i++)
+ x[i] = x[i] + z[i];
+
+ for (i = 0; i < n; i++)
+ for (j = 0; j < n; j++)
+ w[i] = w[i] + alpha * A[i][j] * x[j];
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(n);
+#endif
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/gemver/gemver_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha = common global double 0.000000e+00
+@beta = common global double 0.000000e+00
+@u1 = common global [4000 x double] zeroinitializer, align 32
+@u2 = common global [4000 x double] zeroinitializer, align 32
+@v1 = common global [4000 x double] zeroinitializer, align 32
+@v2 = common global [4000 x double] zeroinitializer, align 32
+@y = common global [4000 x double] zeroinitializer, align 32
+@z = common global [4000 x double] zeroinitializer, align 32
+@x = common global [4000 x double] zeroinitializer, align 32
+@w = common global [4000 x double] zeroinitializer, align 32
+@A = common global [4000 x [4000 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@B = common global [4000 x [4000 x double]] zeroinitializer, align 32
+
+define void @scop_func(i64 %n) nounwind {
+entry:
+ %0 = icmp sgt i64 %n, 0
+ br i1 %0, label %bb.nph40.preheader, label %return
+
+bb.nph40.preheader: ; preds = %entry
+ br label %bb.nph40
+
+bb.nph40: ; preds = %bb.nph40.preheader, %bb3
+ %i.041 = phi i64 [ %11, %bb3 ], [ 0, %bb.nph40.preheader ]
+ %scevgep66 = getelementptr [4000 x double]* @u1, i64 0, i64 %i.041
+ %scevgep67 = getelementptr [4000 x double]* @u2, i64 0, i64 %i.041
+ %1 = load double* %scevgep66, align 8
+ %2 = load double* %scevgep67, align 8
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb.nph40
+ %j.039 = phi i64 [ 0, %bb.nph40 ], [ %10, %bb1 ]
+ %scevgep63 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %i.041, i64 %j.039
+ %scevgep62 = getelementptr [4000 x double]* @v2, i64 0, i64 %j.039
+ %scevgep61 = getelementptr [4000 x double]* @v1, i64 0, i64 %j.039
+ %3 = load double* %scevgep63, align 8
+ %4 = load double* %scevgep61, align 8
+ %5 = fmul double %1, %4
+ %6 = fadd double %3, %5
+ %7 = load double* %scevgep62, align 8
+ %8 = fmul double %2, %7
+ %9 = fadd double %6, %8
+ store double %9, double* %scevgep63, align 8
+ %10 = add nsw i64 %j.039, 1
+ %exitcond16 = icmp eq i64 %10, %n
+ br i1 %exitcond16, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %11 = add nsw i64 %i.041, 1
+ %exitcond20 = icmp eq i64 %11, %n
+ br i1 %exitcond20, label %bb10.preheader, label %bb.nph40
+
+bb10.preheader: ; preds = %bb3
+ br i1 %0, label %bb.nph38.bb.nph38.split_crit_edge, label %return
+
+bb.nph30: ; preds = %bb.nph38.bb.nph38.split_crit_edge, %bb9
+ %i.134 = phi i64 [ 0, %bb.nph38.bb.nph38.split_crit_edge ], [ %18, %bb9 ]
+ %scevgep59 = getelementptr [4000 x double]* @x, i64 0, i64 %i.134
+ %.promoted31 = load double* %scevgep59
+ br label %bb7
+
+bb7: ; preds = %bb7, %bb.nph30
+ %.tmp.032 = phi double [ %.promoted31, %bb.nph30 ], [ %16, %bb7 ]
+ %j.129 = phi i64 [ 0, %bb.nph30 ], [ %17, %bb7 ]
+ %scevgep56 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %j.129, i64 %i.134
+ %scevgep55 = getelementptr [4000 x double]* @y, i64 0, i64 %j.129
+ %12 = load double* %scevgep56, align 8
+ %13 = fmul double %12, %19
+ %14 = load double* %scevgep55, align 8
+ %15 = fmul double %13, %14
+ %16 = fadd double %.tmp.032, %15
+ %17 = add nsw i64 %j.129, 1
+ %exitcond10 = icmp eq i64 %17, %n
+ br i1 %exitcond10, label %bb9, label %bb7
+
+bb9: ; preds = %bb7
+ %.lcssa9 = phi double [ %16, %bb7 ]
+ store double %.lcssa9, double* %scevgep59
+ %18 = add nsw i64 %i.134, 1
+ %exitcond13 = icmp eq i64 %18, %n
+ br i1 %exitcond13, label %bb13.preheader, label %bb.nph30
+
+bb.nph38.bb.nph38.split_crit_edge: ; preds = %bb10.preheader
+ %19 = load double* @beta, align 8
+ br label %bb.nph30
+
+bb13.preheader: ; preds = %bb9
+ br i1 %0, label %bb12.preheader, label %return
+
+bb12.preheader: ; preds = %bb13.preheader
+ br label %bb12
+
+bb12: ; preds = %bb12.preheader, %bb12
+ %i.227 = phi i64 [ %23, %bb12 ], [ 0, %bb12.preheader ]
+ %scevgep52 = getelementptr [4000 x double]* @z, i64 0, i64 %i.227
+ %scevgep51 = getelementptr [4000 x double]* @x, i64 0, i64 %i.227
+ %20 = load double* %scevgep51, align 8
+ %21 = load double* %scevgep52, align 8
+ %22 = fadd double %20, %21
+ store double %22, double* %scevgep51, align 8
+ %23 = add nsw i64 %i.227, 1
+ %exitcond6 = icmp eq i64 %23, %n
+ br i1 %exitcond6, label %bb19.preheader, label %bb12
+
+bb19.preheader: ; preds = %bb12
+ br i1 %0, label %bb.nph26.bb.nph26.split_crit_edge, label %return
+
+bb.nph: ; preds = %bb.nph26.bb.nph26.split_crit_edge, %bb18
+ %i.322 = phi i64 [ 0, %bb.nph26.bb.nph26.split_crit_edge ], [ %30, %bb18 ]
+ %scevgep49 = getelementptr [4000 x double]* @w, i64 0, i64 %i.322
+ %.promoted = load double* %scevgep49
+ br label %bb16
+
+bb16: ; preds = %bb16, %bb.nph
+ %.tmp.0 = phi double [ %.promoted, %bb.nph ], [ %28, %bb16 ]
+ %j.221 = phi i64 [ 0, %bb.nph ], [ %29, %bb16 ]
+ %scevgep46 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %i.322, i64 %j.221
+ %scevgep = getelementptr [4000 x double]* @x, i64 0, i64 %j.221
+ %24 = load double* %scevgep46, align 8
+ %25 = fmul double %24, %31
+ %26 = load double* %scevgep, align 8
+ %27 = fmul double %25, %26
+ %28 = fadd double %.tmp.0, %27
+ %29 = add nsw i64 %j.221, 1
+ %exitcond1 = icmp eq i64 %29, %n
+ br i1 %exitcond1, label %bb18, label %bb16
+
+bb18: ; preds = %bb16
+ %.lcssa = phi double [ %28, %bb16 ]
+ store double %.lcssa, double* %scevgep49
+ %30 = add nsw i64 %i.322, 1
+ %exitcond = icmp eq i64 %30, %n
+ br i1 %exitcond, label %return.loopexit, label %bb.nph
+
+bb.nph26.bb.nph26.split_crit_edge: ; preds = %bb19.preheader
+ %31 = load double* @alpha, align 8
+ br label %bb.nph
+
+return.loopexit: ; preds = %bb18
+ br label %return
+
+return: ; preds = %return.loopexit, %bb19.preheader, %bb13.preheader, %bb10.preheader, %entry
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/gemver/gemver_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha = common global double 0.000000e+00
+@beta = common global double 0.000000e+00
+@u1 = common global [4000 x double] zeroinitializer, align 32
+@u2 = common global [4000 x double] zeroinitializer, align 32
+@v1 = common global [4000 x double] zeroinitializer, align 32
+@v2 = common global [4000 x double] zeroinitializer, align 32
+@y = common global [4000 x double] zeroinitializer, align 32
+@z = common global [4000 x double] zeroinitializer, align 32
+@x = common global [4000 x double] zeroinitializer, align 32
+@w = common global [4000 x double] zeroinitializer, align 32
+@A = common global [4000 x [4000 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@B = common global [4000 x [4000 x double]] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph31.bb.nph31.split_crit_edge:
+ br label %bb.nph26
+
+bb.nph26: ; preds = %bb3, %bb.nph31.bb.nph31.split_crit_edge
+ %storemerge27 = phi i64 [ 0, %bb.nph31.bb.nph31.split_crit_edge ], [ %10, %bb3 ]
+ %scevgep52 = getelementptr [4000 x double]* @u1, i64 0, i64 %storemerge27
+ %scevgep53 = getelementptr [4000 x double]* @u2, i64 0, i64 %storemerge27
+ %0 = load double* %scevgep52, align 8
+ %1 = load double* %scevgep53, align 8
+ br label %bb1
+
+bb1: ; preds = %bb1, %bb.nph26
+ %storemerge625 = phi i64 [ 0, %bb.nph26 ], [ %9, %bb1 ]
+ %scevgep47 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %storemerge27, i64 %storemerge625
+ %scevgep49 = getelementptr [4000 x double]* @v2, i64 0, i64 %storemerge625
+ %scevgep48 = getelementptr [4000 x double]* @v1, i64 0, i64 %storemerge625
+ %2 = load double* %scevgep47, align 8
+ %3 = load double* %scevgep48, align 8
+ %4 = fmul double %0, %3
+ %5 = fadd double %2, %4
+ %6 = load double* %scevgep49, align 8
+ %7 = fmul double %1, %6
+ %8 = fadd double %5, %7
+ store double %8, double* %scevgep47, align 8
+ %9 = add nsw i64 %storemerge625, 1
+ %exitcond16 = icmp eq i64 %9, 4000
+ br i1 %exitcond16, label %bb3, label %bb1
+
+bb3: ; preds = %bb1
+ %10 = add nsw i64 %storemerge27, 1
+ %exitcond20 = icmp eq i64 %10, 4000
+ br i1 %exitcond20, label %bb.nph24.bb.nph24.split_crit_edge, label %bb.nph26
+
+bb.nph16: ; preds = %bb.nph24.bb.nph24.split_crit_edge, %bb9
+ %storemerge120 = phi i64 [ 0, %bb.nph24.bb.nph24.split_crit_edge ], [ %17, %bb9 ]
+ %scevgep45 = getelementptr [4000 x double]* @x, i64 0, i64 %storemerge120
+ %.promoted17 = load double* %scevgep45
+ br label %bb7
+
+bb7: ; preds = %bb7, %bb.nph16
+ %.tmp.018 = phi double [ %.promoted17, %bb.nph16 ], [ %15, %bb7 ]
+ %storemerge515 = phi i64 [ 0, %bb.nph16 ], [ %16, %bb7 ]
+ %scevgep42 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %storemerge515, i64 %storemerge120
+ %scevgep41 = getelementptr [4000 x double]* @y, i64 0, i64 %storemerge515
+ %11 = load double* %scevgep42, align 8
+ %12 = fmul double %11, %18
+ %13 = load double* %scevgep41, align 8
+ %14 = fmul double %12, %13
+ %15 = fadd double %.tmp.018, %14
+ %16 = add nsw i64 %storemerge515, 1
+ %exitcond10 = icmp eq i64 %16, 4000
+ br i1 %exitcond10, label %bb9, label %bb7
+
+bb9: ; preds = %bb7
+ %.lcssa9 = phi double [ %15, %bb7 ]
+ store double %.lcssa9, double* %scevgep45
+ %17 = add nsw i64 %storemerge120, 1
+ %exitcond13 = icmp eq i64 %17, 4000
+ br i1 %exitcond13, label %bb12.preheader, label %bb.nph16
+
+bb12.preheader: ; preds = %bb9
+ br label %bb12
+
+bb.nph24.bb.nph24.split_crit_edge: ; preds = %bb3
+ %18 = load double* @beta, align 8
+ br label %bb.nph16
+
+bb12: ; preds = %bb12.preheader, %bb12
+ %storemerge213 = phi i64 [ %22, %bb12 ], [ 0, %bb12.preheader ]
+ %scevgep38 = getelementptr [4000 x double]* @x, i64 0, i64 %storemerge213
+ %scevgep37 = getelementptr [4000 x double]* @z, i64 0, i64 %storemerge213
+ %19 = load double* %scevgep38, align 8
+ %20 = load double* %scevgep37, align 8
+ %21 = fadd double %19, %20
+ store double %21, double* %scevgep38, align 8
+ %22 = add nsw i64 %storemerge213, 1
+ %exitcond6 = icmp eq i64 %22, 4000
+ br i1 %exitcond6, label %bb.nph12.bb.nph12.split_crit_edge, label %bb12
+
+bb.nph: ; preds = %bb.nph12.bb.nph12.split_crit_edge, %bb18
+ %storemerge38 = phi i64 [ 0, %bb.nph12.bb.nph12.split_crit_edge ], [ %29, %bb18 ]
+ %scevgep35 = getelementptr [4000 x double]* @w, i64 0, i64 %storemerge38
+ %.promoted = load double* %scevgep35
+ br label %bb16
+
+bb16: ; preds = %bb16, %bb.nph
+ %.tmp.0 = phi double [ %.promoted, %bb.nph ], [ %27, %bb16 ]
+ %storemerge47 = phi i64 [ 0, %bb.nph ], [ %28, %bb16 ]
+ %scevgep32 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %storemerge38, i64 %storemerge47
+ %scevgep = getelementptr [4000 x double]* @x, i64 0, i64 %storemerge47
+ %23 = load double* %scevgep32, align 8
+ %24 = fmul double %23, %30
+ %25 = load double* %scevgep, align 8
+ %26 = fmul double %24, %25
+ %27 = fadd double %.tmp.0, %26
+ %28 = add nsw i64 %storemerge47, 1
+ %exitcond1 = icmp eq i64 %28, 4000
+ br i1 %exitcond1, label %bb18, label %bb16
+
+bb18: ; preds = %bb16
+ %.lcssa = phi double [ %27, %bb16 ]
+ store double %.lcssa, double* %scevgep35
+ %29 = add nsw i64 %storemerge38, 1
+ %exitcond = icmp eq i64 %29, 4000
+ br i1 %exitcond, label %return, label %bb.nph
+
+bb.nph12.bb.nph12.split_crit_edge: ; preds = %bb12
+ %30 = load double* @alpha, align 8
+ br label %bb.nph
+
+return: ; preds = %bb18
+ ret void
+}
+; CHECK: for region: 'bb.nph26 => return' in function 'scop_func':
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef N
+# define N 4000
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE alpha;
+DATA_TYPE beta;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[N][N];
+DATA_TYPE B[N][N];
+DATA_TYPE x[N];
+DATA_TYPE y[N];
+DATA_TYPE tmp[N];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+DATA_TYPE** B = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+DATA_TYPE* x = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* y = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+DATA_TYPE* tmp = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ {
+ A[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ B[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ }
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ alpha = 43532;
+ beta = 12313;
+ for (i = 0; i < N; i++)
+ {
+ x[i] = ((DATA_TYPE) i) / N;
+ for (j = 0; j < N; j++)
+ A[i][j] = ((DATA_TYPE) i*j) / N;
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < N; i++) {
+ fprintf(stderr, "%0.2lf ", y[i]);
+ if (i%80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long n = N;
+#else
+void scop_func(long n) {
+#endif
+ long i, j;
+
+#pragma scop
+#pragma live-out y
+
+ for (i = 0; i < n; i++)
+ {
+ tmp[i] = 0;
+ y[i] = 0;
+ for (j = 0; j < n; j++)
+ {
+ tmp[i] = A[i][j] * x[j] + tmp[i];
+ y[i] = B[i][j] * x[j] + y[i];
+ }
+ y[i] = alpha * tmp[i] + beta * y[i];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/gesummv/gesummv_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha = common global double 0.000000e+00
+@beta = common global double 0.000000e+00
+@x = common global [4000 x double] zeroinitializer, align 32
+@A = common global [4000 x [4000 x double]] zeroinitializer, align 32
+@y = common global [4000 x double] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@tmp = common global [4000 x double] zeroinitializer, align 32
+@B = common global [4000 x [4000 x double]] zeroinitializer, align 32
+
+define void @scop_func(i64 %n) nounwind {
+entry:
+ %0 = icmp sgt i64 %n, 0
+ br i1 %0, label %bb.nph10.split.us, label %return
+
+bb.nph10.split.us: ; preds = %entry
+ %1 = load double* @alpha, align 8
+ %2 = load double* @beta, align 8
+ br label %bb.nph.us
+
+bb3.us: ; preds = %bb1.us
+ %.lcssa1 = phi double [ %13, %bb1.us ]
+ %.lcssa = phi double [ %10, %bb1.us ]
+ store double %.lcssa, double* %scevgep17
+ %3 = fmul double %.lcssa, %1
+ %4 = fmul double %.lcssa1, %2
+ %5 = fadd double %3, %4
+ store double %5, double* %scevgep18, align 8
+ %6 = add nsw i64 %storemerge6.us, 1
+ %exitcond = icmp eq i64 %6, %n
+ br i1 %exitcond, label %return.loopexit, label %bb.nph.us
+
+bb1.us: ; preds = %bb.nph.us, %bb1.us
+ %.tmp3.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %13, %bb1.us ]
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %10, %bb1.us ]
+ %storemerge12.us = phi i64 [ 0, %bb.nph.us ], [ %14, %bb1.us ]
+ %scevgep13 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %storemerge6.us, i64 %storemerge12.us
+ %scevgep = getelementptr [4000 x [4000 x double]]* @B, i64 0, i64 %storemerge6.us, i64 %storemerge12.us
+ %scevgep12 = getelementptr [4000 x double]* @x, i64 0, i64 %storemerge12.us
+ %7 = load double* %scevgep13, align 8
+ %8 = load double* %scevgep12, align 8
+ %9 = fmul double %7, %8
+ %10 = fadd double %9, %.tmp.0.us
+ %11 = load double* %scevgep, align 8
+ %12 = fmul double %11, %8
+ %13 = fadd double %12, %.tmp3.0.us
+ %14 = add nsw i64 %storemerge12.us, 1
+ %exitcond2 = icmp eq i64 %14, %n
+ br i1 %exitcond2, label %bb3.us, label %bb1.us
+
+bb.nph.us: ; preds = %bb3.us, %bb.nph10.split.us
+ %storemerge6.us = phi i64 [ 0, %bb.nph10.split.us ], [ %6, %bb3.us ]
+ %scevgep18 = getelementptr [4000 x double]* @y, i64 0, i64 %storemerge6.us
+ %scevgep17 = getelementptr [4000 x double]* @tmp, i64 0, i64 %storemerge6.us
+ store double 0.000000e+00, double* %scevgep17, align 8
+ store double 0.000000e+00, double* %scevgep18, align 8
+ br label %bb1.us
+
+return.loopexit: ; preds = %bb3.us
+ br label %return
+
+return: ; preds = %return.loopexit, %entry
+ ret void
+}
+; CHECK: for region: 'entry.split => return' in function 'scop_func':
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/kernels/gesummv/gesummv_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@alpha = common global double 0.000000e+00
+@beta = common global double 0.000000e+00
+@x = common global [4000 x double] zeroinitializer, align 32
+@A = common global [4000 x [4000 x double]] zeroinitializer, align 32
+@y = common global [4000 x double] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@tmp = common global [4000 x double] zeroinitializer, align 32
+@B = common global [4000 x [4000 x double]] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph10.split.us:
+ %0 = load double* @alpha, align 8
+ %1 = load double* @beta, align 8
+ br label %bb.nph.us
+
+bb3.us: ; preds = %bb1.us
+ %.lcssa1 = phi double [ %12, %bb1.us ]
+ %.lcssa = phi double [ %9, %bb1.us ]
+ store double %.lcssa, double* %scevgep17
+ %2 = fmul double %.lcssa, %0
+ %3 = fmul double %.lcssa1, %1
+ %4 = fadd double %2, %3
+ store double %4, double* %scevgep18, align 8
+ %5 = add nsw i64 %storemerge6.us, 1
+ %exitcond = icmp eq i64 %5, 4000
+ br i1 %exitcond, label %return, label %bb.nph.us
+
+bb1.us: ; preds = %bb.nph.us, %bb1.us
+ %.tmp3.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %12, %bb1.us ]
+ %.tmp.0.us = phi double [ 0.000000e+00, %bb.nph.us ], [ %9, %bb1.us ]
+ %storemerge12.us = phi i64 [ 0, %bb.nph.us ], [ %13, %bb1.us ]
+ %scevgep13 = getelementptr [4000 x [4000 x double]]* @A, i64 0, i64 %storemerge6.us, i64 %storemerge12.us
+ %scevgep = getelementptr [4000 x [4000 x double]]* @B, i64 0, i64 %storemerge6.us, i64 %storemerge12.us
+ %scevgep12 = getelementptr [4000 x double]* @x, i64 0, i64 %storemerge12.us
+ %6 = load double* %scevgep13, align 8
+ %7 = load double* %scevgep12, align 8
+ %8 = fmul double %6, %7
+ %9 = fadd double %8, %.tmp.0.us
+ %10 = load double* %scevgep, align 8
+ %11 = fmul double %10, %7
+ %12 = fadd double %11, %.tmp3.0.us
+ %13 = add nsw i64 %storemerge12.us, 1
+ %exitcond2 = icmp eq i64 %13, 4000
+ br i1 %exitcond2, label %bb3.us, label %bb1.us
+
+bb.nph.us: ; preds = %bb3.us, %bb.nph10.split.us
+ %storemerge6.us = phi i64 [ 0, %bb.nph10.split.us ], [ %5, %bb3.us ]
+ %scevgep18 = getelementptr [4000 x double]* @y, i64 0, i64 %storemerge6.us
+ %scevgep17 = getelementptr [4000 x double]* @tmp, i64 0, i64 %storemerge6.us
+ store double 0.000000e+00, double* %scevgep17, align 8
+ store double 0.000000e+00, double* %scevgep18, align 8
+ br label %bb1.us
+
+return: ; preds = %bb3.us
+ ret void
+}
+; CHECK: Valid Region for Scop: bb.nph.us => return
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef M
+# define M 512
+#endif
+#ifndef N
+# define N 512
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE nrm;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[M][N];
+DATA_TYPE R[M][N];
+DATA_TYPE Q[M][N];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(M * sizeof(DATA_TYPE*));
+DATA_TYPE** R = (DATA_TYPE**)malloc(M * sizeof(DATA_TYPE*));
+DATA_TYPE** Q = (DATA_TYPE**)malloc(M * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < M; ++i)
+ {
+ A[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ R[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ Q[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ }
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < M; i++)
+ for (j = 0; j < N; j++)
+ A[i][j] = ((DATA_TYPE) i*j) / M;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < M; i++)
+ for (j = 0; j < N; j++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, A[i][j]);
+ if ((i * M + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long m = M;
+ long n = N;
+#else
+void scop_func(long m, long n) {
+#endif
+ long i, j, k;
+
+#pragma scop
+#pragma live-out A
+
+ for (k = 0; k < n; k++)
+ {
+ nrm = 0;
+ for (i = 0; i < m; i++)
+ nrm += A[i][k] * A[i][k];
+ R[k][k] = sqrt(nrm);
+ for (i = 0; i < m; i++)
+ Q[i][k] = A[i][k] / R[k][k];
+ for (j = k + 1; j < n; j++)
+ {
+ R[k][j] = 0;
+ for (i = 0; i < m; i++)
+ R[k][j] += Q[i][k] * A[i][j];
+ for (i = 0; i < m; i++)
+ A[i][j] = A[i][j] - Q[i][k] * R[k][j];
+ }
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, k;
+ int m = M;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(m, n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-prepare -polly-cloog -analyze %s | FileCheck %s
+; XFAIL: *
+; ModuleID = './linear-algebra/solvers/gramschmidt/gramschmidt_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@nrm = common global double 0.000000e+00, align 8
+@A = common global [512 x [512 x double]] zeroinitializer, align 16
+@R = common global [512 x [512 x double]] zeroinitializer, align 16
+@Q = common global [512 x [512 x double]] zeroinitializer, align 16
+
+define void @scop_func(i64 %m, i64 %n) nounwind {
+bb:
+ %tmp3 = icmp sgt i64 %m, 0
+ %smax4 = select i1 %tmp3, i64 %m, i64 0
+ %tmp = icmp sgt i64 %m, 0
+ %smax = select i1 %tmp, i64 %m, i64 0
+ %tmp12 = icmp sgt i64 %m, 0
+ %smax13 = select i1 %tmp12, i64 %m, i64 0
+ %tmp25 = icmp sgt i64 %m, 0
+ %smax26 = select i1 %tmp25, i64 %m, i64 0
+ %tmp40 = add i64 %n, -1
+ %tmp60 = icmp sgt i64 %n, 0
+ %smax61 = select i1 %tmp60, i64 %n, i64 0
+ br label %bb1
+
+bb1: ; preds = %bb58, %bb
+ %tmp2 = phi i64 [ 0, %bb ], [ %tmp59, %bb58 ]
+ %tmp63 = mul i64 %tmp2, 513
+ %tmp64 = add i64 %tmp63, 1
+ %tmp67 = add i64 %tmp2, 1
+ %tmp71 = mul i64 %tmp2, -1
+ %tmp45 = add i64 %tmp40, %tmp71
+ %scevgep50 = getelementptr [512 x [512 x double]]* @R, i64 0, i64 0, i64 %tmp63
+ %exitcond62 = icmp ne i64 %tmp2, %smax61
+ br i1 %exitcond62, label %bb3, label %bb60
+
+bb3: ; preds = %bb1
+ store double 0.000000e+00, double* @nrm, align 8
+ br label %bb4
+
+bb4: ; preds = %bb12, %bb3
+ %i.0 = phi i64 [ 0, %bb3 ], [ %tmp14, %bb12 ]
+ %scevgep = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.0, i64 %tmp2
+ %exitcond5 = icmp ne i64 %i.0, %smax4
+ br i1 %exitcond5, label %bb5, label %bb15
+
+bb5: ; preds = %bb4
+ %tmp7 = load double* %scevgep
+ %tmp8 = load double* %scevgep
+ %tmp9 = fmul double %tmp7, %tmp8
+ %tmp10 = load double* @nrm, align 8
+ %tmp11 = fadd double %tmp10, %tmp9
+ store double %tmp11, double* @nrm, align 8
+ br label %bb12
+
+bb12: ; preds = %bb5
+ %tmp14 = add nsw i64 %i.0, 1
+ br label %bb4
+
+bb15: ; preds = %bb4
+ %tmp16 = load double* @nrm, align 8
+ %tmp17 = call double @sqrt(double %tmp16)
+ store double %tmp17, double* %scevgep50
+ br label %bb18
+
+bb18: ; preds = %bb25, %bb15
+ %i.1 = phi i64 [ 0, %bb15 ], [ %tmp26, %bb25 ]
+ %scevgep5 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.1, i64 %tmp2
+ %scevgep4 = getelementptr [512 x [512 x double]]* @Q, i64 0, i64 %i.1, i64 %tmp2
+ %exitcond = icmp ne i64 %i.1, %smax
+ br i1 %exitcond, label %bb19, label %bb27
+
+bb19: ; preds = %bb18
+ %tmp21 = load double* %scevgep5
+ %tmp23 = load double* %scevgep50
+ %tmp24 = fdiv double %tmp21, %tmp23
+ store double %tmp24, double* %scevgep4
+ br label %bb25
+
+bb25: ; preds = %bb19
+ %tmp26 = add nsw i64 %i.1, 1
+ br label %bb18
+
+bb27: ; preds = %bb18
+ br label %bb28
+
+bb28: ; preds = %bb56, %bb27
+ %indvar = phi i64 [ %indvar.next, %bb56 ], [ 0, %bb27 ]
+ %tmp65 = add i64 %tmp64, %indvar
+ %scevgep31 = getelementptr [512 x [512 x double]]* @R, i64 0, i64 0, i64 %tmp65
+ %tmp68 = add i64 %tmp67, %indvar
+ %exitcond46 = icmp ne i64 %indvar, %tmp45
+ br i1 %exitcond46, label %bb29, label %bb57
+
+bb29: ; preds = %bb28
+ store double 0.000000e+00, double* %scevgep31
+ br label %bb30
+
+bb30: ; preds = %bb43, %bb29
+ %i.2 = phi i64 [ 0, %bb29 ], [ %tmp44, %bb43 ]
+ %scevgep11 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.2, i64 %tmp68
+ %scevgep12 = getelementptr [512 x [512 x double]]* @Q, i64 0, i64 %i.2, i64 %tmp2
+ %exitcond14 = icmp ne i64 %i.2, %smax13
+ br i1 %exitcond14, label %bb31, label %bb45
+
+bb31: ; preds = %bb30
+ %tmp33 = load double* %scevgep12
+ %tmp34 = load double* %scevgep11
+ %tmp38 = fmul double %tmp33, %tmp34
+ %tmp41 = load double* %scevgep31
+ %tmp42 = fadd double %tmp41, %tmp38
+ store double %tmp42, double* %scevgep31
+ br label %bb43
+
+bb43: ; preds = %bb31
+ %tmp44 = add nsw i64 %i.2, 1
+ br label %bb30
+
+bb45: ; preds = %bb30
+ br label %bb46
+
+bb46: ; preds = %bb53, %bb45
+ %i.3 = phi i64 [ 0, %bb45 ], [ %tmp54, %bb53 ]
+ %scevgep18 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.3, i64 %tmp68
+ %scevgep19 = getelementptr [512 x [512 x double]]* @Q, i64 0, i64 %i.3, i64 %tmp2
+ %exitcond27 = icmp ne i64 %i.3, %smax26
+ br i1 %exitcond27, label %bb47, label %bb55
+
+bb47: ; preds = %bb46
+ %tmp48 = load double* %scevgep18
+ %tmp49 = load double* %scevgep19
+ %tmp50 = load double* %scevgep31
+ %tmp51 = fmul double %tmp49, %tmp50
+ %tmp52 = fsub double %tmp48, %tmp51
+ store double %tmp52, double* %scevgep18
+ br label %bb53
+
+bb53: ; preds = %bb47
+ %tmp54 = add nsw i64 %i.3, 1
+ br label %bb46
+
+bb55: ; preds = %bb46
+ br label %bb56
+
+bb56: ; preds = %bb55
+ %indvar.next = add i64 %indvar, 1
+ br label %bb28
+
+bb57: ; preds = %bb28
+ br label %bb58
+
+bb58: ; preds = %bb57
+ %tmp59 = add nsw i64 %tmp2, 1
+ br label %bb1
+
+bb60: ; preds = %bb1
+ ret void
+}
+
+declare double @sqrt(double) nounwind readnone
+
+define i32 @main(i32 %argc, i8** %argv) nounwind {
+bb:
+ call void (...)* @init_array()
+ %tmp = sext i32 512 to i64
+ %tmp1 = sext i32 512 to i64
+ call void @scop_func(i64 %tmp, i64 %tmp1)
+ call void @print_array(i32 %argc, i8** %argv)
+ ret i32 0
+}
+
+declare void @init_array(...)
+
+declare void @print_array(i32, i8**)
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-prepare -polly-cloog -analyze %s | FileCheck %s
+; ModuleID = './linear-algebra/solvers/gramschmidt/gramschmidt_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-pc-linux-gnu"
+
+@nrm = common global double 0.000000e+00, align 8
+@A = common global [512 x [512 x double]] zeroinitializer, align 16
+@R = common global [512 x [512 x double]] zeroinitializer, align 16
+@Q = common global [512 x [512 x double]] zeroinitializer, align 16
+
+define void @scop_func() nounwind {
+bb:
+ br label %bb1
+
+bb1: ; preds = %bb51, %bb
+ %tmp2 = phi i64 [ 0, %bb ], [ %tmp52, %bb51 ]
+ %tmp49 = mul i64 %tmp2, 513
+ %tmp50 = add i64 %tmp49, 1
+ %tmp53 = add i64 %tmp2, 1
+ %tmp57 = mul i64 %tmp2, -1
+ %tmp28 = add i64 %tmp57, 511
+ %scevgep39 = getelementptr [512 x [512 x double]]* @R, i64 0, i64 0, i64 %tmp49
+ %exitcond48 = icmp ne i64 %tmp2, 512
+ br i1 %exitcond48, label %bb3, label %bb53
+
+bb3: ; preds = %bb1
+ store double 0.000000e+00, double* @nrm, align 8
+ br label %bb4
+
+bb4: ; preds = %bb11, %bb3
+ %i.0 = phi i64 [ 0, %bb3 ], [ %tmp12, %bb11 ]
+ %scevgep = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.0, i64 %tmp2
+ %exitcond2 = icmp ne i64 %i.0, 512
+ br i1 %exitcond2, label %bb5, label %bb13
+
+bb5: ; preds = %bb4
+ %tmp6 = load double* %scevgep
+ %tmp7 = load double* %scevgep
+ %tmp8 = fmul double %tmp6, %tmp7
+ %tmp9 = load double* @nrm, align 8
+ %tmp10 = fadd double %tmp9, %tmp8
+ store double %tmp10, double* @nrm, align 8
+ br label %bb11
+
+bb11: ; preds = %bb5
+ %tmp12 = add nsw i64 %i.0, 1
+ br label %bb4
+
+bb13: ; preds = %bb4
+ %tmp15 = load double* @nrm, align 8
+ %tmp16 = call double @sqrt(double %tmp15)
+ store double %tmp16, double* %scevgep39
+ br label %bb17
+
+bb17: ; preds = %bb22, %bb13
+ %i.1 = phi i64 [ 0, %bb13 ], [ %tmp23, %bb22 ]
+ %scevgep3 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.1, i64 %tmp2
+ %scevgep2 = getelementptr [512 x [512 x double]]* @Q, i64 0, i64 %i.1, i64 %tmp2
+ %exitcond = icmp ne i64 %i.1, 512
+ br i1 %exitcond, label %bb18, label %bb24
+
+bb18: ; preds = %bb17
+ %tmp19 = load double* %scevgep3
+ %tmp20 = load double* %scevgep39
+ %tmp21 = fdiv double %tmp19, %tmp20
+ store double %tmp21, double* %scevgep2
+ br label %bb22
+
+bb22: ; preds = %bb18
+ %tmp23 = add nsw i64 %i.1, 1
+ br label %bb17
+
+bb24: ; preds = %bb17
+ br label %bb25
+
+bb25: ; preds = %bb49, %bb24
+ %indvar = phi i64 [ %indvar.next, %bb49 ], [ 0, %bb24 ]
+ %tmp51 = add i64 %tmp50, %indvar
+ %scevgep23 = getelementptr [512 x [512 x double]]* @R, i64 0, i64 0, i64 %tmp51
+ %tmp54 = add i64 %tmp53, %indvar
+ %exitcond29 = icmp ne i64 %indvar, %tmp28
+ br i1 %exitcond29, label %bb26, label %bb50
+
+bb26: ; preds = %bb25
+ store double 0.000000e+00, double* %scevgep23
+ br label %bb27
+
+bb27: ; preds = %bb36, %bb26
+ %i.2 = phi i64 [ 0, %bb26 ], [ %tmp37, %bb36 ]
+ %scevgep6 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.2, i64 %tmp54
+ %scevgep7 = getelementptr [512 x [512 x double]]* @Q, i64 0, i64 %i.2, i64 %tmp2
+ %exitcond9 = icmp ne i64 %i.2, 512
+ br i1 %exitcond9, label %bb28, label %bb38
+
+bb28: ; preds = %bb27
+ %tmp30 = load double* %scevgep7
+ %tmp31 = load double* %scevgep6
+ %tmp33 = fmul double %tmp30, %tmp31
+ %tmp34 = load double* %scevgep23
+ %tmp35 = fadd double %tmp34, %tmp33
+ store double %tmp35, double* %scevgep23
+ br label %bb36
+
+bb36: ; preds = %bb28
+ %tmp37 = add nsw i64 %i.2, 1
+ br label %bb27
+
+bb38: ; preds = %bb27
+ br label %bb39
+
+bb39: ; preds = %bb46, %bb38
+ %i.3 = phi i64 [ 0, %bb38 ], [ %tmp47, %bb46 ]
+ %scevgep11 = getelementptr [512 x [512 x double]]* @A, i64 0, i64 %i.3, i64 %tmp54
+ %scevgep12 = getelementptr [512 x [512 x double]]* @Q, i64 0, i64 %i.3, i64 %tmp2
+ %exitcond16 = icmp ne i64 %i.3, 512
+ br i1 %exitcond16, label %bb40, label %bb48
+
+bb40: ; preds = %bb39
+ %tmp41 = load double* %scevgep11
+ %tmp42 = load double* %scevgep12
+ %tmp43 = load double* %scevgep23
+ %tmp44 = fmul double %tmp42, %tmp43
+ %tmp45 = fsub double %tmp41, %tmp44
+ store double %tmp45, double* %scevgep11
+ br label %bb46
+
+bb46: ; preds = %bb40
+ %tmp47 = add nsw i64 %i.3, 1
+ br label %bb39
+
+bb48: ; preds = %bb39
+ br label %bb49
+
+bb49: ; preds = %bb48
+ %indvar.next = add i64 %indvar, 1
+ br label %bb25
+
+bb50: ; preds = %bb25
+ br label %bb51
+
+bb51: ; preds = %bb50
+ %tmp52 = add nsw i64 %tmp2, 1
+ br label %bb1
+
+bb53: ; preds = %bb1
+ ret void
+}
+
+declare double @sqrt(double) nounwind readnone
+
+define i32 @main(i32 %argc, i8** %argv) nounwind {
+bb:
+ call void (...)* @init_array()
+ call void @scop_func()
+ call void @print_array(i32 %argc, i8** %argv)
+ ret i32 0
+}
+
+declare void @init_array(...)
+
+declare void @print_array(i32, i8**)
+; CHECK: for region: 'bb1 => bb53' in function 'scop_func':
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef N
+# define N 1024
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[N][N];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < M; ++i)
+ A[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ A[i][j] = ((DATA_TYPE) i*j + 1) / N;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, A[i][j]);
+ if ((i * N + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long n = N;
+#else
+void scop_func(long n) {
+#endif
+ long i, j, k;
+
+#pragma scop
+#pragma live-out A
+
+ for (k = 0; k < n; k++)
+ {
+ for (j = k + 1; j < n; j++)
+ A[k][j] = A[k][j] / A[k][k];
+ for(i = k + 1; i < n; i++)
+ for (j = k + 1; j < n; j++)
+ A[i][j] = A[i][j] - A[i][k] * A[k][j];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, k;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; region-simplify make polly fail to detect the canonical induction variable.
+; XFAIL:*
+
+; ModuleID = './linear-algebra/solvers/lu/lu_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func(i64 %n) nounwind {
+entry:
+ %0 = icmp sgt i64 %n, 0
+ br i1 %0, label %bb.nph28, label %return
+
+bb1: ; preds = %bb1.preheader, %bb1
+ %indvar = phi i64 [ %indvar.next, %bb1 ], [ 0, %bb1.preheader ]
+ %tmp27 = add i64 %tmp26, %indvar
+ %scevgep = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 0, i64 %tmp27
+ %1 = load double* %scevgep, align 8
+ %2 = load double* %scevgep69, align 8
+ %3 = fdiv double %1, %2
+ store double %3, double* %scevgep, align 8
+ %indvar.next = add i64 %indvar, 1
+ %exitcond20 = icmp eq i64 %indvar.next, %tmp1
+ br i1 %exitcond20, label %bb8.loopexit, label %bb1
+
+bb5: ; preds = %bb6.preheader, %bb5
+ %indvar34 = phi i64 [ %indvar.next35, %bb5 ], [ 0, %bb6.preheader ]
+ %tmp34 = add i64 %tmp26, %indvar34
+ %scevgep45 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp32, i64 %tmp34
+ %scevgep46 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 0, i64 %tmp34
+ %4 = load double* %scevgep45, align 8
+ %5 = load double* %scevgep55, align 8
+ %6 = load double* %scevgep46, align 8
+ %7 = fmul double %5, %6
+ %8 = fsub double %4, %7
+ store double %8, double* %scevgep45, align 8
+ %indvar.next35 = add i64 %indvar34, 1
+ %exitcond2 = icmp eq i64 %indvar.next35, %tmp1
+ br i1 %exitcond2, label %bb8.loopexit4, label %bb5
+
+bb8.loopexit: ; preds = %bb1
+ br i1 %10, label %bb6.preheader.preheader, label %bb9
+
+bb6.preheader.preheader: ; preds = %bb8.loopexit
+ br label %bb6.preheader
+
+bb8.loopexit4: ; preds = %bb5
+ %exitcond11 = icmp eq i64 %tmp57, %tmp1
+ br i1 %exitcond11, label %bb9.loopexit, label %bb6.preheader
+
+bb6.preheader: ; preds = %bb6.preheader.preheader, %bb8.loopexit4
+ %indvar39 = phi i64 [ %tmp57, %bb8.loopexit4 ], [ 0, %bb6.preheader.preheader ]
+ %tmp32 = add i64 %indvar39, 1
+ %scevgep55 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp32, i64 %tmp25
+ %tmp57 = add i64 %indvar39, 1
+ br label %bb5
+
+bb9.loopexit: ; preds = %bb8.loopexit4
+ br label %bb9
+
+bb9: ; preds = %bb9.loopexit, %bb2.preheader, %bb8.loopexit
+ %exitcond = icmp eq i64 %9, %n
+ br i1 %exitcond, label %return.loopexit, label %bb2.preheader
+
+bb.nph28: ; preds = %entry
+ %tmp29 = add i64 %n, -1
+ br label %bb2.preheader
+
+bb2.preheader: ; preds = %bb.nph28, %bb9
+ %storemerge17 = phi i64 [ 0, %bb.nph28 ], [ %9, %bb9 ]
+ %tmp25 = mul i64 %storemerge17, 1025
+ %tmp26 = add i64 %tmp25, 1
+ %tmp30 = mul i64 %storemerge17, -1
+ %tmp1 = add i64 %tmp29, %tmp30
+ %storemerge15 = add i64 %storemerge17, 1
+ %scevgep69 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 0, i64 %tmp25
+ %9 = add i64 %storemerge17, 1
+ %10 = icmp slt i64 %storemerge15, %n
+ br i1 %10, label %bb1.preheader, label %bb9
+
+bb1.preheader: ; preds = %bb2.preheader
+ br label %bb1
+
+return.loopexit: ; preds = %bb9
+ br label %return
+
+return: ; preds = %return.loopexit, %entry
+ ret void
+}
+; CHECK: Valid Region for Scop: entry.split => return
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; region-simplify make polly fail to detect the canonical induction variable.
+; XFAIL:*
+
+; ModuleID = './linear-algebra/solvers/lu/lu_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func() nounwind {
+bb.nph28:
+ br label %bb2.preheader
+
+bb1: ; preds = %bb1.preheader, %bb1
+ %indvar = phi i64 [ %indvar.next, %bb1 ], [ 0, %bb1.preheader ]
+ %tmp27 = add i64 %tmp26, %indvar
+ %scevgep = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 0, i64 %tmp27
+ %0 = load double* %scevgep, align 8
+ %1 = load double* %scevgep68, align 8
+ %2 = fdiv double %0, %1
+ store double %2, double* %scevgep, align 8
+ %indvar.next = add i64 %indvar, 1
+ %exitcond20 = icmp eq i64 %indvar.next, %tmp1
+ br i1 %exitcond20, label %bb8.loopexit, label %bb1
+
+bb5: ; preds = %bb6.preheader, %bb5
+ %indvar33 = phi i64 [ %indvar.next34, %bb5 ], [ 0, %bb6.preheader ]
+ %tmp33 = add i64 %tmp26, %indvar33
+ %scevgep44 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp31, i64 %tmp33
+ %scevgep45 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 0, i64 %tmp33
+ %3 = load double* %scevgep44, align 8
+ %4 = load double* %scevgep54, align 8
+ %5 = load double* %scevgep45, align 8
+ %6 = fmul double %4, %5
+ %7 = fsub double %3, %6
+ store double %7, double* %scevgep44, align 8
+ %indvar.next34 = add i64 %indvar33, 1
+ %exitcond2 = icmp eq i64 %indvar.next34, %tmp1
+ br i1 %exitcond2, label %bb8.loopexit4, label %bb5
+
+bb8.loopexit: ; preds = %bb1
+ br i1 %9, label %bb6.preheader.preheader, label %bb9
+
+bb6.preheader.preheader: ; preds = %bb8.loopexit
+ br label %bb6.preheader
+
+bb8.loopexit4: ; preds = %bb5
+ %exitcond11 = icmp eq i64 %tmp56, %tmp1
+ br i1 %exitcond11, label %bb9.loopexit, label %bb6.preheader
+
+bb6.preheader: ; preds = %bb6.preheader.preheader, %bb8.loopexit4
+ %indvar38 = phi i64 [ %tmp56, %bb8.loopexit4 ], [ 0, %bb6.preheader.preheader ]
+ %tmp31 = add i64 %indvar38, 1
+ %scevgep54 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp31, i64 %tmp25
+ %tmp56 = add i64 %indvar38, 1
+ br label %bb5
+
+bb9.loopexit: ; preds = %bb8.loopexit4
+ br label %bb9
+
+bb9: ; preds = %bb9.loopexit, %bb2.preheader, %bb8.loopexit
+ %exitcond = icmp eq i64 %8, 1024
+ br i1 %exitcond, label %return, label %bb2.preheader
+
+bb2.preheader: ; preds = %bb9, %bb.nph28
+ %storemerge17 = phi i64 [ 0, %bb.nph28 ], [ %8, %bb9 ]
+ %tmp25 = mul i64 %storemerge17, 1025
+ %tmp26 = add i64 %tmp25, 1
+ %tmp29 = mul i64 %storemerge17, -1
+ %tmp1 = add i64 %tmp29, 1023
+ %storemerge15 = add i64 %storemerge17, 1
+ %scevgep68 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 0, i64 %tmp25
+ %8 = add i64 %storemerge17, 1
+ %9 = icmp slt i64 %storemerge15, 1024
+ br i1 %9, label %bb1.preheader, label %bb9
+
+bb1.preheader: ; preds = %bb2.preheader
+ br label %bb1
+
+return: ; preds = %bb9
+ ret void
+}
+; CHECK: Valid Region for Scop: bb2.preheader => return
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef N
+# define N 1024
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+DATA_TYPE w;
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE a[N+1][N+1];
+DATA_TYPE x[N+1];
+DATA_TYPE y[N+1];
+DATA_TYPE b[N+1];
+#else
+DATA_TYPE** a = (DATA_TYPE**)malloc((N + 1) * sizeof(DATA_TYPE*));
+DATA_TYPE* x = (DATA_TYPE*)malloc((N + 1) * sizeof(DATA_TYPE));
+DATA_TYPE* y = (DATA_TYPE*)malloc((N + 1) * sizeof(DATA_TYPE));
+DATA_TYPE* b = (DATA_TYPE*)malloc((N + 1) * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i <= N; ++i)
+ a[i] = (DATA_TYPE*)malloc((N + 1) * sizeof(DATA_TYPE));
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i <= N; i++)
+ {
+ x[i] = ((DATA_TYPE) i + 1) / N;
+ b[i] = ((DATA_TYPE) i + 2) / N;
+ for (j = 0; j <= N; j++)
+ a[i][j] = ((DATA_TYPE) i*j + 1) / N;
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i <= N; i++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, x[i]);
+ if (i % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long n = N;
+#else
+void scop_func(long n) {
+#endif
+ long i, j, k;
+#pragma scop
+#pragma live-out x
+
+ b[0] = 1.0;
+ for (i = 0; i < n; i++)
+ {
+ for (j = i+1; j <= n; j++)
+ {
+ w = a[j][i];
+ for (k = 0; k < i; k++)
+ w = w- a[j][k] * a[k][i];
+ a[j][i] = w / a[i][i];
+ }
+ for (j = i+1; j <= n; j++)
+ {
+ w = a[i+1][j];
+ for (k = 0; k <= i; k++)
+ w = w - a[i+1][k] * a[k][j];
+ a[i+1][j] = w;
+ }
+ }
+ y[0] = b[0];
+ for (i = 1; i <= n; i++)
+ {
+ w = b[i];
+ for (j = 0; j < i; j++)
+ w = w - a[i][j] * y[j];
+ y[i] = w;
+ }
+ x[n] = y[n] / a[n][n];
+ for (i = 0; i <= n - 1; i++)
+ {
+ w = y[n - 1 - (i)];
+ for (j = n - i; j <= n; j++)
+ w = w - a[n - 1 - i][j] * x[j];
+ x[n - 1 - i] = w / a[n - 1 - (i)][n - 1-(i)];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int i, j, k;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -print-top-scop-only -analyze %s | FileCheck %s
+; XFAIL: *
+; ModuleID = './linear-algebra/solvers/ludcmp/ludcmp_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@x = common global [1025 x double] zeroinitializer, align 32
+@b = common global [1025 x double] zeroinitializer, align 32
+@a = common global [1025 x [1025 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@w = common global double 0.000000e+00
+@y = common global [1025 x double] zeroinitializer, align 32
+
+define void @scop_func(i64 %n) nounwind {
+entry:
+ store double 1.000000e+00, double* getelementptr inbounds ([1025 x double]* @b, i64 0, i64 0), align 32
+ %0 = icmp sgt i64 %n, 0
+ br i1 %0, label %bb.nph81, label %bb14
+
+bb.nph43: ; preds = %bb5.preheader
+ %1 = icmp sgt i64 %storemerge60, 0
+ br i1 %1, label %bb.nph43.split.us, label %bb4.preheader
+
+bb4.preheader: ; preds = %bb.nph43
+ br label %bb4
+
+bb.nph43.split.us: ; preds = %bb.nph43
+ br label %bb.nph35.us
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa63 = phi double [ %9, %bb2.us ]
+ %2 = load double* %scevgep110, align 8
+ %3 = fdiv double %.lcssa63, %2
+ store double %3, double* %scevgep148, align 8
+ %4 = icmp sgt i64 %storemerge5.us, %n
+ br i1 %4, label %bb11.loopexit.loopexit1, label %bb.nph35.us
+
+bb2.us: ; preds = %bb.nph35.us, %bb2.us
+ %5 = phi double [ %11, %bb.nph35.us ], [ %9, %bb2.us ]
+ %storemerge834.us = phi i64 [ 0, %bb.nph35.us ], [ %10, %bb2.us ]
+ %scevgep141 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %tmp96, i64 %storemerge834.us
+ %scevgep136 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %storemerge834.us, i64 %storemerge60
+ %6 = load double* %scevgep141, align 8
+ %7 = load double* %scevgep136, align 8
+ %8 = fmul double %6, %7
+ %9 = fsub double %5, %8
+ %10 = add nsw i64 %storemerge834.us, 1
+ %exitcond64 = icmp eq i64 %10, %storemerge60
+ br i1 %exitcond64, label %bb4.us, label %bb2.us
+
+bb.nph35.us: ; preds = %bb4.us, %bb.nph43.split.us
+ %indvar137 = phi i64 [ %tmp146, %bb4.us ], [ 0, %bb.nph43.split.us ]
+ %storemerge5.us = add i64 %tmp, %indvar137
+ %tmp93 = add i64 %indvar137, 1
+ %scevgep148 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %tmp93, i64 %tmp87
+ %tmp96 = add i64 %storemerge538, %indvar137
+ %tmp146 = add i64 %indvar137, 1
+ %11 = load double* %scevgep148, align 8
+ br label %bb2.us
+
+bb4: ; preds = %bb4.preheader, %bb4
+ %indvar152 = phi i64 [ %indvar.next153, %bb4 ], [ 0, %bb4.preheader ]
+ %tmp99 = add i64 %indvar152, 1
+ %scevgep157 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %tmp99, i64 %tmp87
+ %storemerge5 = add i64 %tmp, %indvar152
+ %12 = load double* %scevgep157, align 8
+ %13 = load double* %scevgep110, align 8
+ %14 = fdiv double %12, %13
+ store double %14, double* %scevgep157, align 8
+ %15 = icmp sgt i64 %storemerge5, %n
+ %indvar.next153 = add i64 %indvar152, 1
+ br i1 %15, label %bb11.loopexit.loopexit, label %bb4
+
+bb.nph56: ; preds = %bb11.loopexit
+ br i1 false, label %bb10.us.preheader, label %bb.nph47.preheader
+
+bb10.us.preheader: ; preds = %bb.nph56
+ br label %bb10.us
+
+bb.nph47.preheader: ; preds = %bb.nph56
+ br label %bb.nph47
+
+bb10.us: ; preds = %bb10.us.preheader, %bb10.us
+ %indvar122 = phi i64 [ %indvar.next123, %bb10.us ], [ 0, %bb10.us.preheader ]
+ %storemerge6.us = add i64 %tmp, %indvar122
+ %tmp89 = add i64 %tmp88, %indvar122
+ %scevgep128 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 1, i64 %tmp89
+ %16 = load double* %scevgep128, align 8
+ store double %16, double* %scevgep128, align 8
+ %17 = icmp sgt i64 %storemerge6.us, %n
+ %indvar.next123 = add i64 %indvar122, 1
+ br i1 %17, label %bb13.loopexit.loopexit2, label %bb10.us
+
+bb.nph47: ; preds = %bb.nph47.preheader, %bb10
+ %indvar162 = phi i64 [ %indvar.next163, %bb10 ], [ 0, %bb.nph47.preheader ]
+ %storemerge6 = add i64 %tmp, %indvar162
+ %tmp104 = add i64 %tmp88, %indvar162
+ %scevgep180 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 1, i64 %tmp104
+ %tmp107 = add i64 %storemerge538, %indvar162
+ %18 = load double* %scevgep180, align 8
+ br label %bb8
+
+bb8: ; preds = %bb8, %bb.nph47
+ %w.tmp.048 = phi double [ %18, %bb.nph47 ], [ %22, %bb8 ]
+ %storemerge746 = phi i64 [ 0, %bb.nph47 ], [ %23, %bb8 ]
+ %scevgep166 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %storemerge746, i64 %tmp107
+ %scevgep167 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %storemerge538, i64 %storemerge746
+ %19 = load double* %scevgep167, align 8
+ %20 = load double* %scevgep166, align 8
+ %21 = fmul double %19, %20
+ %22 = fsub double %w.tmp.048, %21
+ %23 = add nsw i64 %storemerge746, 1
+ %exitcond = icmp eq i64 %23, %smax
+ br i1 %exitcond, label %bb10, label %bb8
+
+bb10: ; preds = %bb8
+ %.lcssa40 = phi double [ %22, %bb8 ]
+ store double %.lcssa40, double* %scevgep180, align 8
+ %24 = icmp sgt i64 %storemerge6, %n
+ %indvar.next163 = add i64 %indvar162, 1
+ br i1 %24, label %bb13.loopexit.loopexit, label %bb.nph47
+
+bb11.loopexit.loopexit: ; preds = %bb4
+ %.lcssa57 = phi double [ %12, %bb4 ]
+ br label %bb11.loopexit
+
+bb11.loopexit.loopexit1: ; preds = %bb4.us
+ %.lcssa63.lcssa = phi double [ %.lcssa63, %bb4.us ]
+ br label %bb11.loopexit
+
+bb11.loopexit: ; preds = %bb11.loopexit.loopexit1, %bb11.loopexit.loopexit, %bb5.preheader
+ %w.tmp.082 = phi double [ %w.tmp.1, %bb5.preheader ], [ %.lcssa57, %bb11.loopexit.loopexit ], [ %.lcssa63.lcssa, %bb11.loopexit.loopexit1 ]
+ %25 = icmp sgt i64 %storemerge538, %n
+ br i1 %25, label %bb13.loopexit, label %bb.nph56
+
+bb13.loopexit.loopexit: ; preds = %bb10
+ %.lcssa40.lcssa = phi double [ %.lcssa40, %bb10 ]
+ br label %bb13.loopexit
+
+bb13.loopexit.loopexit2: ; preds = %bb10.us
+ %.lcssa77 = phi double [ %16, %bb10.us ]
+ br label %bb13.loopexit
+
+bb13.loopexit: ; preds = %bb13.loopexit.loopexit2, %bb13.loopexit.loopexit, %bb11.loopexit
+ %w.tmp.2 = phi double [ %w.tmp.082, %bb11.loopexit ], [ %.lcssa40.lcssa, %bb13.loopexit.loopexit ], [ %.lcssa77, %bb13.loopexit.loopexit2 ]
+ %indvar.next42 = add i64 %storemerge60, 1
+ %exitcond84 = icmp ne i64 %indvar.next42, %n
+ br i1 %exitcond84, label %bb5.preheader, label %bb13.bb14_crit_edge
+
+bb13.bb14_crit_edge: ; preds = %bb13.loopexit
+ %w.tmp.2.lcssa = phi double [ %w.tmp.2, %bb13.loopexit ]
+ store double %w.tmp.2.lcssa, double* @w
+ br label %bb14
+
+bb.nph81: ; preds = %entry
+ %w.promoted = load double* @w
+ br label %bb5.preheader
+
+bb5.preheader: ; preds = %bb.nph81, %bb13.loopexit
+ %storemerge60 = phi i64 [ 0, %bb.nph81 ], [ %indvar.next42, %bb13.loopexit ]
+ %w.tmp.1 = phi double [ %w.promoted, %bb.nph81 ], [ %w.tmp.2, %bb13.loopexit ]
+ %tmp = add i64 %storemerge60, 2
+ %tmp87 = mul i64 %storemerge60, 1026
+ %tmp88 = add i64 %tmp87, 1
+ %storemerge538 = add i64 %storemerge60, 1
+ %scevgep110 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 0, i64 %tmp87
+ %tmp44 = icmp sgt i64 %storemerge538, 1
+ %smax = select i1 %tmp44, i64 %storemerge538, i64 1
+ %26 = icmp sgt i64 %storemerge538, %n
+ br i1 %26, label %bb11.loopexit, label %bb.nph43
+
+bb14: ; preds = %bb13.bb14_crit_edge, %entry
+ store double 1.000000e+00, double* getelementptr inbounds ([1025 x double]* @y, i64 0, i64 0), align 32
+ %27 = icmp slt i64 %n, 1
+ br i1 %27, label %bb20, label %bb15.preheader
+
+bb15.preheader: ; preds = %bb14
+ br label %bb15
+
+bb15: ; preds = %bb15.preheader, %bb18
+ %indvar111 = phi i64 [ %28, %bb18 ], [ 0, %bb15.preheader ]
+ %storemerge126 = add i64 %indvar111, 1
+ %tmp117 = add i64 %indvar111, 2
+ %scevgep119 = getelementptr [1025 x double]* @b, i64 0, i64 %storemerge126
+ %scevgep118 = getelementptr [1025 x double]* @y, i64 0, i64 %storemerge126
+ %28 = add i64 %indvar111, 1
+ %29 = load double* %scevgep119, align 8
+ %30 = icmp sgt i64 %storemerge126, 0
+ br i1 %30, label %bb16.preheader, label %bb18
+
+bb16.preheader: ; preds = %bb15
+ br label %bb16
+
+bb16: ; preds = %bb16.preheader, %bb16
+ %31 = phi double [ %35, %bb16 ], [ %29, %bb16.preheader ]
+ %storemerge423 = phi i64 [ %36, %bb16 ], [ 0, %bb16.preheader ]
+ %scevgep114 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %storemerge126, i64 %storemerge423
+ %scevgep113 = getelementptr [1025 x double]* @y, i64 0, i64 %storemerge423
+ %32 = load double* %scevgep114, align 8
+ %33 = load double* %scevgep113, align 8
+ %34 = fmul double %32, %33
+ %35 = fsub double %31, %34
+ %36 = add nsw i64 %storemerge423, 1
+ %exitcond4 = icmp eq i64 %36, %storemerge126
+ br i1 %exitcond4, label %bb18.loopexit, label %bb16
+
+bb18.loopexit: ; preds = %bb16
+ %.lcssa = phi double [ %35, %bb16 ]
+ br label %bb18
+
+bb18: ; preds = %bb18.loopexit, %bb15
+ %w.tmp.032 = phi double [ %29, %bb15 ], [ %.lcssa, %bb18.loopexit ]
+ store double %w.tmp.032, double* %scevgep118, align 8
+ %37 = icmp sgt i64 %tmp117, %n
+ br i1 %37, label %bb19.bb20_crit_edge, label %bb15
+
+bb19.bb20_crit_edge: ; preds = %bb18
+ %w.tmp.032.lcssa = phi double [ %w.tmp.032, %bb18 ]
+ store double %w.tmp.032.lcssa, double* @w
+ br label %bb20
+
+bb20: ; preds = %bb19.bb20_crit_edge, %bb14
+ %38 = getelementptr inbounds [1025 x double]* @y, i64 0, i64 %n
+ %39 = load double* %38, align 8
+ %40 = getelementptr inbounds [1025 x [1025 x double]]* @a, i64 0, i64 %n, i64 %n
+ %41 = load double* %40, align 8
+ %42 = fdiv double %39, %41
+ %43 = getelementptr inbounds [1025 x double]* @x, i64 0, i64 %n
+ store double %42, double* %43, align 8
+ %44 = add nsw i64 %n, -1
+ %45 = icmp slt i64 %44, 0
+ br i1 %45, label %return, label %bb.nph19
+
+bb.nph19: ; preds = %bb20
+ %tmp86 = mul i64 %n, 1026
+ %tmp90 = add i64 %n, 1
+ %tmp94 = add i64 %tmp86, -1
+ %tmp34 = add i64 %n, -1
+ br label %bb21
+
+bb21: ; preds = %bb24, %bb.nph19
+ %storemerge211 = phi i64 [ 0, %bb.nph19 ], [ %46, %bb24 ]
+ %tmp23 = mul i64 %storemerge211, -1026
+ %tmp24 = add i64 %tmp86, %tmp23
+ %tmp27 = mul i64 %storemerge211, -1
+ %tmp106 = add i64 %n, %tmp27
+ %tmp31 = add i64 %tmp90, %tmp27
+ %tmp109 = add i64 %storemerge211, 1
+ %tmp35 = add i64 %tmp34, %tmp27
+ %scevgep100 = getelementptr [1025 x double]* @y, i64 0, i64 %tmp35
+ %scevgep99 = getelementptr [1025 x double]* @x, i64 0, i64 %tmp35
+ %tmp38 = add i64 %tmp94, %tmp23
+ %scevgep96 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 -1, i64 %tmp38
+ %46 = add i64 %storemerge211, 1
+ %47 = load double* %scevgep100, align 8
+ %48 = icmp sgt i64 %tmp106, %n
+ br i1 %48, label %bb24, label %bb22.preheader
+
+bb22.preheader: ; preds = %bb21
+ br label %bb22
+
+bb22: ; preds = %bb22.preheader, %bb22
+ %indvar = phi i64 [ %indvar.next, %bb22 ], [ 0, %bb22.preheader ]
+ %w.tmp.0 = phi double [ %52, %bb22 ], [ %47, %bb22.preheader ]
+ %tmp25 = add i64 %tmp24, %indvar
+ %scevgep89 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 -1, i64 %tmp25
+ %tmp29 = add i64 %tmp106, %indvar
+ %scevgep = getelementptr [1025 x double]* @x, i64 0, i64 %tmp29
+ %tmp92 = add i64 %tmp31, %indvar
+ %49 = load double* %scevgep89, align 8
+ %50 = load double* %scevgep, align 8
+ %51 = fmul double %49, %50
+ %52 = fsub double %w.tmp.0, %51
+ %53 = icmp sgt i64 %tmp92, %n
+ %indvar.next = add i64 %indvar, 1
+ br i1 %53, label %bb24.loopexit, label %bb22
+
+bb24.loopexit: ; preds = %bb22
+ %.lcssa12 = phi double [ %52, %bb22 ]
+ br label %bb24
+
+bb24: ; preds = %bb24.loopexit, %bb21
+ %w.tmp.021 = phi double [ %47, %bb21 ], [ %.lcssa12, %bb24.loopexit ]
+ %54 = load double* %scevgep96, align 8
+ %55 = fdiv double %w.tmp.021, %54
+ store double %55, double* %scevgep99, align 8
+ %56 = icmp slt i64 %44, %tmp109
+ br i1 %56, label %bb25.return_crit_edge, label %bb21
+
+bb25.return_crit_edge: ; preds = %bb24
+ %w.tmp.021.lcssa = phi double [ %w.tmp.021, %bb24 ]
+ store double %w.tmp.021.lcssa, double* @w
+ ret void
+
+return: ; preds = %bb20
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -polly-cloog -analyze %s | FileCheck %s
+; region-simplify make polly fail to detect the canonical induction variable.
+; XFAIL:*
+
+; ModuleID = './linear-algebra/solvers/ludcmp/ludcmp_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@x = common global [1025 x double] zeroinitializer, align 32
+@b = common global [1025 x double] zeroinitializer, align 32
+@a = common global [1025 x [1025 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+@w = common global double 0.000000e+00
+@y = common global [1025 x double] zeroinitializer, align 32
+
+define void @scop_func() nounwind {
+bb.nph76:
+ store double 1.000000e+00, double* getelementptr inbounds ([1025 x double]* @b, i64 0, i64 0), align 32
+ %w.promoted = load double* @w
+ br label %bb5.preheader
+
+bb.nph38: ; preds = %bb5.preheader
+ %0 = icmp sgt i64 %storemerge55, 0
+ br i1 %0, label %bb.nph38.split.us, label %bb4.preheader
+
+bb4.preheader: ; preds = %bb.nph38
+ br label %bb4
+
+bb.nph38.split.us: ; preds = %bb.nph38
+ br label %bb.nph30.us
+
+bb4.us: ; preds = %bb2.us
+ %.lcssa62 = phi double [ %7, %bb2.us ]
+ %1 = load double* %scevgep109, align 8
+ %2 = fdiv double %.lcssa62, %1
+ store double %2, double* %scevgep141, align 8
+ %exitcond70 = icmp eq i64 %tmp139, %tmp46
+ br i1 %exitcond70, label %bb11.loopexit.loopexit1, label %bb.nph30.us
+
+bb2.us: ; preds = %bb.nph30.us, %bb2.us
+ %3 = phi double [ %9, %bb.nph30.us ], [ %7, %bb2.us ]
+ %storemerge829.us = phi i64 [ 0, %bb.nph30.us ], [ %8, %bb2.us ]
+ %scevgep134 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %tmp95, i64 %storemerge829.us
+ %scevgep129 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %storemerge829.us, i64 %storemerge55
+ %4 = load double* %scevgep134, align 8
+ %5 = load double* %scevgep129, align 8
+ %6 = fmul double %4, %5
+ %7 = fsub double %3, %6
+ %8 = add nsw i64 %storemerge829.us, 1
+ %exitcond63 = icmp eq i64 %8, %storemerge55
+ br i1 %exitcond63, label %bb4.us, label %bb2.us
+
+bb.nph30.us: ; preds = %bb4.us, %bb.nph38.split.us
+ %indvar130 = phi i64 [ %tmp139, %bb4.us ], [ 0, %bb.nph38.split.us ]
+ %tmp92 = add i64 %indvar130, 1
+ %scevgep141 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %tmp92, i64 %tmp86
+ %tmp95 = add i64 %storemerge533, %indvar130
+ %tmp139 = add i64 %indvar130, 1
+ %9 = load double* %scevgep141, align 8
+ br label %bb2.us
+
+bb4: ; preds = %bb4.preheader, %bb4
+ %indvar145 = phi i64 [ %indvar.next146, %bb4 ], [ 0, %bb4.preheader ]
+ %tmp99 = add i64 %indvar145, 1
+ %scevgep150 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %tmp99, i64 %tmp86
+ %10 = load double* %scevgep150, align 8
+ %11 = load double* %scevgep109, align 8
+ %12 = fdiv double %10, %11
+ store double %12, double* %scevgep150, align 8
+ %indvar.next146 = add i64 %indvar145, 1
+ %exitcond58 = icmp eq i64 %indvar.next146, %tmp46
+ br i1 %exitcond58, label %bb11.loopexit.loopexit, label %bb4
+
+bb.nph51: ; preds = %bb11.loopexit
+ br i1 false, label %bb10.us.preheader, label %bb.nph42.preheader
+
+bb10.us.preheader: ; preds = %bb.nph51
+ br label %bb10.us
+
+bb.nph42.preheader: ; preds = %bb.nph51
+ br label %bb.nph42
+
+bb10.us: ; preds = %bb10.us.preheader, %bb10.us
+ %indvar114 = phi i64 [ %indvar.next115, %bb10.us ], [ 0, %bb10.us.preheader ]
+ %tmp88 = add i64 %tmp87, %indvar114
+ %scevgep121 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 1, i64 %tmp88
+ %13 = load double* %scevgep121, align 8
+ store double %13, double* %scevgep121, align 8
+ %indvar.next115 = add i64 %indvar114, 1
+ %exitcond80 = icmp eq i64 %indvar.next115, %tmp46
+ br i1 %exitcond80, label %bb13.loopexit.loopexit2, label %bb10.us
+
+bb.nph42: ; preds = %bb.nph42.preheader, %bb10
+ %indvar155 = phi i64 [ %indvar.next156, %bb10 ], [ 0, %bb.nph42.preheader ]
+ %tmp102 = add i64 %tmp87, %indvar155
+ %scevgep173 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 1, i64 %tmp102
+ %tmp104 = add i64 %storemerge533, %indvar155
+ %14 = load double* %scevgep173, align 8
+ br label %bb8
+
+bb8: ; preds = %bb8, %bb.nph42
+ %w.tmp.043 = phi double [ %14, %bb.nph42 ], [ %18, %bb8 ]
+ %storemerge741 = phi i64 [ 0, %bb.nph42 ], [ %19, %bb8 ]
+ %scevgep159 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %storemerge741, i64 %tmp104
+ %scevgep160 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %storemerge533, i64 %storemerge741
+ %15 = load double* %scevgep160, align 8
+ %16 = load double* %scevgep159, align 8
+ %17 = fmul double %15, %16
+ %18 = fsub double %w.tmp.043, %17
+ %19 = add nsw i64 %storemerge741, 1
+ %exitcond41 = icmp eq i64 %19, %storemerge533
+ br i1 %exitcond41, label %bb10, label %bb8
+
+bb10: ; preds = %bb8
+ %.lcssa37 = phi double [ %18, %bb8 ]
+ store double %.lcssa37, double* %scevgep173, align 8
+ %indvar.next156 = add i64 %indvar155, 1
+ %exitcond47 = icmp eq i64 %indvar.next156, %tmp46
+ br i1 %exitcond47, label %bb13.loopexit.loopexit, label %bb.nph42
+
+bb11.loopexit.loopexit: ; preds = %bb4
+ %.lcssa55 = phi double [ %10, %bb4 ]
+ br label %bb11.loopexit
+
+bb11.loopexit.loopexit1: ; preds = %bb4.us
+ %.lcssa62.lcssa = phi double [ %.lcssa62, %bb4.us ]
+ br label %bb11.loopexit
+
+bb11.loopexit: ; preds = %bb11.loopexit.loopexit1, %bb11.loopexit.loopexit, %bb5.preheader
+ %w.tmp.077 = phi double [ %w.tmp.1, %bb5.preheader ], [ %.lcssa55, %bb11.loopexit.loopexit ], [ %.lcssa62.lcssa, %bb11.loopexit.loopexit1 ]
+ br i1 false, label %bb13.loopexit, label %bb.nph51
+
+bb13.loopexit.loopexit: ; preds = %bb10
+ %.lcssa37.lcssa = phi double [ %.lcssa37, %bb10 ]
+ br label %bb13.loopexit
+
+bb13.loopexit.loopexit2: ; preds = %bb10.us
+ %.lcssa77 = phi double [ %13, %bb10.us ]
+ br label %bb13.loopexit
+
+bb13.loopexit: ; preds = %bb13.loopexit.loopexit2, %bb13.loopexit.loopexit, %bb11.loopexit
+ %w.tmp.2 = phi double [ %w.tmp.077, %bb11.loopexit ], [ %.lcssa37.lcssa, %bb13.loopexit.loopexit ], [ %.lcssa77, %bb13.loopexit.loopexit2 ]
+ %indvar.next39 = add i64 %storemerge55, 1
+ %exitcond85 = icmp ne i64 %indvar.next39, 1024
+ br i1 %exitcond85, label %bb5.preheader, label %bb.nph25
+
+bb5.preheader: ; preds = %bb13.loopexit, %bb.nph76
+ %storemerge55 = phi i64 [ %indvar.next39, %bb13.loopexit ], [ 0, %bb.nph76 ]
+ %w.tmp.1 = phi double [ %w.promoted, %bb.nph76 ], [ %w.tmp.2, %bb13.loopexit ]
+ %tmp86 = mul i64 %storemerge55, 1026
+ %tmp87 = add i64 %tmp86, 1
+ %tmp90 = mul i64 %storemerge55, -1
+ %tmp46 = add i64 %tmp90, 1024
+ %storemerge533 = add i64 %storemerge55, 1
+ %scevgep109 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 0, i64 %tmp86
+ br i1 false, label %bb11.loopexit, label %bb.nph38
+
+bb.nph25: ; preds = %bb13.loopexit
+ %w.tmp.2.lcssa = phi double [ %w.tmp.2, %bb13.loopexit ]
+ store double %w.tmp.2.lcssa, double* @w
+ store double 1.000000e+00, double* getelementptr inbounds ([1025 x double]* @y, i64 0, i64 0), align 32
+ br label %bb.nph19
+
+bb.nph19: ; preds = %bb18, %bb.nph25
+ %indvar102 = phi i64 [ 0, %bb.nph25 ], [ %tmp, %bb18 ]
+ %tmp29 = add i64 %indvar102, 1
+ %scevgep111 = getelementptr [1025 x double]* @b, i64 0, i64 %tmp29
+ %scevgep110 = getelementptr [1025 x double]* @y, i64 0, i64 %tmp29
+ %tmp = add i64 %indvar102, 1
+ %20 = load double* %scevgep111, align 8
+ br label %bb16
+
+bb16: ; preds = %bb16, %bb.nph19
+ %21 = phi double [ %20, %bb.nph19 ], [ %25, %bb16 ]
+ %storemerge418 = phi i64 [ 0, %bb.nph19 ], [ %26, %bb16 ]
+ %scevgep106 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 %tmp29, i64 %storemerge418
+ %scevgep105 = getelementptr [1025 x double]* @y, i64 0, i64 %storemerge418
+ %22 = load double* %scevgep106, align 8
+ %23 = load double* %scevgep105, align 8
+ %24 = fmul double %22, %23
+ %25 = fsub double %21, %24
+ %26 = add nsw i64 %storemerge418, 1
+ %exitcond = icmp eq i64 %26, %tmp29
+ br i1 %exitcond, label %bb18, label %bb16
+
+bb18: ; preds = %bb16
+ %.lcssa28 = phi double [ %25, %bb16 ]
+ store double %.lcssa28, double* %scevgep110, align 8
+ %exitcond32 = icmp eq i64 %tmp, 1024
+ br i1 %exitcond32, label %bb.nph14, label %bb.nph19
+
+bb.nph14: ; preds = %bb18
+ %.lcssa28.lcssa = phi double [ %.lcssa28, %bb18 ]
+ store double %.lcssa28.lcssa, double* @w
+ %27 = load double* getelementptr inbounds ([1025 x double]* @y, i64 0, i64 1024), align 32
+ %28 = load double* getelementptr inbounds ([1025 x [1025 x double]]* @a, i64 0, i64 1024, i64 1024), align 32
+ %29 = fdiv double %27, %28
+ store double %29, double* getelementptr inbounds ([1025 x double]* @x, i64 0, i64 1024), align 32
+ br label %bb.nph
+
+bb.nph: ; preds = %bb24, %bb.nph14
+ %storemerge210 = phi i64 [ 0, %bb.nph14 ], [ %37, %bb24 ]
+ %tmp14 = mul i64 %storemerge210, -1026
+ %tmp15 = add i64 %tmp14, 1024
+ %tmp18 = mul i64 %storemerge210, -1
+ %tmp19 = add i64 %tmp18, 1024
+ %tmp3 = add i64 %storemerge210, 1
+ %tmp23 = add i64 %tmp18, 1023
+ %scevgep100 = getelementptr [1025 x double]* @y, i64 0, i64 %tmp23
+ %scevgep99 = getelementptr [1025 x double]* @x, i64 0, i64 %tmp23
+ %tmp26 = add i64 %tmp14, 1023
+ %scevgep97 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 1023, i64 %tmp26
+ %30 = load double* %scevgep100, align 8
+ br label %bb22
+
+bb22: ; preds = %bb22, %bb.nph
+ %indvar = phi i64 [ 0, %bb.nph ], [ %indvar.next, %bb22 ]
+ %w.tmp.0 = phi double [ %30, %bb.nph ], [ %34, %bb22 ]
+ %tmp16 = add i64 %tmp15, %indvar
+ %scevgep83 = getelementptr [1025 x [1025 x double]]* @a, i64 0, i64 1023, i64 %tmp16
+ %tmp20 = add i64 %tmp19, %indvar
+ %scevgep = getelementptr [1025 x double]* @x, i64 0, i64 %tmp20
+ %31 = load double* %scevgep83, align 8
+ %32 = load double* %scevgep, align 8
+ %33 = fmul double %31, %32
+ %34 = fsub double %w.tmp.0, %33
+ %indvar.next = add i64 %indvar, 1
+ %exitcond4 = icmp eq i64 %indvar.next, %tmp3
+ br i1 %exitcond4, label %bb24, label %bb22
+
+bb24: ; preds = %bb22
+ %.lcssa = phi double [ %34, %bb22 ]
+ %35 = load double* %scevgep97, align 8
+ %36 = fdiv double %.lcssa, %35
+ store double %36, double* %scevgep99, align 8
+ %37 = add nsw i64 %storemerge210, 1
+ %exitcond13 = icmp eq i64 %37, 1024
+ br i1 %exitcond13, label %return, label %bb.nph
+
+return: ; preds = %bb24
+ %.lcssa.lcssa = phi double [ %.lcssa, %bb24 ]
+ store double %.lcssa.lcssa, double* @w
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
--- /dev/null
+#!/bin/sh
+
+if [ $# -ne 3 ]; then
+ echo "Usage: compile.sh <compiler command> <input file> <output file>";
+ exit 1;
+fi;
+
+COMPILER_COMMAND="$1";
+INPUT_FILE="$2";
+OUTPUT_FILE="$3";
+
+$COMPILER_COMMAND -DPOLYBENCH_TIME -lm -I utilities utilities/instrument.c $INPUT_FILE -o $OUTPUT_FILE
+
+exit 0;
--- /dev/null
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Usage: runall.sh <machine-acronym>";
+ exit 1;
+fi;
+
+## Default value for the compilation line.
+if [ -z "$COMPILER_COMMAND" ]; then
+ COMPILER_COMMAND="gcc -O3 -fopenmp";
+fi;
+
+echo "Machine: $1";
+for i in `ls`; do
+ if [ -d "$i" ] && [ -f "$i/$i.c" ]; then
+ echo "Testing benchmark $i";
+ rm -f data/$1-$i.dat
+ if [ -f "$i/compiler.opts" ]; then
+ read comp_opts < $i/compiler.opts;
+ COMPILER_F_COMMAND="$COMPILER_COMMAND $comp_opts";
+ else
+ COMPILER_F_COMMAND="$COMPILER_COMMAND";
+ fi;
+ for j in `find $i -name "*.c"`; do
+ echo "Testing $j";
+ scripts/compile.sh "$COMPILER_F_COMMAND" "$j" "transfo" > /dev/null;
+ if [ $? -ne 0 ]; then
+ echo "Problem when compiling $j";
+ else
+ val=`./transfo`;
+ if [ $? -ne 0 ]; then
+ echo "Problem when executing $j";
+ else
+ echo "execution time: $val";
+ echo "$j $val" >> data/$1-$i.dat
+ fi;
+ fi;
+ done;
+ fi;
+done;
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+/* Default problem size. */
+#ifndef TSTEPS
+# define TSTEPS 10
+#endif
+#ifndef N
+# define N 1024
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE X[N][N];
+DATA_TYPE A[N][N];
+DATA_TYPE B[N][N];
+#else
+DATA_TYPE** X = (DATA_TYPE**)malloc(MAXGRID * sizeof(DATA_TYPE*));
+DATA_TYPE** A = (DATA_TYPE**)malloc(MAXGRID * sizeof(DATA_TYPE*));
+DATA_TYPE** B = (DATA_TYPE**)malloc(MAXGRID * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ {
+ X[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ A[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ B[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ }
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ {
+ X[i][j] = ((DATA_TYPE) i*j + 1) / N;
+ A[i][j] = ((DATA_TYPE) i*j + 2) / N;
+ B[i][j] = ((DATA_TYPE) i*j + 3) / N;
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, A[i][j]);
+ if ((i * N + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long n = N;
+#else
+void scop_func(long n) {
+#endif
+ long t, i1, i2;
+ long tsteps = TSTEPS;
+#pragma scop
+#pragma live-out X
+
+ for (t = 0; t < tsteps; t++)
+ {
+ for (i1 = 0; i1 < n; i1++)
+ for (i2 = 1; i2 < n; i2++)
+ {
+ X[i1][i2] = X[i1][i2] - X[i1][i2-1] * A[i1][i2] / B[i1][i2-1];
+ B[i1][i2] = B[i1][i2] - A[i1][i2] * A[i1][i2] / B[i1][i2-1];
+ }
+
+ for (i1 = 0; i1 < n; i1++)
+ X[i1][n-1] = X[i1][n-1] / B[i1][n-1];
+
+ for (i1 = 0; i1 < n; i1++)
+ for (i2 = 0; i2 < n-2; i2++)
+ X[i1][n-i2-2] = (X[i1][n-2-i2] - X[i1][n-2-i2-1] * A[i1][n-i2-3]) / B[i1][n-3-i2];
+
+ for (i1 = 1; i1 < n; i1++)
+ for (i2 = 0; i2 < n; i2++) {
+ X[i1][i2] = X[i1][i2] - X[i1-1][i2] * A[i1][i2] / B[i1-1][i2];
+ B[i1][i2] = B[i1][i2] - A[i1][i2] * A[i1][i2] / B[i1-1][i2];
+ }
+
+ for (i2 = 0; i2 < n; i2++)
+ X[n-1][i2] = X[n-1][i2] / B[n-1][i2];
+
+ for (i1 = 0; i1 < n-2; i1++)
+ for (i2 = 0; i2 < n; i2++)
+ X[n-2-i1][i2] = (X[n-2-i1][i2] - X[n-i1-3][i2] * A[n-3-i1][i2]) / B[n-2-i1][i2];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int t, i1, i2;
+ int n = N;
+ int tsteps = TSTEPS;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -print-top-scop-only -analyze %s | FileCheck %s
+; XFAIL: *
+; ModuleID = './stencils/adi/adi_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@X = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@B = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func(i64 %n) nounwind {
+bb.nph81:
+ %0 = icmp sgt i64 %n, 0
+ %1 = icmp sgt i64 %n, 1
+ %2 = add nsw i64 %n, -2
+ %3 = icmp sgt i64 %2, 0
+ %4 = add nsw i64 %n, -3
+ %tmp = add i64 %n, -1
+ br label %bb5.preheader
+
+bb.nph: ; preds = %bb.nph.preheader, %bb4
+ %storemerge112 = phi i64 [ %16, %bb4 ], [ 0, %bb.nph.preheader ]
+ %scevgep86.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge112, i64 0
+ %scevgep85.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge112, i64 0
+ %.pre = load double* %scevgep85.phi.trans.insert, align 32
+ %.pre149 = load double* %scevgep86.phi.trans.insert, align 32
+ br label %bb2
+
+bb2: ; preds = %bb2, %bb.nph
+ %5 = phi double [ %.pre149, %bb.nph ], [ %15, %bb2 ]
+ %6 = phi double [ %.pre, %bb.nph ], [ %11, %bb2 ]
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp90, %bb2 ]
+ %tmp42 = add i64 %indvar, 1
+ %scevgep84 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge112, i64 %tmp42
+ %scevgep83 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %storemerge112, i64 %tmp42
+ %scevgep = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge112, i64 %tmp42
+ %tmp90 = add i64 %indvar, 1
+ %7 = load double* %scevgep, align 8
+ %8 = load double* %scevgep83, align 8
+ %9 = fmul double %6, %8
+ %10 = fdiv double %9, %5
+ %11 = fsub double %7, %10
+ store double %11, double* %scevgep, align 8
+ %12 = load double* %scevgep84, align 8
+ %13 = fmul double %8, %8
+ %14 = fdiv double %13, %5
+ %15 = fsub double %12, %14
+ store double %15, double* %scevgep84, align 8
+ %exitcond37 = icmp eq i64 %tmp90, %tmp
+ br i1 %exitcond37, label %bb4, label %bb2
+
+bb4: ; preds = %bb2
+ %16 = add nsw i64 %storemerge112, 1
+ %exitcond = icmp eq i64 %16, %n
+ br i1 %exitcond, label %bb8.loopexit.loopexit, label %bb.nph
+
+bb.nph16: ; preds = %bb5.preheader
+ br i1 %1, label %bb.nph.preheader, label %bb8.loopexit
+
+bb.nph.preheader: ; preds = %bb.nph16
+ br label %bb.nph
+
+bb7: ; preds = %bb7.preheader, %bb7
+ %storemerge217 = phi i64 [ %20, %bb7 ], [ 0, %bb7.preheader ]
+ %scevgep96 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge217, i64 %tmp
+ %scevgep95 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge217, i64 %tmp
+ %17 = load double* %scevgep95, align 8
+ %18 = load double* %scevgep96, align 8
+ %19 = fdiv double %17, %18
+ store double %19, double* %scevgep95, align 8
+ %20 = add nsw i64 %storemerge217, 1
+ %exitcond18 = icmp eq i64 %20, %n
+ br i1 %exitcond18, label %bb14.loopexit, label %bb7
+
+bb8.loopexit.loopexit: ; preds = %bb4
+ br label %bb8.loopexit
+
+bb8.loopexit: ; preds = %bb8.loopexit.loopexit, %bb.nph16
+ br i1 %0, label %bb7.preheader, label %bb20.loopexit
+
+bb7.preheader: ; preds = %bb8.loopexit
+ br label %bb7
+
+bb11: ; preds = %bb12.preheader, %bb11
+ %storemerge920 = phi i64 [ %28, %bb11 ], [ 0, %bb12.preheader ]
+ %tmp30 = mul i64 %storemerge920, -1
+ %tmp31 = add i64 %4, %tmp30
+ %scevgep104 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge323, i64 %tmp31
+ %scevgep103 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %storemerge323, i64 %tmp31
+ %scevgep102 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge323, i64 %tmp31
+ %tmp35 = add i64 %2, %tmp30
+ %scevgep100 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge323, i64 %tmp35
+ %21 = load double* %scevgep100, align 8
+ %22 = load double* %scevgep102, align 8
+ %23 = load double* %scevgep103, align 8
+ %24 = fmul double %22, %23
+ %25 = fsub double %21, %24
+ %26 = load double* %scevgep104, align 8
+ %27 = fdiv double %25, %26
+ store double %27, double* %scevgep100, align 8
+ %28 = add nsw i64 %storemerge920, 1
+ %exitcond21 = icmp eq i64 %28, %2
+ br i1 %exitcond21, label %bb13, label %bb11
+
+bb13: ; preds = %bb11
+ %29 = add nsw i64 %storemerge323, 1
+ %exitcond29 = icmp eq i64 %29, %n
+ br i1 %exitcond29, label %bb20.loopexit.loopexit, label %bb12.preheader
+
+bb14.loopexit: ; preds = %bb7
+ %.not = xor i1 %0, true
+ %.not150 = xor i1 %3, true
+ %brmerge = or i1 %.not, %.not150
+ br i1 %brmerge, label %bb20.loopexit, label %bb12.preheader.preheader
+
+bb12.preheader.preheader: ; preds = %bb14.loopexit
+ br label %bb12.preheader
+
+bb12.preheader: ; preds = %bb12.preheader.preheader, %bb13
+ %storemerge323 = phi i64 [ %29, %bb13 ], [ 0, %bb12.preheader.preheader ]
+ br label %bb11
+
+bb17: ; preds = %bb18.preheader, %bb17
+ %storemerge828 = phi i64 [ %41, %bb17 ], [ 0, %bb18.preheader ]
+ %scevgep119 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %indvar114, i64 %storemerge828
+ %scevgep118 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %indvar114, i64 %storemerge828
+ %scevgep121 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp11, i64 %storemerge828
+ %scevgep120 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp11, i64 %storemerge828
+ %scevgep117 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %tmp11, i64 %storemerge828
+ %30 = load double* %scevgep117, align 8
+ %31 = load double* %scevgep118, align 8
+ %32 = load double* %scevgep120, align 8
+ %33 = fmul double %31, %32
+ %34 = load double* %scevgep119, align 8
+ %35 = fdiv double %33, %34
+ %36 = fsub double %30, %35
+ store double %36, double* %scevgep117, align 8
+ %37 = load double* %scevgep121, align 8
+ %38 = fmul double %32, %32
+ %39 = fdiv double %38, %34
+ %40 = fsub double %37, %39
+ store double %40, double* %scevgep121, align 8
+ %41 = add nsw i64 %storemerge828, 1
+ %exitcond1 = icmp eq i64 %41, %n
+ br i1 %exitcond1, label %bb19, label %bb17
+
+bb19: ; preds = %bb17
+ %tmp125 = add i64 %indvar114, 1
+ %exitcond8 = icmp eq i64 %tmp125, %tmp
+ br i1 %exitcond8, label %bb23.loopexit.loopexit, label %bb18.preheader
+
+bb20.loopexit.loopexit: ; preds = %bb13
+ br label %bb20.loopexit
+
+bb20.loopexit: ; preds = %bb20.loopexit.loopexit, %bb5.preheader, %bb14.loopexit, %bb8.loopexit
+ br i1 %1, label %bb.nph34, label %bb23.loopexit
+
+bb.nph34: ; preds = %bb20.loopexit
+ br i1 %0, label %bb18.preheader.preheader, label %bb29.loopexit
+
+bb18.preheader.preheader: ; preds = %bb.nph34
+ br label %bb18.preheader
+
+bb18.preheader: ; preds = %bb18.preheader.preheader, %bb19
+ %indvar114 = phi i64 [ %tmp125, %bb19 ], [ 0, %bb18.preheader.preheader ]
+ %tmp11 = add i64 %indvar114, 1
+ br label %bb17
+
+bb22: ; preds = %bb22.preheader, %bb22
+ %storemerge535 = phi i64 [ %45, %bb22 ], [ 0, %bb22.preheader ]
+ %scevgep131 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp, i64 %storemerge535
+ %scevgep130 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %tmp, i64 %storemerge535
+ %42 = load double* %scevgep130, align 8
+ %43 = load double* %scevgep131, align 8
+ %44 = fdiv double %42, %43
+ store double %44, double* %scevgep130, align 8
+ %45 = add nsw i64 %storemerge535, 1
+ %exitcond15 = icmp eq i64 %45, %n
+ br i1 %exitcond15, label %bb29.loopexit.loopexit, label %bb22
+
+bb23.loopexit.loopexit: ; preds = %bb19
+ br label %bb23.loopexit
+
+bb23.loopexit: ; preds = %bb23.loopexit.loopexit, %bb20.loopexit
+ br i1 %0, label %bb22.preheader, label %bb29.loopexit
+
+bb22.preheader: ; preds = %bb23.loopexit
+ br label %bb22
+
+bb26: ; preds = %bb27.preheader, %bb26
+ %storemerge737 = phi i64 [ %53, %bb26 ], [ 0, %bb27.preheader ]
+ %scevgep138 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp58, i64 %storemerge737
+ %scevgep137 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %tmp58, i64 %storemerge737
+ %scevgep139 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp61, i64 %storemerge737
+ %scevgep135 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %tmp61, i64 %storemerge737
+ %46 = load double* %scevgep135, align 8
+ %47 = load double* %scevgep137, align 8
+ %48 = load double* %scevgep138, align 8
+ %49 = fmul double %47, %48
+ %50 = fsub double %46, %49
+ %51 = load double* %scevgep139, align 8
+ %52 = fdiv double %50, %51
+ store double %52, double* %scevgep135, align 8
+ %53 = add nsw i64 %storemerge737, 1
+ %exitcond48 = icmp eq i64 %53, %n
+ br i1 %exitcond48, label %bb28, label %bb26
+
+bb28: ; preds = %bb26
+ %54 = add nsw i64 %storemerge640, 1
+ %exitcond56 = icmp eq i64 %54, %2
+ br i1 %exitcond56, label %bb30.loopexit, label %bb27.preheader
+
+bb29.loopexit.loopexit: ; preds = %bb22
+ br label %bb29.loopexit
+
+bb29.loopexit: ; preds = %bb29.loopexit.loopexit, %bb23.loopexit, %bb.nph34
+ %.not151 = xor i1 %3, true
+ %.not152 = xor i1 %0, true
+ %brmerge153 = or i1 %.not151, %.not152
+ br i1 %brmerge153, label %bb30, label %bb27.preheader.preheader
+
+bb27.preheader.preheader: ; preds = %bb29.loopexit
+ br label %bb27.preheader
+
+bb27.preheader: ; preds = %bb27.preheader.preheader, %bb28
+ %storemerge640 = phi i64 [ %54, %bb28 ], [ 0, %bb27.preheader.preheader ]
+ %tmp57 = mul i64 %storemerge640, -1
+ %tmp58 = add i64 %4, %tmp57
+ %tmp61 = add i64 %2, %tmp57
+ br label %bb26
+
+bb30.loopexit: ; preds = %bb28
+ br label %bb30
+
+bb30: ; preds = %bb30.loopexit, %bb29.loopexit
+ %55 = add nsw i64 %storemerge46, 1
+ %exitcond64 = icmp eq i64 %55, 10
+ br i1 %exitcond64, label %return, label %bb5.preheader
+
+bb5.preheader: ; preds = %bb30, %bb.nph81
+ %storemerge46 = phi i64 [ 0, %bb.nph81 ], [ %55, %bb30 ]
+ br i1 %0, label %bb.nph16, label %bb20.loopexit
+
+return: ; preds = %bb30
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './stencils/adi/adi_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@X = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@B = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func() nounwind {
+bb.nph79:
+ br label %bb5.preheader
+
+bb.nph: ; preds = %bb5.preheader, %bb4
+ %storemerge112 = phi i64 [ %11, %bb4 ], [ 0, %bb5.preheader ]
+ %scevgep83.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge112, i64 0
+ %scevgep82.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge112, i64 0
+ %.pre = load double* %scevgep82.phi.trans.insert, align 32
+ %.pre143 = load double* %scevgep83.phi.trans.insert, align 32
+ br label %bb2
+
+bb2: ; preds = %bb2, %bb.nph
+ %0 = phi double [ %.pre143, %bb.nph ], [ %10, %bb2 ]
+ %1 = phi double [ %.pre, %bb.nph ], [ %6, %bb2 ]
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp87, %bb2 ]
+ %tmp5 = add i64 %indvar, 1
+ %scevgep81 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge112, i64 %tmp5
+ %scevgep80 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %storemerge112, i64 %tmp5
+ %scevgep = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge112, i64 %tmp5
+ %tmp87 = add i64 %indvar, 1
+ %2 = load double* %scevgep, align 8
+ %3 = load double* %scevgep80, align 8
+ %4 = fmul double %1, %3
+ %5 = fdiv double %4, %0
+ %6 = fsub double %2, %5
+ store double %6, double* %scevgep, align 8
+ %7 = load double* %scevgep81, align 8
+ %8 = fmul double %3, %3
+ %9 = fdiv double %8, %0
+ %10 = fsub double %7, %9
+ store double %10, double* %scevgep81, align 8
+ %exitcond1 = icmp eq i64 %tmp87, 1023
+ br i1 %exitcond1, label %bb4, label %bb2
+
+bb4: ; preds = %bb2
+ %11 = add nsw i64 %storemerge112, 1
+ %exitcond = icmp eq i64 %11, 1024
+ br i1 %exitcond, label %bb7.loopexit, label %bb.nph
+
+bb7.loopexit: ; preds = %bb4
+ br label %bb7
+
+bb7: ; preds = %bb7.loopexit, %bb7
+ %storemerge217 = phi i64 [ %15, %bb7 ], [ 0, %bb7.loopexit ]
+ %scevgep93 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge217, i64 1023
+ %scevgep92 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge217, i64 1023
+ %12 = load double* %scevgep92, align 8
+ %13 = load double* %scevgep93, align 8
+ %14 = fdiv double %12, %13
+ store double %14, double* %scevgep92, align 8
+ %15 = add nsw i64 %storemerge217, 1
+ %exitcond11 = icmp eq i64 %15, 1024
+ br i1 %exitcond11, label %bb12.preheader.loopexit, label %bb7
+
+bb11: ; preds = %bb12.preheader, %bb11
+ %storemerge920 = phi i64 [ %23, %bb11 ], [ 0, %bb12.preheader ]
+ %tmp22 = mul i64 %storemerge920, -1
+ %tmp23 = add i64 %tmp22, 1021
+ %scevgep100 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %storemerge323, i64 %tmp23
+ %scevgep99 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %storemerge323, i64 %tmp23
+ %scevgep98 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge323, i64 %tmp23
+ %tmp27 = add i64 %tmp22, 1022
+ %scevgep96 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %storemerge323, i64 %tmp27
+ %16 = load double* %scevgep96, align 8
+ %17 = load double* %scevgep98, align 8
+ %18 = load double* %scevgep99, align 8
+ %19 = fmul double %17, %18
+ %20 = fsub double %16, %19
+ %21 = load double* %scevgep100, align 8
+ %22 = fdiv double %20, %21
+ store double %22, double* %scevgep96, align 8
+ %23 = add nsw i64 %storemerge920, 1
+ %exitcond14 = icmp eq i64 %23, 1022
+ br i1 %exitcond14, label %bb13, label %bb11
+
+bb13: ; preds = %bb11
+ %24 = add nsw i64 %storemerge323, 1
+ %exitcond21 = icmp eq i64 %24, 1024
+ br i1 %exitcond21, label %bb18.preheader.loopexit, label %bb12.preheader
+
+bb12.preheader.loopexit: ; preds = %bb7
+ br label %bb12.preheader
+
+bb12.preheader: ; preds = %bb12.preheader.loopexit, %bb13
+ %storemerge323 = phi i64 [ %24, %bb13 ], [ 0, %bb12.preheader.loopexit ]
+ br label %bb11
+
+bb17: ; preds = %bb18.preheader, %bb17
+ %storemerge828 = phi i64 [ %36, %bb17 ], [ 0, %bb18.preheader ]
+ %scevgep114 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %indvar110, i64 %storemerge828
+ %scevgep113 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %indvar110, i64 %storemerge828
+ %scevgep116 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp38, i64 %storemerge828
+ %scevgep115 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp38, i64 %storemerge828
+ %scevgep112 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %tmp38, i64 %storemerge828
+ %25 = load double* %scevgep112, align 8
+ %26 = load double* %scevgep113, align 8
+ %27 = load double* %scevgep115, align 8
+ %28 = fmul double %26, %27
+ %29 = load double* %scevgep114, align 8
+ %30 = fdiv double %28, %29
+ %31 = fsub double %25, %30
+ store double %31, double* %scevgep112, align 8
+ %32 = load double* %scevgep116, align 8
+ %33 = fmul double %27, %27
+ %34 = fdiv double %33, %29
+ %35 = fsub double %32, %34
+ store double %35, double* %scevgep116, align 8
+ %36 = add nsw i64 %storemerge828, 1
+ %exitcond29 = icmp eq i64 %36, 1024
+ br i1 %exitcond29, label %bb19, label %bb17
+
+bb19: ; preds = %bb17
+ %tmp120 = add i64 %indvar110, 1
+ %exitcond35 = icmp eq i64 %tmp120, 1023
+ br i1 %exitcond35, label %bb22.loopexit, label %bb18.preheader
+
+bb18.preheader.loopexit: ; preds = %bb13
+ br label %bb18.preheader
+
+bb18.preheader: ; preds = %bb18.preheader.loopexit, %bb19
+ %indvar110 = phi i64 [ %tmp120, %bb19 ], [ 0, %bb18.preheader.loopexit ]
+ %tmp38 = add i64 %indvar110, 1
+ br label %bb17
+
+bb22.loopexit: ; preds = %bb19
+ br label %bb22
+
+bb22: ; preds = %bb22.loopexit, %bb22
+ %storemerge535 = phi i64 [ %40, %bb22 ], [ 0, %bb22.loopexit ]
+ %scevgep126 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 1023, i64 %storemerge535
+ %scevgep125 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 1023, i64 %storemerge535
+ %37 = load double* %scevgep125, align 8
+ %38 = load double* %scevgep126, align 8
+ %39 = fdiv double %37, %38
+ store double %39, double* %scevgep125, align 8
+ %40 = add nsw i64 %storemerge535, 1
+ %exitcond42 = icmp eq i64 %40, 1024
+ br i1 %exitcond42, label %bb27.preheader.loopexit, label %bb22
+
+bb26: ; preds = %bb27.preheader, %bb26
+ %storemerge737 = phi i64 [ %48, %bb26 ], [ 0, %bb27.preheader ]
+ %scevgep132 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp54, i64 %storemerge737
+ %scevgep131 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %tmp54, i64 %storemerge737
+ %scevgep133 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp57, i64 %storemerge737
+ %scevgep129 = getelementptr [1024 x [1024 x double]]* @X, i64 0, i64 %tmp57, i64 %storemerge737
+ %41 = load double* %scevgep129, align 8
+ %42 = load double* %scevgep131, align 8
+ %43 = load double* %scevgep132, align 8
+ %44 = fmul double %42, %43
+ %45 = fsub double %41, %44
+ %46 = load double* %scevgep133, align 8
+ %47 = fdiv double %45, %46
+ store double %47, double* %scevgep129, align 8
+ %48 = add nsw i64 %storemerge737, 1
+ %exitcond45 = icmp eq i64 %48, 1024
+ br i1 %exitcond45, label %bb28, label %bb26
+
+bb28: ; preds = %bb26
+ %49 = add nsw i64 %storemerge639, 1
+ %exitcond52 = icmp eq i64 %49, 1022
+ br i1 %exitcond52, label %bb30, label %bb27.preheader
+
+bb27.preheader.loopexit: ; preds = %bb22
+ br label %bb27.preheader
+
+bb27.preheader: ; preds = %bb27.preheader.loopexit, %bb28
+ %storemerge639 = phi i64 [ %49, %bb28 ], [ 0, %bb27.preheader.loopexit ]
+ %tmp53 = mul i64 %storemerge639, -1
+ %tmp54 = add i64 %tmp53, 1021
+ %tmp57 = add i64 %tmp53, 1022
+ br label %bb26
+
+bb30: ; preds = %bb28
+ %50 = add nsw i64 %storemerge44, 1
+ %exitcond60 = icmp eq i64 %50, 10
+ br i1 %exitcond60, label %return, label %bb5.preheader
+
+bb5.preheader: ; preds = %bb30, %bb.nph79
+ %storemerge44 = phi i64 [ 0, %bb.nph79 ], [ %50, %bb30 ]
+ br label %bb.nph
+
+return: ; preds = %bb30
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+/* Default problem size. */
+#ifndef TSTEPS
+# define TSTEPS 20
+#endif
+#ifndef N
+# define N 1024
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[N][N];
+DATA_TYPE B[N][N];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+DATA_TYPE** B = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ {
+ A[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ B[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+ }
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ {
+ A[i][j] = ((DATA_TYPE) i*j + 10) / N;
+ B[i][j] = ((DATA_TYPE) i*j + 11) / N;
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, A[i][j]);
+ if ((i * N + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long n = N;
+#else
+void scop_func(long n) {
+#endif
+ long t, i, j;
+ long tsteps = TSTEPS;
+
+#pragma scop
+#pragma live-out A
+
+ for (t = 0; t < tsteps; t++)
+ {
+ for (i = 2; i < n - 1; i++)
+ for (j = 2; j < n - 1; j++)
+ B[i][j] = 0.2 * (A[i][j] + A[i][j-1] + A[i][1+j] + A[1+i][j] + A[i-1][j]);
+ for (i = 2; i < n-1; i++)
+ for (j = 2; j < n-1; j++)
+ A[i][j] = B[i][j];
+ }
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int t, i, j;
+ int tsteps = TSTEPS;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; region-simplify causes: Non canonical PHI node found
+; XFAIL:*
+
+; ModuleID = './stencils/jacobi-2d-imper/jacobi-2d-imper_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@B = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func(i64 %n) nounwind {
+bb.nph35:
+ %0 = add nsw i64 %n, -1
+ %1 = icmp sgt i64 %0, 2
+ %tmp = add i64 %n, -3
+ br label %bb5.preheader
+
+bb.nph: ; preds = %bb.nph.preheader, %bb4
+ %indvar36 = phi i64 [ %tmp50, %bb4 ], [ 0, %bb.nph.preheader ]
+ %tmp13 = add i64 %indvar36, 1
+ %tmp16 = add i64 %indvar36, 3
+ %tmp18 = add i64 %indvar36, 2
+ %scevgep40.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp18, i64 2
+ %.pre = load double* %scevgep40.phi.trans.insert, align 16
+ br label %bb2
+
+bb2: ; preds = %bb2, %bb.nph
+ %2 = phi double [ %.pre, %bb.nph ], [ %5, %bb2 ]
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp58, %bb2 ]
+ %tmp14 = add i64 %indvar, 2
+ %scevgep44 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp13, i64 %tmp14
+ %scevgep42 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp16, i64 %tmp14
+ %scevgep = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp18, i64 %tmp14
+ %tmp20 = add i64 %indvar, 3
+ %scevgep48 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp18, i64 %tmp20
+ %tmp22 = add i64 %indvar, 1
+ %scevgep46 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp18, i64 %tmp22
+ %tmp58 = add i64 %indvar, 1
+ %3 = load double* %scevgep46, align 8
+ %4 = fadd double %2, %3
+ %5 = load double* %scevgep48, align 8
+ %6 = fadd double %4, %5
+ %7 = load double* %scevgep42, align 8
+ %8 = fadd double %6, %7
+ %9 = load double* %scevgep44, align 8
+ %10 = fadd double %8, %9
+ %11 = fmul double %10, 2.000000e-01
+ store double %11, double* %scevgep, align 8
+ %exitcond1 = icmp eq i64 %tmp58, %tmp
+ br i1 %exitcond1, label %bb4, label %bb2
+
+bb4: ; preds = %bb2
+ %tmp50 = add i64 %indvar36, 1
+ %exitcond = icmp eq i64 %tmp50, %tmp
+ br i1 %exitcond, label %bb11.loopexit, label %bb.nph
+
+bb8: ; preds = %bb9.preheader, %bb8
+ %indvar62 = phi i64 [ %indvar.next63, %bb8 ], [ 0, %bb9.preheader ]
+ %tmp32 = add i64 %indvar62, 2
+ %scevgep70 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp31, i64 %tmp32
+ %scevgep69 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp31, i64 %tmp32
+ %12 = load double* %scevgep70, align 8
+ store double %12, double* %scevgep69, align 8
+ %indvar.next63 = add i64 %indvar62, 1
+ %exitcond25 = icmp eq i64 %indvar.next63, %tmp
+ br i1 %exitcond25, label %bb10, label %bb8
+
+bb10: ; preds = %bb8
+ %indvar.next66 = add i64 %indvar65, 1
+ %exitcond30 = icmp eq i64 %indvar.next66, %tmp
+ br i1 %exitcond30, label %bb12.loopexit, label %bb9.preheader
+
+bb11.loopexit: ; preds = %bb4
+ br i1 %1, label %bb9.preheader.preheader, label %bb12
+
+bb9.preheader.preheader: ; preds = %bb11.loopexit
+ br label %bb9.preheader
+
+bb9.preheader: ; preds = %bb9.preheader.preheader, %bb10
+ %indvar65 = phi i64 [ %indvar.next66, %bb10 ], [ 0, %bb9.preheader.preheader ]
+ %tmp31 = add i64 %indvar65, 2
+ br label %bb8
+
+bb12.loopexit: ; preds = %bb10
+ br label %bb12
+
+bb12: ; preds = %bb12.loopexit, %bb5.preheader, %bb11.loopexit
+ %13 = add nsw i64 %storemerge20, 1
+ %exitcond35 = icmp eq i64 %13, 20
+ br i1 %exitcond35, label %return, label %bb5.preheader
+
+bb5.preheader: ; preds = %bb12, %bb.nph35
+ %storemerge20 = phi i64 [ 0, %bb.nph35 ], [ %13, %bb12 ]
+ br i1 %1, label %bb.nph.preheader, label %bb12
+
+bb.nph.preheader: ; preds = %bb5.preheader
+ br label %bb.nph
+
+return: ; preds = %bb12
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
+
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './stencils/jacobi-2d-imper/jacobi-2d-imper_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@B = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func() nounwind {
+bb.nph35:
+ br label %bb5.preheader
+
+bb.nph: ; preds = %bb5.preheader, %bb4
+ %indvar36 = phi i64 [ %tmp49, %bb4 ], [ 0, %bb5.preheader ]
+ %tmp12 = add i64 %indvar36, 1
+ %tmp15 = add i64 %indvar36, 3
+ %tmp17 = add i64 %indvar36, 2
+ %scevgep39.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp17, i64 2
+ %.pre = load double* %scevgep39.phi.trans.insert, align 16
+ br label %bb2
+
+bb2: ; preds = %bb2, %bb.nph
+ %0 = phi double [ %.pre, %bb.nph ], [ %3, %bb2 ]
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp57, %bb2 ]
+ %tmp13 = add i64 %indvar, 2
+ %scevgep43 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp12, i64 %tmp13
+ %scevgep41 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp15, i64 %tmp13
+ %scevgep = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp17, i64 %tmp13
+ %tmp19 = add i64 %indvar, 3
+ %scevgep47 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp17, i64 %tmp19
+ %tmp21 = add i64 %indvar, 1
+ %scevgep45 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp17, i64 %tmp21
+ %tmp57 = add i64 %indvar, 1
+ %1 = load double* %scevgep45, align 8
+ %2 = fadd double %0, %1
+ %3 = load double* %scevgep47, align 8
+ %4 = fadd double %2, %3
+ %5 = load double* %scevgep41, align 8
+ %6 = fadd double %4, %5
+ %7 = load double* %scevgep43, align 8
+ %8 = fadd double %6, %7
+ %9 = fmul double %8, 2.000000e-01
+ store double %9, double* %scevgep, align 8
+ %exitcond1 = icmp eq i64 %tmp57, 1021
+ br i1 %exitcond1, label %bb4, label %bb2
+
+bb4: ; preds = %bb2
+ %tmp49 = add i64 %indvar36, 1
+ %exitcond = icmp eq i64 %tmp49, 1021
+ br i1 %exitcond, label %bb9.preheader.loopexit, label %bb.nph
+
+bb8: ; preds = %bb9.preheader, %bb8
+ %indvar61 = phi i64 [ %indvar.next62, %bb8 ], [ 0, %bb9.preheader ]
+ %tmp30 = add i64 %indvar61, 2
+ %scevgep68 = getelementptr [1024 x [1024 x double]]* @B, i64 0, i64 %tmp29, i64 %tmp30
+ %scevgep67 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp29, i64 %tmp30
+ %10 = load double* %scevgep68, align 8
+ store double %10, double* %scevgep67, align 8
+ %indvar.next62 = add i64 %indvar61, 1
+ %exitcond24 = icmp eq i64 %indvar.next62, 1021
+ br i1 %exitcond24, label %bb10, label %bb8
+
+bb10: ; preds = %bb8
+ %indvar.next65 = add i64 %indvar64, 1
+ %exitcond28 = icmp eq i64 %indvar.next65, 1021
+ br i1 %exitcond28, label %bb12, label %bb9.preheader
+
+bb9.preheader.loopexit: ; preds = %bb4
+ br label %bb9.preheader
+
+bb9.preheader: ; preds = %bb9.preheader.loopexit, %bb10
+ %indvar64 = phi i64 [ %indvar.next65, %bb10 ], [ 0, %bb9.preheader.loopexit ]
+ %tmp29 = add i64 %indvar64, 2
+ br label %bb8
+
+bb12: ; preds = %bb10
+ %11 = add nsw i64 %storemerge20, 1
+ %exitcond33 = icmp eq i64 %11, 20
+ br i1 %exitcond33, label %return, label %bb5.preheader
+
+bb5.preheader: ; preds = %bb12, %bb.nph35
+ %storemerge20 = phi i64 [ 0, %bb.nph35 ], [ %11, %bb12 ]
+ br label %bb.nph
+
+return: ; preds = %bb12
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+/* Default problem size. */
+#ifndef TSTEPS
+# define TSTEPS 20
+#endif
+#ifndef N
+# define N 1024
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+#ifndef DATA_PRINTF_MODIFIER
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[N][N];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(N * sizeof(DATA_TYPE*));
+{
+ int i;
+ for (i = 0; i < N; ++i)
+ A[i] = (DATA_TYPE*)malloc(N * sizeof(DATA_TYPE));
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ A[i][j] = ((DATA_TYPE) i*j + 10) / N;
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++) {
+ fprintf(stderr, DATA_PRINTF_MODIFIER, A[i][j]);
+ if ((i * N + j) % 80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+#ifndef SCOP_PARAM
+void scop_func() {
+ long n = N;
+#else
+void scop_func(long n) {
+#endif
+ long t, i, j;
+ long tsteps = TSTEPS;
+
+#pragma scop
+#pragma live-out A
+
+ for (t = 0; t <= tsteps - 1; t++)
+ for (i = 1; i<= n - 2; i++)
+ for (j = 1; j <= n - 2; j++)
+ A[i][j] = (A[i-1][j-1] + A[i-1][j] + A[i-1][j+1]
+ + A[i][j-1] + A[i][j] + A[i][j+1]
+ + A[i+1][j-1] + A[i+1][j] + A[i+1][j+1])/9.0;
+
+#pragma endscop
+}
+
+int main(int argc, char** argv)
+{
+ int t, i, j;
+ int tsteps = TSTEPS;
+ int n = N;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#ifndef SCOP_PARAM
+ scop_func();
+#else
+ scop_func(n);
+#endif
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-analyze-ir -print-top-scop-only -analyze %s | FileCheck %s
+; XFAIL: *
+; ModuleID = './stencils/seidel/seidel_with_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func(i64 %n) nounwind {
+bb.nph20:
+ %0 = add nsw i64 %n, -2
+ %1 = icmp slt i64 %0, 1
+ br i1 %1, label %return, label %bb.nph8.preheader
+
+bb.nph8.preheader: ; preds = %bb.nph20
+ br label %bb.nph8
+
+bb.nph: ; preds = %bb.nph.preheader, %bb4
+ %indvar21 = phi i64 [ %tmp39, %bb4 ], [ 0, %bb.nph.preheader ]
+ %tmp5 = add i64 %indvar21, 1
+ %tmp43 = add i64 %indvar21, 2
+ %scevgep26.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %indvar21, i64 1
+ %scevgep.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp43, i64 1
+ %scevgep30.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp5, i64 0
+ %scevgep25.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp5, i64 1
+ %tmp39 = add i64 %indvar21, 1
+ %.pre = load double* %scevgep26.phi.trans.insert, align 8
+ %.pre47 = load double* %scevgep25.phi.trans.insert, align 8
+ %.pre48 = load double* %scevgep.phi.trans.insert, align 8
+ %.pre49 = load double* %scevgep30.phi.trans.insert, align 32
+ br label %bb2
+
+bb2: ; preds = %bb2, %bb.nph
+ %2 = phi double [ %.pre49, %bb.nph ], [ %19, %bb2 ]
+ %3 = phi double [ %.pre48, %bb.nph ], [ %17, %bb2 ]
+ %4 = phi double [ %.pre47, %bb.nph ], [ %12, %bb2 ]
+ %5 = phi double [ %.pre, %bb.nph ], [ %8, %bb2 ]
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp37, %bb2 ]
+ %tmp4 = add i64 %indvar, 2
+ %scevgep29 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %indvar21, i64 %tmp4
+ %scevgep27 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %indvar21, i64 %indvar
+ %scevgep31 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp5, i64 %tmp4
+ %tmp6 = add i64 %indvar, 1
+ %scevgep25 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp5, i64 %tmp6
+ %scevgep33 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp43, i64 %tmp4
+ %scevgep32 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp43, i64 %indvar
+ %tmp34 = add i64 %indvar, 2
+ %tmp37 = add i64 %indvar, 1
+ %6 = load double* %scevgep27, align 8
+ %7 = fadd double %6, %5
+ %8 = load double* %scevgep29, align 8
+ %9 = fadd double %7, %8
+ %10 = fadd double %9, %2
+ %11 = fadd double %10, %4
+ %12 = load double* %scevgep31, align 8
+ %13 = fadd double %11, %12
+ %14 = load double* %scevgep32, align 8
+ %15 = fadd double %13, %14
+ %16 = fadd double %15, %3
+ %17 = load double* %scevgep33, align 8
+ %18 = fadd double %16, %17
+ %19 = fdiv double %18, 9.000000e+00
+ store double %19, double* %scevgep25, align 8
+ %20 = icmp slt i64 %0, %tmp34
+ br i1 %20, label %bb4, label %bb2
+
+bb4: ; preds = %bb2
+ %21 = icmp slt i64 %0, %tmp43
+ br i1 %21, label %bb6.loopexit, label %bb.nph
+
+bb.nph8: ; preds = %bb.nph8.preheader, %bb6
+ %storemerge9 = phi i64 [ %22, %bb6 ], [ 0, %bb.nph8.preheader ]
+ br i1 %1, label %bb6, label %bb.nph.preheader
+
+bb.nph.preheader: ; preds = %bb.nph8
+ br label %bb.nph
+
+bb6.loopexit: ; preds = %bb4
+ br label %bb6
+
+bb6: ; preds = %bb6.loopexit, %bb.nph8
+ %22 = add nsw i64 %storemerge9, 1
+ %exitcond8 = icmp eq i64 %22, 20
+ br i1 %exitcond8, label %return.loopexit, label %bb.nph8
+
+return.loopexit: ; preds = %bb6
+ br label %return
+
+return: ; preds = %return.loopexit, %bb.nph20
+ ret void
+}
--- /dev/null
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze %s | FileCheck %s
+; ModuleID = './stencils/seidel/seidel_without_param.ll'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+@A = common global [1024 x [1024 x double]] zeroinitializer, align 32
+@stderr = external global %struct._IO_FILE*
+@.str = private constant [8 x i8] c"%0.2lf \00", align 1
+
+define void @scop_func() nounwind {
+bb.nph20.bb.nph20.split_crit_edge:
+ br label %bb5.preheader
+
+bb.nph: ; preds = %bb5.preheader, %bb4
+ %indvar21 = phi i64 [ %tmp40, %bb4 ], [ 0, %bb5.preheader ]
+ %tmp6 = add i64 %indvar21, 1
+ %tmp8 = add i64 %indvar21, 2
+ %scevgep26.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %indvar21, i64 1
+ %scevgep.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp8, i64 1
+ %scevgep30.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp6, i64 0
+ %scevgep25.phi.trans.insert = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp6, i64 1
+ %tmp40 = add i64 %indvar21, 1
+ %.pre = load double* %scevgep26.phi.trans.insert, align 8
+ %.pre49 = load double* %scevgep25.phi.trans.insert, align 8
+ %.pre50 = load double* %scevgep.phi.trans.insert, align 8
+ %.pre51 = load double* %scevgep30.phi.trans.insert, align 32
+ br label %bb2
+
+bb2: ; preds = %bb2, %bb.nph
+ %0 = phi double [ %.pre51, %bb.nph ], [ %17, %bb2 ]
+ %1 = phi double [ %.pre50, %bb.nph ], [ %15, %bb2 ]
+ %2 = phi double [ %.pre49, %bb.nph ], [ %10, %bb2 ]
+ %3 = phi double [ %.pre, %bb.nph ], [ %6, %bb2 ]
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp38, %bb2 ]
+ %tmp5 = add i64 %indvar, 2
+ %scevgep29 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %indvar21, i64 %tmp5
+ %scevgep27 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %indvar21, i64 %indvar
+ %scevgep31 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp6, i64 %tmp5
+ %tmp7 = add i64 %indvar, 1
+ %scevgep25 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp6, i64 %tmp7
+ %scevgep33 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp8, i64 %tmp5
+ %scevgep32 = getelementptr [1024 x [1024 x double]]* @A, i64 0, i64 %tmp8, i64 %indvar
+ %tmp38 = add i64 %indvar, 1
+ %4 = load double* %scevgep27, align 8
+ %5 = fadd double %4, %3
+ %6 = load double* %scevgep29, align 8
+ %7 = fadd double %5, %6
+ %8 = fadd double %7, %0
+ %9 = fadd double %8, %2
+ %10 = load double* %scevgep31, align 8
+ %11 = fadd double %9, %10
+ %12 = load double* %scevgep32, align 8
+ %13 = fadd double %11, %12
+ %14 = fadd double %13, %1
+ %15 = load double* %scevgep33, align 8
+ %16 = fadd double %14, %15
+ %17 = fdiv double %16, 9.000000e+00
+ store double %17, double* %scevgep25, align 8
+ %exitcond1 = icmp eq i64 %tmp38, 1022
+ br i1 %exitcond1, label %bb4, label %bb2
+
+bb4: ; preds = %bb2
+ %exitcond = icmp eq i64 %tmp40, 1022
+ br i1 %exitcond, label %bb6, label %bb.nph
+
+bb6: ; preds = %bb4
+ %18 = add nsw i64 %storemerge9, 1
+ %exitcond9 = icmp eq i64 %18, 20
+ br i1 %exitcond9, label %return, label %bb5.preheader
+
+bb5.preheader: ; preds = %bb6, %bb.nph20.bb.nph20.split_crit_edge
+ %storemerge9 = phi i64 [ 0, %bb.nph20.bb.nph20.split_crit_edge ], [ %18, %bb6 ]
+ br label %bb.nph
+
+return: ; preds = %bb6
+ ret void
+}
+; CHECK: Valid Region for Scop: bb5.preheader => return
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sched.h>
+#include <math.h>
+
+#ifndef POLYBENCH_CACHE_SIZE_KB
+# define POLYBENCH_CACHE_SIZE_KB 8192
+#endif
+
+/* Timer code (gettimeofday). */
+double polybench_t_start, polybench_t_end;
+
+static
+inline
+double rtclock()
+{
+ struct timezone Tzp;
+ struct timeval Tp;
+ int stat;
+ stat = gettimeofday (&Tp, &Tzp);
+ if (stat != 0)
+ printf("Error return from gettimeofday: %d", stat);
+ return (Tp.tv_sec + Tp.tv_usec * 1.0e-6);
+}
+
+inline
+void polybench_flush_cache()
+{
+ int cs = POLYBENCH_CACHE_SIZE_KB * 1024 / sizeof(double);
+ double* flush = (double*) calloc(cs, sizeof(double));
+ int i;
+ double tmp = 0.0;
+ for (i = 0; i < cs; i++)
+ tmp += flush[i];
+ /* This prevents DCE on the cache flush code. */
+ assert (tmp <= 10.0);
+}
+
+#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
+inline
+void polybench_linux_fifo_scheduler()
+{
+ /* Use FIFO scheduler to limit OS interference. Program must be run
+ as root, and this works only for Linux kernels. */
+ struct sched_param schedParam;
+ schedParam.sched_priority = sched_get_priority_max(SCHED_FIFO);
+ sched_setscheduler(0, SCHED_FIFO, &schedParam);
+}
+
+inline
+void polybench_linux_standard_scheduler()
+{
+ /* Restore to standard scheduler policy. */
+ struct sched_param schedParam;
+ schedParam.sched_priority = sched_get_priority_max(SCHED_OTHER);
+ sched_setscheduler(0, SCHED_OTHER, &schedParam);
+}
+#endif
+
+void polybench_timer_start()
+{
+#ifndef POLYBENCH_NO_FLUSH_CACHE
+ polybench_flush_cache();
+#endif
+#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
+ polybench_linux_fifo_scheduler();
+#endif
+ polybench_t_start = rtclock();
+}
+
+void polybench_timer_stop()
+{
+#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
+ polybench_linux_standard_scheduler();
+#endif
+ polybench_t_end = rtclock();
+}
+
+void polybench_timer_print()
+{
+ printf("%0.6lfs\n", polybench_t_end - polybench_t_start);
+}
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <math.h>
+
+
+#define polybench_start_instruments
+#define polybench_stop_instruments
+#define polybench_print_instruments
+
+#ifdef POLYBENCH_TIME
+# undef polybench_start_instruments
+# undef polybench_stop_instruments
+# undef polybench_print_instruments
+# define polybench_start_instruments polybench_timer_start();
+# define polybench_stop_instruments polybench_timer_stop();
+# define polybench_print_instruments polybench_timer_print();
+#endif
+
+
+extern void polybench_timer_start();
+extern void polybench_timer_stop();
+extern void polybench_timer_print();
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#include "instrument.h"
+
+
+/* Default problem size. */
+#ifndef NX
+# define NX 8000
+#endif
+#ifnef NY
+# define NY 8000
+#endif
+
+/* Default data type is double. */
+#ifndef DATA_TYPE
+# define DATA_TYPE double
+#endif
+
+/* Array declaration. Enable malloc if POLYBENCH_TEST_MALLOC. */
+#ifndef POLYBENCH_TEST_MALLOC
+DATA_TYPE A[nx][ny];
+DATA_TYPE x[ny];
+DATA_TYPE y[ny];
+DATA_TYPE tmp[nx];
+#else
+DATA_TYPE** A = (DATA_TYPE**)malloc(nx * sizeof(DATA_TYPE*));
+DATA_TYPE* x = (DATA_TYPE*)malloc(ny * sizeof(DATA_TYPE));
+DATA_TYPE* y = (DATA_TYPE*)malloc(ny * sizeof(DATA_TYPE));
+DATA_TYPE* tmp = (DATA_TYPE*)malloc(nx * sizeof(DATA_TYPE));
+{
+ int i;
+ for (i = 0; i < nx; ++i)
+ A[i] = (DATA_TYPE*)malloc(ny * sizeof(DATA_TYPE));
+}
+#endif
+
+inline
+void init_array()
+{
+ int i, j;
+
+ for (i = 0; i < nx; i++)
+ {
+ x[i] = i * M_PI;
+ for (j = 0; j < ny; j++)
+ A[i][j] = ((DATA_TYPE) i*j) / nx;
+ }
+}
+
+/* Define the live-out variables. Code is not executed unless
+ POLYBENCH_DUMP_ARRAYS is defined. */
+inline
+void print_array(int argc, char** argv)
+{
+ int i, j;
+#ifndef POLYBENCH_DUMP_ARRAYS
+ if (argc > 42 && ! strcmp(argv[0], ""))
+#endif
+ {
+ for (i = 0; i < nx; i++) {
+ fprintf(stderr, "%0.2lf ", y[i]);
+ if (i%80 == 20) fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+
+int main(int argc, char** argv)
+{
+ int i, j;
+ int nx = NX;
+ int ny = NY;
+
+ /* Initialize array. */
+ init_array();
+
+ /* Start timer. */
+ polybench_start_instruments;
+
+#pragma scop
+#pragma live-out
+
+
+
+
+#pragma endscop
+
+ /* Stop and print timer. */
+ polybench_stop_instruments;
+ polybench_print_instruments;
+
+ print_array(argc, argv);
+
+ return 0;
+}
--- /dev/null
+set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE)
--- /dev/null
+##===- tools/Makefile --------------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ..
+DIRS :=
+
+include $(LEVEL)/Makefile.common
--- /dev/null
+# -*- coding: utf-8 -*-\r
+\r
+# Copyright © 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not\r
+# use this file except in compliance with the License. You may obtain a copy\r
+# of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+# License for the specific language governing permissions and limitations\r
+# under the License.\r
+\r
+"""Command-line parsing library\r
+\r
+This module is an optparse-inspired command-line parsing library that:\r
+\r
+ - handles both optional and positional arguments\r
+ - produces highly informative usage messages\r
+ - supports parsers that dispatch to sub-parsers\r
+\r
+The following is a simple usage example that sums integers from the\r
+command-line and writes the result to a file::\r
+\r
+ parser = argparse.ArgumentParser(\r
+ description='sum the integers at the command line')\r
+ parser.add_argument(\r
+ 'integers', metavar='int', nargs='+', type=int,\r
+ help='an integer to be summed')\r
+ parser.add_argument(\r
+ '--log', default=sys.stdout, type=argparse.FileType('w'),\r
+ help='the file where the sum should be written')\r
+ args = parser.parse_args()\r
+ args.log.write('%s' % sum(args.integers))\r
+ args.log.close()\r
+\r
+The module contains the following public classes:\r
+\r
+ - ArgumentParser -- The main entry point for command-line parsing. As the\r
+ example above shows, the add_argument() method is used to populate\r
+ the parser with actions for optional and positional arguments. Then\r
+ the parse_args() method is invoked to convert the args at the\r
+ command-line into an object with attributes.\r
+\r
+ - ArgumentError -- The exception raised by ArgumentParser objects when\r
+ there are errors with the parser's actions. Errors raised while\r
+ parsing the command-line are caught by ArgumentParser and emitted\r
+ as command-line messages.\r
+\r
+ - FileType -- A factory for defining types of files to be created. As the\r
+ example above shows, instances of FileType are typically passed as\r
+ the type= argument of add_argument() calls.\r
+\r
+ - Action -- The base class for parser actions. Typically actions are\r
+ selected by passing strings like 'store_true' or 'append_const' to\r
+ the action= argument of add_argument(). However, for greater\r
+ customization of ArgumentParser actions, subclasses of Action may\r
+ be defined and passed as the action= argument.\r
+\r
+ - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,\r
+ ArgumentDefaultsHelpFormatter -- Formatter classes which\r
+ may be passed as the formatter_class= argument to the\r
+ ArgumentParser constructor. HelpFormatter is the default,\r
+ RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser\r
+ not to change the formatting for help text, and\r
+ ArgumentDefaultsHelpFormatter adds information about argument defaults\r
+ to the help.\r
+\r
+All other classes in this module are considered implementation details.\r
+(Also note that HelpFormatter and RawDescriptionHelpFormatter are only\r
+considered public as object names -- the API of the formatter objects is\r
+still considered an implementation detail.)\r
+"""\r
+\r
+__version__ = '1.1'\r
+__all__ = [\r
+ 'ArgumentParser',\r
+ 'ArgumentError',\r
+ 'Namespace',\r
+ 'Action',\r
+ 'FileType',\r
+ 'HelpFormatter',\r
+ 'RawDescriptionHelpFormatter',\r
+ 'RawTextHelpFormatter',\r
+ 'ArgumentDefaultsHelpFormatter',\r
+]\r
+\r
+\r
+import copy as _copy\r
+import os as _os\r
+import re as _re\r
+import sys as _sys\r
+import textwrap as _textwrap\r
+\r
+from gettext import gettext as _\r
+\r
+try:\r
+ _set = set\r
+except NameError:\r
+ from sets import Set as _set\r
+\r
+try:\r
+ _basestring = basestring\r
+except NameError:\r
+ _basestring = str\r
+\r
+try:\r
+ _sorted = sorted\r
+except NameError:\r
+\r
+ def _sorted(iterable, reverse=False):\r
+ result = list(iterable)\r
+ result.sort()\r
+ if reverse:\r
+ result.reverse()\r
+ return result\r
+\r
+\r
+def _callable(obj):\r
+ return hasattr(obj, '__call__') or hasattr(obj, '__bases__')\r
+\r
+# silence Python 2.6 buggy warnings about Exception.message\r
+if _sys.version_info[:2] == (2, 6):\r
+ import warnings\r
+ warnings.filterwarnings(\r
+ action='ignore',\r
+ message='BaseException.message has been deprecated as of Python 2.6',\r
+ category=DeprecationWarning,\r
+ module='argparse')\r
+\r
+\r
+SUPPRESS = '==SUPPRESS=='\r
+\r
+OPTIONAL = '?'\r
+ZERO_OR_MORE = '*'\r
+ONE_OR_MORE = '+'\r
+PARSER = 'A...'\r
+REMAINDER = '...'\r
+\r
+# =============================\r
+# Utility functions and classes\r
+# =============================\r
+\r
+class _AttributeHolder(object):\r
+ """Abstract base class that provides __repr__.\r
+\r
+ The __repr__ method returns a string in the format::\r
+ ClassName(attr=name, attr=name, ...)\r
+ The attributes are determined either by a class-level attribute,\r
+ '_kwarg_names', or by inspecting the instance __dict__.\r
+ """\r
+\r
+ def __repr__(self):\r
+ type_name = type(self).__name__\r
+ arg_strings = []\r
+ for arg in self._get_args():\r
+ arg_strings.append(repr(arg))\r
+ for name, value in self._get_kwargs():\r
+ arg_strings.append('%s=%r' % (name, value))\r
+ return '%s(%s)' % (type_name, ', '.join(arg_strings))\r
+\r
+ def _get_kwargs(self):\r
+ return _sorted(self.__dict__.items())\r
+\r
+ def _get_args(self):\r
+ return []\r
+\r
+\r
+def _ensure_value(namespace, name, value):\r
+ if getattr(namespace, name, None) is None:\r
+ setattr(namespace, name, value)\r
+ return getattr(namespace, name)\r
+\r
+\r
+# ===============\r
+# Formatting Help\r
+# ===============\r
+\r
+class HelpFormatter(object):\r
+ """Formatter for generating usage messages and argument help strings.\r
+\r
+ Only the name of this class is considered a public API. All the methods\r
+ provided by the class are considered an implementation detail.\r
+ """\r
+\r
+ def __init__(self,\r
+ prog,\r
+ indent_increment=2,\r
+ max_help_position=24,\r
+ width=None):\r
+\r
+ # default setting for width\r
+ if width is None:\r
+ try:\r
+ width = int(_os.environ['COLUMNS'])\r
+ except (KeyError, ValueError):\r
+ width = 80\r
+ width -= 2\r
+\r
+ self._prog = prog\r
+ self._indent_increment = indent_increment\r
+ self._max_help_position = max_help_position\r
+ self._width = width\r
+\r
+ self._current_indent = 0\r
+ self._level = 0\r
+ self._action_max_length = 0\r
+\r
+ self._root_section = self._Section(self, None)\r
+ self._current_section = self._root_section\r
+\r
+ self._whitespace_matcher = _re.compile(r'\s+')\r
+ self._long_break_matcher = _re.compile(r'\n\n\n+')\r
+\r
+ # ===============================\r
+ # Section and indentation methods\r
+ # ===============================\r
+ def _indent(self):\r
+ self._current_indent += self._indent_increment\r
+ self._level += 1\r
+\r
+ def _dedent(self):\r
+ self._current_indent -= self._indent_increment\r
+ assert self._current_indent >= 0, 'Indent decreased below 0.'\r
+ self._level -= 1\r
+\r
+ class _Section(object):\r
+\r
+ def __init__(self, formatter, parent, heading=None):\r
+ self.formatter = formatter\r
+ self.parent = parent\r
+ self.heading = heading\r
+ self.items = []\r
+\r
+ def format_help(self):\r
+ # format the indented section\r
+ if self.parent is not None:\r
+ self.formatter._indent()\r
+ join = self.formatter._join_parts\r
+ for func, args in self.items:\r
+ func(*args)\r
+ item_help = join([func(*args) for func, args in self.items])\r
+ if self.parent is not None:\r
+ self.formatter._dedent()\r
+\r
+ # return nothing if the section was empty\r
+ if not item_help:\r
+ return ''\r
+\r
+ # add the heading if the section was non-empty\r
+ if self.heading is not SUPPRESS and self.heading is not None:\r
+ current_indent = self.formatter._current_indent\r
+ heading = '%*s%s:\n' % (current_indent, '', self.heading)\r
+ else:\r
+ heading = ''\r
+\r
+ # join the section-initial newline, the heading and the help\r
+ return join(['\n', heading, item_help, '\n'])\r
+\r
+ def _add_item(self, func, args):\r
+ self._current_section.items.append((func, args))\r
+\r
+ # ========================\r
+ # Message building methods\r
+ # ========================\r
+ def start_section(self, heading):\r
+ self._indent()\r
+ section = self._Section(self, self._current_section, heading)\r
+ self._add_item(section.format_help, [])\r
+ self._current_section = section\r
+\r
+ def end_section(self):\r
+ self._current_section = self._current_section.parent\r
+ self._dedent()\r
+\r
+ def add_text(self, text):\r
+ if text is not SUPPRESS and text is not None:\r
+ self._add_item(self._format_text, [text])\r
+\r
+ def add_usage(self, usage, actions, groups, prefix=None):\r
+ if usage is not SUPPRESS:\r
+ args = usage, actions, groups, prefix\r
+ self._add_item(self._format_usage, args)\r
+\r
+ def add_argument(self, action):\r
+ if action.help is not SUPPRESS:\r
+\r
+ # find all invocations\r
+ get_invocation = self._format_action_invocation\r
+ invocations = [get_invocation(action)]\r
+ for subaction in self._iter_indented_subactions(action):\r
+ invocations.append(get_invocation(subaction))\r
+\r
+ # update the maximum item length\r
+ invocation_length = max([len(s) for s in invocations])\r
+ action_length = invocation_length + self._current_indent\r
+ self._action_max_length = max(self._action_max_length,\r
+ action_length)\r
+\r
+ # add the item to the list\r
+ self._add_item(self._format_action, [action])\r
+\r
+ def add_arguments(self, actions):\r
+ for action in actions:\r
+ self.add_argument(action)\r
+\r
+ # =======================\r
+ # Help-formatting methods\r
+ # =======================\r
+ def format_help(self):\r
+ help = self._root_section.format_help()\r
+ if help:\r
+ help = self._long_break_matcher.sub('\n\n', help)\r
+ help = help.strip('\n') + '\n'\r
+ return help\r
+\r
+ def _join_parts(self, part_strings):\r
+ return ''.join([part\r
+ for part in part_strings\r
+ if part and part is not SUPPRESS])\r
+\r
+ def _format_usage(self, usage, actions, groups, prefix):\r
+ if prefix is None:\r
+ prefix = _('usage: ')\r
+\r
+ # if usage is specified, use that\r
+ if usage is not None:\r
+ usage = usage % dict(prog=self._prog)\r
+\r
+ # if no optionals or positionals are available, usage is just prog\r
+ elif usage is None and not actions:\r
+ usage = '%(prog)s' % dict(prog=self._prog)\r
+\r
+ # if optionals and positionals are available, calculate usage\r
+ elif usage is None:\r
+ prog = '%(prog)s' % dict(prog=self._prog)\r
+\r
+ # split optionals from positionals\r
+ optionals = []\r
+ positionals = []\r
+ for action in actions:\r
+ if action.option_strings:\r
+ optionals.append(action)\r
+ else:\r
+ positionals.append(action)\r
+\r
+ # build full usage string\r
+ format = self._format_actions_usage\r
+ action_usage = format(optionals + positionals, groups)\r
+ usage = ' '.join([s for s in [prog, action_usage] if s])\r
+\r
+ # wrap the usage parts if it's too long\r
+ text_width = self._width - self._current_indent\r
+ if len(prefix) + len(usage) > text_width:\r
+\r
+ # break usage into wrappable parts\r
+ part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'\r
+ opt_usage = format(optionals, groups)\r
+ pos_usage = format(positionals, groups)\r
+ opt_parts = _re.findall(part_regexp, opt_usage)\r
+ pos_parts = _re.findall(part_regexp, pos_usage)\r
+ assert ' '.join(opt_parts) == opt_usage\r
+ assert ' '.join(pos_parts) == pos_usage\r
+\r
+ # helper for wrapping lines\r
+ def get_lines(parts, indent, prefix=None):\r
+ lines = []\r
+ line = []\r
+ if prefix is not None:\r
+ line_len = len(prefix) - 1\r
+ else:\r
+ line_len = len(indent) - 1\r
+ for part in parts:\r
+ if line_len + 1 + len(part) > text_width:\r
+ lines.append(indent + ' '.join(line))\r
+ line = []\r
+ line_len = len(indent) - 1\r
+ line.append(part)\r
+ line_len += len(part) + 1\r
+ if line:\r
+ lines.append(indent + ' '.join(line))\r
+ if prefix is not None:\r
+ lines[0] = lines[0][len(indent):]\r
+ return lines\r
+\r
+ # if prog is short, follow it with optionals or positionals\r
+ if len(prefix) + len(prog) <= 0.75 * text_width:\r
+ indent = ' ' * (len(prefix) + len(prog) + 1)\r
+ if opt_parts:\r
+ lines = get_lines([prog] + opt_parts, indent, prefix)\r
+ lines.extend(get_lines(pos_parts, indent))\r
+ elif pos_parts:\r
+ lines = get_lines([prog] + pos_parts, indent, prefix)\r
+ else:\r
+ lines = [prog]\r
+\r
+ # if prog is long, put it on its own line\r
+ else:\r
+ indent = ' ' * len(prefix)\r
+ parts = opt_parts + pos_parts\r
+ lines = get_lines(parts, indent)\r
+ if len(lines) > 1:\r
+ lines = []\r
+ lines.extend(get_lines(opt_parts, indent))\r
+ lines.extend(get_lines(pos_parts, indent))\r
+ lines = [prog] + lines\r
+\r
+ # join lines into usage\r
+ usage = '\n'.join(lines)\r
+\r
+ # prefix with 'usage:'\r
+ return '%s%s\n\n' % (prefix, usage)\r
+\r
+ def _format_actions_usage(self, actions, groups):\r
+ # find group indices and identify actions in groups\r
+ group_actions = _set()\r
+ inserts = {}\r
+ for group in groups:\r
+ try:\r
+ start = actions.index(group._group_actions[0])\r
+ except ValueError:\r
+ continue\r
+ else:\r
+ end = start + len(group._group_actions)\r
+ if actions[start:end] == group._group_actions:\r
+ for action in group._group_actions:\r
+ group_actions.add(action)\r
+ if not group.required:\r
+ inserts[start] = '['\r
+ inserts[end] = ']'\r
+ else:\r
+ inserts[start] = '('\r
+ inserts[end] = ')'\r
+ for i in range(start + 1, end):\r
+ inserts[i] = '|'\r
+\r
+ # collect all actions format strings\r
+ parts = []\r
+ for i, action in enumerate(actions):\r
+\r
+ # suppressed arguments are marked with None\r
+ # remove | separators for suppressed arguments\r
+ if action.help is SUPPRESS:\r
+ parts.append(None)\r
+ if inserts.get(i) == '|':\r
+ inserts.pop(i)\r
+ elif inserts.get(i + 1) == '|':\r
+ inserts.pop(i + 1)\r
+\r
+ # produce all arg strings\r
+ elif not action.option_strings:\r
+ part = self._format_args(action, action.dest)\r
+\r
+ # if it's in a group, strip the outer []\r
+ if action in group_actions:\r
+ if part[0] == '[' and part[-1] == ']':\r
+ part = part[1:-1]\r
+\r
+ # add the action string to the list\r
+ parts.append(part)\r
+\r
+ # produce the first way to invoke the option in brackets\r
+ else:\r
+ option_string = action.option_strings[0]\r
+\r
+ # if the Optional doesn't take a value, format is:\r
+ # -s or --long\r
+ if action.nargs == 0:\r
+ part = '%s' % option_string\r
+\r
+ # if the Optional takes a value, format is:\r
+ # -s ARGS or --long ARGS\r
+ else:\r
+ default = action.dest.upper()\r
+ args_string = self._format_args(action, default)\r
+ part = '%s %s' % (option_string, args_string)\r
+\r
+ # make it look optional if it's not required or in a group\r
+ if not action.required and action not in group_actions:\r
+ part = '[%s]' % part\r
+\r
+ # add the action string to the list\r
+ parts.append(part)\r
+\r
+ # insert things at the necessary indices\r
+ for i in _sorted(inserts, reverse=True):\r
+ parts[i:i] = [inserts[i]]\r
+\r
+ # join all the action items with spaces\r
+ text = ' '.join([item for item in parts if item is not None])\r
+\r
+ # clean up separators for mutually exclusive groups\r
+ open = r'[\[(]'\r
+ close = r'[\])]'\r
+ text = _re.sub(r'(%s) ' % open, r'\1', text)\r
+ text = _re.sub(r' (%s)' % close, r'\1', text)\r
+ text = _re.sub(r'%s *%s' % (open, close), r'', text)\r
+ text = _re.sub(r'\(([^|]*)\)', r'\1', text)\r
+ text = text.strip()\r
+\r
+ # return the text\r
+ return text\r
+\r
+ def _format_text(self, text):\r
+ if '%(prog)' in text:\r
+ text = text % dict(prog=self._prog)\r
+ text_width = self._width - self._current_indent\r
+ indent = ' ' * self._current_indent\r
+ return self._fill_text(text, text_width, indent) + '\n\n'\r
+\r
+ def _format_action(self, action):\r
+ # determine the required width and the entry label\r
+ help_position = min(self._action_max_length + 2,\r
+ self._max_help_position)\r
+ help_width = self._width - help_position\r
+ action_width = help_position - self._current_indent - 2\r
+ action_header = self._format_action_invocation(action)\r
+\r
+ # ho nelp; start on same line and add a final newline\r
+ if not action.help:\r
+ tup = self._current_indent, '', action_header\r
+ action_header = '%*s%s\n' % tup\r
+\r
+ # short action name; start on the same line and pad two spaces\r
+ elif len(action_header) <= action_width:\r
+ tup = self._current_indent, '', action_width, action_header\r
+ action_header = '%*s%-*s ' % tup\r
+ indent_first = 0\r
+\r
+ # long action name; start on the next line\r
+ else:\r
+ tup = self._current_indent, '', action_header\r
+ action_header = '%*s%s\n' % tup\r
+ indent_first = help_position\r
+\r
+ # collect the pieces of the action help\r
+ parts = [action_header]\r
+\r
+ # if there was help for the action, add lines of help text\r
+ if action.help:\r
+ help_text = self._expand_help(action)\r
+ help_lines = self._split_lines(help_text, help_width)\r
+ parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))\r
+ for line in help_lines[1:]:\r
+ parts.append('%*s%s\n' % (help_position, '', line))\r
+\r
+ # or add a newline if the description doesn't end with one\r
+ elif not action_header.endswith('\n'):\r
+ parts.append('\n')\r
+\r
+ # if there are any sub-actions, add their help as well\r
+ for subaction in self._iter_indented_subactions(action):\r
+ parts.append(self._format_action(subaction))\r
+\r
+ # return a single string\r
+ return self._join_parts(parts)\r
+\r
+ def _format_action_invocation(self, action):\r
+ if not action.option_strings:\r
+ metavar, = self._metavar_formatter(action, action.dest)(1)\r
+ return metavar\r
+\r
+ else:\r
+ parts = []\r
+\r
+ # if the Optional doesn't take a value, format is:\r
+ # -s, --long\r
+ if action.nargs == 0:\r
+ parts.extend(action.option_strings)\r
+\r
+ # if the Optional takes a value, format is:\r
+ # -s ARGS, --long ARGS\r
+ else:\r
+ default = action.dest.upper()\r
+ args_string = self._format_args(action, default)\r
+ for option_string in action.option_strings:\r
+ parts.append('%s %s' % (option_string, args_string))\r
+\r
+ return ', '.join(parts)\r
+\r
+ def _metavar_formatter(self, action, default_metavar):\r
+ if action.metavar is not None:\r
+ result = action.metavar\r
+ elif action.choices is not None:\r
+ choice_strs = [str(choice) for choice in action.choices]\r
+ result = '{%s}' % ','.join(choice_strs)\r
+ else:\r
+ result = default_metavar\r
+\r
+ def format(tuple_size):\r
+ if isinstance(result, tuple):\r
+ return result\r
+ else:\r
+ return (result, ) * tuple_size\r
+ return format\r
+\r
+ def _format_args(self, action, default_metavar):\r
+ get_metavar = self._metavar_formatter(action, default_metavar)\r
+ if action.nargs is None:\r
+ result = '%s' % get_metavar(1)\r
+ elif action.nargs == OPTIONAL:\r
+ result = '[%s]' % get_metavar(1)\r
+ elif action.nargs == ZERO_OR_MORE:\r
+ result = '[%s [%s ...]]' % get_metavar(2)\r
+ elif action.nargs == ONE_OR_MORE:\r
+ result = '%s [%s ...]' % get_metavar(2)\r
+ elif action.nargs == REMAINDER:\r
+ result = '...'\r
+ elif action.nargs == PARSER:\r
+ result = '%s ...' % get_metavar(1)\r
+ else:\r
+ formats = ['%s' for _ in range(action.nargs)]\r
+ result = ' '.join(formats) % get_metavar(action.nargs)\r
+ return result\r
+\r
+ def _expand_help(self, action):\r
+ params = dict(vars(action), prog=self._prog)\r
+ for name in list(params):\r
+ if params[name] is SUPPRESS:\r
+ del params[name]\r
+ for name in list(params):\r
+ if hasattr(params[name], '__name__'):\r
+ params[name] = params[name].__name__\r
+ if params.get('choices') is not None:\r
+ choices_str = ', '.join([str(c) for c in params['choices']])\r
+ params['choices'] = choices_str\r
+ return self._get_help_string(action) % params\r
+\r
+ def _iter_indented_subactions(self, action):\r
+ try:\r
+ get_subactions = action._get_subactions\r
+ except AttributeError:\r
+ pass\r
+ else:\r
+ self._indent()\r
+ for subaction in get_subactions():\r
+ yield subaction\r
+ self._dedent()\r
+\r
+ def _split_lines(self, text, width):\r
+ text = self._whitespace_matcher.sub(' ', text).strip()\r
+ return _textwrap.wrap(text, width)\r
+\r
+ def _fill_text(self, text, width, indent):\r
+ text = self._whitespace_matcher.sub(' ', text).strip()\r
+ return _textwrap.fill(text, width, initial_indent=indent,\r
+ subsequent_indent=indent)\r
+\r
+ def _get_help_string(self, action):\r
+ return action.help\r
+\r
+\r
+class RawDescriptionHelpFormatter(HelpFormatter):\r
+ """Help message formatter which retains any formatting in descriptions.\r
+\r
+ Only the name of this class is considered a public API. All the methods\r
+ provided by the class are considered an implementation detail.\r
+ """\r
+\r
+ def _fill_text(self, text, width, indent):\r
+ return ''.join([indent + line for line in text.splitlines(True)])\r
+\r
+\r
+class RawTextHelpFormatter(RawDescriptionHelpFormatter):\r
+ """Help message formatter which retains formatting of all help text.\r
+\r
+ Only the name of this class is considered a public API. All the methods\r
+ provided by the class are considered an implementation detail.\r
+ """\r
+\r
+ def _split_lines(self, text, width):\r
+ return text.splitlines()\r
+\r
+\r
+class ArgumentDefaultsHelpFormatter(HelpFormatter):\r
+ """Help message formatter which adds default values to argument help.\r
+\r
+ Only the name of this class is considered a public API. All the methods\r
+ provided by the class are considered an implementation detail.\r
+ """\r
+\r
+ def _get_help_string(self, action):\r
+ help = action.help\r
+ if '%(default)' not in action.help:\r
+ if action.default is not SUPPRESS:\r
+ defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]\r
+ if action.option_strings or action.nargs in defaulting_nargs:\r
+ help += ' (default: %(default)s)'\r
+ return help\r
+\r
+\r
+# =====================\r
+# Options and Arguments\r
+# =====================\r
+\r
+def _get_action_name(argument):\r
+ if argument is None:\r
+ return None\r
+ elif argument.option_strings:\r
+ return '/'.join(argument.option_strings)\r
+ elif argument.metavar not in (None, SUPPRESS):\r
+ return argument.metavar\r
+ elif argument.dest not in (None, SUPPRESS):\r
+ return argument.dest\r
+ else:\r
+ return None\r
+\r
+\r
+class ArgumentError(Exception):\r
+ """An error from creating or using an argument (optional or positional).\r
+\r
+ The string value of this exception is the message, augmented with\r
+ information about the argument that caused it.\r
+ """\r
+\r
+ def __init__(self, argument, message):\r
+ self.argument_name = _get_action_name(argument)\r
+ self.message = message\r
+\r
+ def __str__(self):\r
+ if self.argument_name is None:\r
+ format = '%(message)s'\r
+ else:\r
+ format = 'argument %(argument_name)s: %(message)s'\r
+ return format % dict(message=self.message,\r
+ argument_name=self.argument_name)\r
+\r
+\r
+class ArgumentTypeError(Exception):\r
+ """An error from trying to convert a command line string to a type."""\r
+ pass\r
+\r
+\r
+# ==============\r
+# Action classes\r
+# ==============\r
+\r
+class Action(_AttributeHolder):\r
+ """Information about how to convert command line strings to Python objects.\r
+\r
+ Action objects are used by an ArgumentParser to represent the information\r
+ needed to parse a single argument from one or more strings from the\r
+ command line. The keyword arguments to the Action constructor are also\r
+ all attributes of Action instances.\r
+\r
+ Keyword Arguments:\r
+\r
+ - option_strings -- A list of command-line option strings which\r
+ should be associated with this action.\r
+\r
+ - dest -- The name of the attribute to hold the created object(s)\r
+\r
+ - nargs -- The number of command-line arguments that should be\r
+ consumed. By default, one argument will be consumed and a single\r
+ value will be produced. Other values include:\r
+ - N (an integer) consumes N arguments (and produces a list)\r
+ - '?' consumes zero or one arguments\r
+ - '*' consumes zero or more arguments (and produces a list)\r
+ - '+' consumes one or more arguments (and produces a list)\r
+ Note that the difference between the default and nargs=1 is that\r
+ with the default, a single value will be produced, while with\r
+ nargs=1, a list containing a single value will be produced.\r
+\r
+ - const -- The value to be produced if the option is specified and the\r
+ option uses an action that takes no values.\r
+\r
+ - default -- The value to be produced if the option is not specified.\r
+\r
+ - type -- The type which the command-line arguments should be converted\r
+ to, should be one of 'string', 'int', 'float', 'complex' or a\r
+ callable object that accepts a single string argument. If None,\r
+ 'string' is assumed.\r
+\r
+ - choices -- A container of values that should be allowed. If not None,\r
+ after a command-line argument has been converted to the appropriate\r
+ type, an exception will be raised if it is not a member of this\r
+ collection.\r
+\r
+ - required -- True if the action must always be specified at the\r
+ command line. This is only meaningful for optional command-line\r
+ arguments.\r
+\r
+ - help -- The help string describing the argument.\r
+\r
+ - metavar -- The name to be used for the option's argument with the\r
+ help string. If None, the 'dest' value will be used as the name.\r
+ """\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ nargs=None,\r
+ const=None,\r
+ default=None,\r
+ type=None,\r
+ choices=None,\r
+ required=False,\r
+ help=None,\r
+ metavar=None):\r
+ self.option_strings = option_strings\r
+ self.dest = dest\r
+ self.nargs = nargs\r
+ self.const = const\r
+ self.default = default\r
+ self.type = type\r
+ self.choices = choices\r
+ self.required = required\r
+ self.help = help\r
+ self.metavar = metavar\r
+\r
+ def _get_kwargs(self):\r
+ names = [\r
+ 'option_strings',\r
+ 'dest',\r
+ 'nargs',\r
+ 'const',\r
+ 'default',\r
+ 'type',\r
+ 'choices',\r
+ 'help',\r
+ 'metavar',\r
+ ]\r
+ return [(name, getattr(self, name)) for name in names]\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ raise NotImplementedError(_('.__call__() not defined'))\r
+\r
+\r
+class _StoreAction(Action):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ nargs=None,\r
+ const=None,\r
+ default=None,\r
+ type=None,\r
+ choices=None,\r
+ required=False,\r
+ help=None,\r
+ metavar=None):\r
+ if nargs == 0:\r
+ raise ValueError('nargs for store actions must be > 0; if you '\r
+ 'have nothing to store, actions such as store '\r
+ 'true or store const may be more appropriate')\r
+ if const is not None and nargs != OPTIONAL:\r
+ raise ValueError('nargs must be %r to supply const' % OPTIONAL)\r
+ super(_StoreAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ nargs=nargs,\r
+ const=const,\r
+ default=default,\r
+ type=type,\r
+ choices=choices,\r
+ required=required,\r
+ help=help,\r
+ metavar=metavar)\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ setattr(namespace, self.dest, values)\r
+\r
+\r
+class _StoreConstAction(Action):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ const,\r
+ default=None,\r
+ required=False,\r
+ help=None,\r
+ metavar=None):\r
+ super(_StoreConstAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ nargs=0,\r
+ const=const,\r
+ default=default,\r
+ required=required,\r
+ help=help)\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ setattr(namespace, self.dest, self.const)\r
+\r
+\r
+class _StoreTrueAction(_StoreConstAction):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ default=False,\r
+ required=False,\r
+ help=None):\r
+ super(_StoreTrueAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ const=True,\r
+ default=default,\r
+ required=required,\r
+ help=help)\r
+\r
+\r
+class _StoreFalseAction(_StoreConstAction):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ default=True,\r
+ required=False,\r
+ help=None):\r
+ super(_StoreFalseAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ const=False,\r
+ default=default,\r
+ required=required,\r
+ help=help)\r
+\r
+\r
+class _AppendAction(Action):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ nargs=None,\r
+ const=None,\r
+ default=None,\r
+ type=None,\r
+ choices=None,\r
+ required=False,\r
+ help=None,\r
+ metavar=None):\r
+ if nargs == 0:\r
+ raise ValueError('nargs for append actions must be > 0; if arg '\r
+ 'strings are not supplying the value to append, '\r
+ 'the append const action may be more appropriate')\r
+ if const is not None and nargs != OPTIONAL:\r
+ raise ValueError('nargs must be %r to supply const' % OPTIONAL)\r
+ super(_AppendAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ nargs=nargs,\r
+ const=const,\r
+ default=default,\r
+ type=type,\r
+ choices=choices,\r
+ required=required,\r
+ help=help,\r
+ metavar=metavar)\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ items = _copy.copy(_ensure_value(namespace, self.dest, []))\r
+ items.append(values)\r
+ setattr(namespace, self.dest, items)\r
+\r
+\r
+class _AppendConstAction(Action):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ const,\r
+ default=None,\r
+ required=False,\r
+ help=None,\r
+ metavar=None):\r
+ super(_AppendConstAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ nargs=0,\r
+ const=const,\r
+ default=default,\r
+ required=required,\r
+ help=help,\r
+ metavar=metavar)\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ items = _copy.copy(_ensure_value(namespace, self.dest, []))\r
+ items.append(self.const)\r
+ setattr(namespace, self.dest, items)\r
+\r
+\r
+class _CountAction(Action):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest,\r
+ default=None,\r
+ required=False,\r
+ help=None):\r
+ super(_CountAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ nargs=0,\r
+ default=default,\r
+ required=required,\r
+ help=help)\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ new_count = _ensure_value(namespace, self.dest, 0) + 1\r
+ setattr(namespace, self.dest, new_count)\r
+\r
+\r
+class _HelpAction(Action):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ dest=SUPPRESS,\r
+ default=SUPPRESS,\r
+ help=None):\r
+ super(_HelpAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ default=default,\r
+ nargs=0,\r
+ help=help)\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ parser.print_help()\r
+ parser.exit()\r
+\r
+\r
+class _VersionAction(Action):\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ version=None,\r
+ dest=SUPPRESS,\r
+ default=SUPPRESS,\r
+ help=None):\r
+ super(_VersionAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ default=default,\r
+ nargs=0,\r
+ help=help)\r
+ self.version = version\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ version = self.version\r
+ if version is None:\r
+ version = parser.version\r
+ formatter = parser._get_formatter()\r
+ formatter.add_text(version)\r
+ parser.exit(message=formatter.format_help())\r
+\r
+\r
+class _SubParsersAction(Action):\r
+\r
+ class _ChoicesPseudoAction(Action):\r
+\r
+ def __init__(self, name, help):\r
+ sup = super(_SubParsersAction._ChoicesPseudoAction, self)\r
+ sup.__init__(option_strings=[], dest=name, help=help)\r
+\r
+ def __init__(self,\r
+ option_strings,\r
+ prog,\r
+ parser_class,\r
+ dest=SUPPRESS,\r
+ help=None,\r
+ metavar=None):\r
+\r
+ self._prog_prefix = prog\r
+ self._parser_class = parser_class\r
+ self._name_parser_map = {}\r
+ self._choices_actions = []\r
+\r
+ super(_SubParsersAction, self).__init__(\r
+ option_strings=option_strings,\r
+ dest=dest,\r
+ nargs=PARSER,\r
+ choices=self._name_parser_map,\r
+ help=help,\r
+ metavar=metavar)\r
+\r
+ def add_parser(self, name, **kwargs):\r
+ # set prog from the existing prefix\r
+ if kwargs.get('prog') is None:\r
+ kwargs['prog'] = '%s %s' % (self._prog_prefix, name)\r
+\r
+ # create a pseudo-action to hold the choice help\r
+ if 'help' in kwargs:\r
+ help = kwargs.pop('help')\r
+ choice_action = self._ChoicesPseudoAction(name, help)\r
+ self._choices_actions.append(choice_action)\r
+\r
+ # create the parser and add it to the map\r
+ parser = self._parser_class(**kwargs)\r
+ self._name_parser_map[name] = parser\r
+ return parser\r
+\r
+ def _get_subactions(self):\r
+ return self._choices_actions\r
+\r
+ def __call__(self, parser, namespace, values, option_string=None):\r
+ parser_name = values[0]\r
+ arg_strings = values[1:]\r
+\r
+ # set the parser name if requested\r
+ if self.dest is not SUPPRESS:\r
+ setattr(namespace, self.dest, parser_name)\r
+\r
+ # select the parser\r
+ try:\r
+ parser = self._name_parser_map[parser_name]\r
+ except KeyError:\r
+ tup = parser_name, ', '.join(self._name_parser_map)\r
+ msg = _('unknown parser %r (choices: %s)' % tup)\r
+ raise ArgumentError(self, msg)\r
+\r
+ # parse all the remaining options into the namespace\r
+ parser.parse_args(arg_strings, namespace)\r
+\r
+\r
+# ==============\r
+# Type classes\r
+# ==============\r
+\r
+class FileType(object):\r
+ """Factory for creating file object types\r
+\r
+ Instances of FileType are typically passed as type= arguments to the\r
+ ArgumentParser add_argument() method.\r
+\r
+ Keyword Arguments:\r
+ - mode -- A string indicating how the file is to be opened. Accepts the\r
+ same values as the builtin open() function.\r
+ - bufsize -- The file's desired buffer size. Accepts the same values as\r
+ the builtin open() function.\r
+ """\r
+\r
+ def __init__(self, mode='r', bufsize=None):\r
+ self._mode = mode\r
+ self._bufsize = bufsize\r
+\r
+ def __call__(self, string):\r
+ # the special argument "-" means sys.std{in,out}\r
+ if string == '-':\r
+ if 'r' in self._mode:\r
+ return _sys.stdin\r
+ elif 'w' in self._mode:\r
+ return _sys.stdout\r
+ else:\r
+ msg = _('argument "-" with mode %r' % self._mode)\r
+ raise ValueError(msg)\r
+\r
+ # all other arguments are used as file names\r
+ if self._bufsize:\r
+ return open(string, self._mode, self._bufsize)\r
+ else:\r
+ return open(string, self._mode)\r
+\r
+ def __repr__(self):\r
+ args = [self._mode, self._bufsize]\r
+ args_str = ', '.join([repr(arg) for arg in args if arg is not None])\r
+ return '%s(%s)' % (type(self).__name__, args_str)\r
+\r
+# ===========================\r
+# Optional and Positional Parsing\r
+# ===========================\r
+\r
+class Namespace(_AttributeHolder):\r
+ """Simple object for storing attributes.\r
+\r
+ Implements equality by attribute names and values, and provides a simple\r
+ string representation.\r
+ """\r
+\r
+ def __init__(self, **kwargs):\r
+ for name in kwargs:\r
+ setattr(self, name, kwargs[name])\r
+\r
+ def __eq__(self, other):\r
+ return vars(self) == vars(other)\r
+\r
+ def __ne__(self, other):\r
+ return not (self == other)\r
+\r
+ def __contains__(self, key):\r
+ return key in self.__dict__\r
+\r
+\r
+class _ActionsContainer(object):\r
+\r
+ def __init__(self,\r
+ description,\r
+ prefix_chars,\r
+ argument_default,\r
+ conflict_handler):\r
+ super(_ActionsContainer, self).__init__()\r
+\r
+ self.description = description\r
+ self.argument_default = argument_default\r
+ self.prefix_chars = prefix_chars\r
+ self.conflict_handler = conflict_handler\r
+\r
+ # set up registries\r
+ self._registries = {}\r
+\r
+ # register actions\r
+ self.register('action', None, _StoreAction)\r
+ self.register('action', 'store', _StoreAction)\r
+ self.register('action', 'store_const', _StoreConstAction)\r
+ self.register('action', 'store_true', _StoreTrueAction)\r
+ self.register('action', 'store_false', _StoreFalseAction)\r
+ self.register('action', 'append', _AppendAction)\r
+ self.register('action', 'append_const', _AppendConstAction)\r
+ self.register('action', 'count', _CountAction)\r
+ self.register('action', 'help', _HelpAction)\r
+ self.register('action', 'version', _VersionAction)\r
+ self.register('action', 'parsers', _SubParsersAction)\r
+\r
+ # raise an exception if the conflict handler is invalid\r
+ self._get_handler()\r
+\r
+ # action storage\r
+ self._actions = []\r
+ self._option_string_actions = {}\r
+\r
+ # groups\r
+ self._action_groups = []\r
+ self._mutually_exclusive_groups = []\r
+\r
+ # defaults storage\r
+ self._defaults = {}\r
+\r
+ # determines whether an "option" looks like a negative number\r
+ self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')\r
+\r
+ # whether or not there are any optionals that look like negative\r
+ # numbers -- uses a list so it can be shared and edited\r
+ self._has_negative_number_optionals = []\r
+\r
+ # ====================\r
+ # Registration methods\r
+ # ====================\r
+ def register(self, registry_name, value, object):\r
+ registry = self._registries.setdefault(registry_name, {})\r
+ registry[value] = object\r
+\r
+ def _registry_get(self, registry_name, value, default=None):\r
+ return self._registries[registry_name].get(value, default)\r
+\r
+ # ==================================\r
+ # Namespace default accessor methods\r
+ # ==================================\r
+ def set_defaults(self, **kwargs):\r
+ self._defaults.update(kwargs)\r
+\r
+ # if these defaults match any existing arguments, replace\r
+ # the previous default on the object with the new one\r
+ for action in self._actions:\r
+ if action.dest in kwargs:\r
+ action.default = kwargs[action.dest]\r
+\r
+ def get_default(self, dest):\r
+ for action in self._actions:\r
+ if action.dest == dest and action.default is not None:\r
+ return action.default\r
+ return self._defaults.get(dest, None)\r
+\r
+\r
+ # =======================\r
+ # Adding argument actions\r
+ # =======================\r
+ def add_argument(self, *args, **kwargs):\r
+ """\r
+ add_argument(dest, ..., name=value, ...)\r
+ add_argument(option_string, option_string, ..., name=value, ...)\r
+ """\r
+\r
+ # if no positional args are supplied or only one is supplied and\r
+ # it doesn't look like an option string, parse a positional\r
+ # argument\r
+ chars = self.prefix_chars\r
+ if not args or len(args) == 1 and args[0][0] not in chars:\r
+ if args and 'dest' in kwargs:\r
+ raise ValueError('dest supplied twice for positional argument')\r
+ kwargs = self._get_positional_kwargs(*args, **kwargs)\r
+\r
+ # otherwise, we're adding an optional argument\r
+ else:\r
+ kwargs = self._get_optional_kwargs(*args, **kwargs)\r
+\r
+ # if no default was supplied, use the parser-level default\r
+ if 'default' not in kwargs:\r
+ dest = kwargs['dest']\r
+ if dest in self._defaults:\r
+ kwargs['default'] = self._defaults[dest]\r
+ elif self.argument_default is not None:\r
+ kwargs['default'] = self.argument_default\r
+\r
+ # create the action object, and add it to the parser\r
+ action_class = self._pop_action_class(kwargs)\r
+ if not _callable(action_class):\r
+ raise ValueError('unknown action "%s"' % action_class)\r
+ action = action_class(**kwargs)\r
+\r
+ # raise an error if the action type is not callable\r
+ type_func = self._registry_get('type', action.type, action.type)\r
+ if not _callable(type_func):\r
+ raise ValueError('%r is not callable' % type_func)\r
+\r
+ return self._add_action(action)\r
+\r
+ def add_argument_group(self, *args, **kwargs):\r
+ group = _ArgumentGroup(self, *args, **kwargs)\r
+ self._action_groups.append(group)\r
+ return group\r
+\r
+ def add_mutually_exclusive_group(self, **kwargs):\r
+ group = _MutuallyExclusiveGroup(self, **kwargs)\r
+ self._mutually_exclusive_groups.append(group)\r
+ return group\r
+\r
+ def _add_action(self, action):\r
+ # resolve any conflicts\r
+ self._check_conflict(action)\r
+\r
+ # add to actions list\r
+ self._actions.append(action)\r
+ action.container = self\r
+\r
+ # index the action by any option strings it has\r
+ for option_string in action.option_strings:\r
+ self._option_string_actions[option_string] = action\r
+\r
+ # set the flag if any option strings look like negative numbers\r
+ for option_string in action.option_strings:\r
+ if self._negative_number_matcher.match(option_string):\r
+ if not self._has_negative_number_optionals:\r
+ self._has_negative_number_optionals.append(True)\r
+\r
+ # return the created action\r
+ return action\r
+\r
+ def _remove_action(self, action):\r
+ self._actions.remove(action)\r
+\r
+ def _add_container_actions(self, container):\r
+ # collect groups by titles\r
+ title_group_map = {}\r
+ for group in self._action_groups:\r
+ if group.title in title_group_map:\r
+ msg = _('cannot merge actions - two groups are named %r')\r
+ raise ValueError(msg % (group.title))\r
+ title_group_map[group.title] = group\r
+\r
+ # map each action to its group\r
+ group_map = {}\r
+ for group in container._action_groups:\r
+\r
+ # if a group with the title exists, use that, otherwise\r
+ # create a new group matching the container's group\r
+ if group.title not in title_group_map:\r
+ title_group_map[group.title] = self.add_argument_group(\r
+ title=group.title,\r
+ description=group.description,\r
+ conflict_handler=group.conflict_handler)\r
+\r
+ # map the actions to their new group\r
+ for action in group._group_actions:\r
+ group_map[action] = title_group_map[group.title]\r
+\r
+ # add container's mutually exclusive groups\r
+ # NOTE: if add_mutually_exclusive_group ever gains title= and\r
+ # description= then this code will need to be expanded as above\r
+ for group in container._mutually_exclusive_groups:\r
+ mutex_group = self.add_mutually_exclusive_group(\r
+ required=group.required)\r
+\r
+ # map the actions to their new mutex group\r
+ for action in group._group_actions:\r
+ group_map[action] = mutex_group\r
+\r
+ # add all actions to this container or their group\r
+ for action in container._actions:\r
+ group_map.get(action, self)._add_action(action)\r
+\r
+ def _get_positional_kwargs(self, dest, **kwargs):\r
+ # make sure required is not specified\r
+ if 'required' in kwargs:\r
+ msg = _("'required' is an invalid argument for positionals")\r
+ raise TypeError(msg)\r
+\r
+ # mark positional arguments as required if at least one is\r
+ # always required\r
+ if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:\r
+ kwargs['required'] = True\r
+ if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:\r
+ kwargs['required'] = True\r
+\r
+ # return the keyword arguments with no option strings\r
+ return dict(kwargs, dest=dest, option_strings=[])\r
+\r
+ def _get_optional_kwargs(self, *args, **kwargs):\r
+ # determine short and long option strings\r
+ option_strings = []\r
+ long_option_strings = []\r
+ for option_string in args:\r
+ # error on strings that don't start with an appropriate prefix\r
+ if not option_string[0] in self.prefix_chars:\r
+ msg = _('invalid option string %r: '\r
+ 'must start with a character %r')\r
+ tup = option_string, self.prefix_chars\r
+ raise ValueError(msg % tup)\r
+\r
+ # strings starting with two prefix characters are long options\r
+ option_strings.append(option_string)\r
+ if option_string[0] in self.prefix_chars:\r
+ if len(option_string) > 1:\r
+ if option_string[1] in self.prefix_chars:\r
+ long_option_strings.append(option_string)\r
+\r
+ # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'\r
+ dest = kwargs.pop('dest', None)\r
+ if dest is None:\r
+ if long_option_strings:\r
+ dest_option_string = long_option_strings[0]\r
+ else:\r
+ dest_option_string = option_strings[0]\r
+ dest = dest_option_string.lstrip(self.prefix_chars)\r
+ if not dest:\r
+ msg = _('dest= is required for options like %r')\r
+ raise ValueError(msg % option_string)\r
+ dest = dest.replace('-', '_')\r
+\r
+ # return the updated keyword arguments\r
+ return dict(kwargs, dest=dest, option_strings=option_strings)\r
+\r
+ def _pop_action_class(self, kwargs, default=None):\r
+ action = kwargs.pop('action', default)\r
+ return self._registry_get('action', action, action)\r
+\r
+ def _get_handler(self):\r
+ # determine function from conflict handler string\r
+ handler_func_name = '_handle_conflict_%s' % self.conflict_handler\r
+ try:\r
+ return getattr(self, handler_func_name)\r
+ except AttributeError:\r
+ msg = _('invalid conflict_resolution value: %r')\r
+ raise ValueError(msg % self.conflict_handler)\r
+\r
+ def _check_conflict(self, action):\r
+\r
+ # find all options that conflict with this option\r
+ confl_optionals = []\r
+ for option_string in action.option_strings:\r
+ if option_string in self._option_string_actions:\r
+ confl_optional = self._option_string_actions[option_string]\r
+ confl_optionals.append((option_string, confl_optional))\r
+\r
+ # resolve any conflicts\r
+ if confl_optionals:\r
+ conflict_handler = self._get_handler()\r
+ conflict_handler(action, confl_optionals)\r
+\r
+ def _handle_conflict_error(self, action, conflicting_actions):\r
+ message = _('conflicting option string(s): %s')\r
+ conflict_string = ', '.join([option_string\r
+ for option_string, action\r
+ in conflicting_actions])\r
+ raise ArgumentError(action, message % conflict_string)\r
+\r
+ def _handle_conflict_resolve(self, action, conflicting_actions):\r
+\r
+ # remove all conflicting options\r
+ for option_string, action in conflicting_actions:\r
+\r
+ # remove the conflicting option\r
+ action.option_strings.remove(option_string)\r
+ self._option_string_actions.pop(option_string, None)\r
+\r
+ # if the option now has no option string, remove it from the\r
+ # container holding it\r
+ if not action.option_strings:\r
+ action.container._remove_action(action)\r
+\r
+\r
+class _ArgumentGroup(_ActionsContainer):\r
+\r
+ def __init__(self, container, title=None, description=None, **kwargs):\r
+ # add any missing keyword arguments by checking the container\r
+ update = kwargs.setdefault\r
+ update('conflict_handler', container.conflict_handler)\r
+ update('prefix_chars', container.prefix_chars)\r
+ update('argument_default', container.argument_default)\r
+ super_init = super(_ArgumentGroup, self).__init__\r
+ super_init(description=description, **kwargs)\r
+\r
+ # group attributes\r
+ self.title = title\r
+ self._group_actions = []\r
+\r
+ # share most attributes with the container\r
+ self._registries = container._registries\r
+ self._actions = container._actions\r
+ self._option_string_actions = container._option_string_actions\r
+ self._defaults = container._defaults\r
+ self._has_negative_number_optionals = \\r
+ container._has_negative_number_optionals\r
+\r
+ def _add_action(self, action):\r
+ action = super(_ArgumentGroup, self)._add_action(action)\r
+ self._group_actions.append(action)\r
+ return action\r
+\r
+ def _remove_action(self, action):\r
+ super(_ArgumentGroup, self)._remove_action(action)\r
+ self._group_actions.remove(action)\r
+\r
+\r
+class _MutuallyExclusiveGroup(_ArgumentGroup):\r
+\r
+ def __init__(self, container, required=False):\r
+ super(_MutuallyExclusiveGroup, self).__init__(container)\r
+ self.required = required\r
+ self._container = container\r
+\r
+ def _add_action(self, action):\r
+ if action.required:\r
+ msg = _('mutually exclusive arguments must be optional')\r
+ raise ValueError(msg)\r
+ action = self._container._add_action(action)\r
+ self._group_actions.append(action)\r
+ return action\r
+\r
+ def _remove_action(self, action):\r
+ self._container._remove_action(action)\r
+ self._group_actions.remove(action)\r
+\r
+\r
+class ArgumentParser(_AttributeHolder, _ActionsContainer):\r
+ """Object for parsing command line strings into Python objects.\r
+\r
+ Keyword Arguments:\r
+ - prog -- The name of the program (default: sys.argv[0])\r
+ - usage -- A usage message (default: auto-generated from arguments)\r
+ - description -- A description of what the program does\r
+ - epilog -- Text following the argument descriptions\r
+ - parents -- Parsers whose arguments should be copied into this one\r
+ - formatter_class -- HelpFormatter class for printing help messages\r
+ - prefix_chars -- Characters that prefix optional arguments\r
+ - fromfile_prefix_chars -- Characters that prefix files containing\r
+ additional arguments\r
+ - argument_default -- The default value for all arguments\r
+ - conflict_handler -- String indicating how to handle conflicts\r
+ - add_help -- Add a -h/-help option\r
+ """\r
+\r
+ def __init__(self,\r
+ prog=None,\r
+ usage=None,\r
+ description=None,\r
+ epilog=None,\r
+ version=None,\r
+ parents=[],\r
+ formatter_class=HelpFormatter,\r
+ prefix_chars='-',\r
+ fromfile_prefix_chars=None,\r
+ argument_default=None,\r
+ conflict_handler='error',\r
+ add_help=True):\r
+\r
+ if version is not None:\r
+ import warnings\r
+ warnings.warn(\r
+ """The "version" argument to ArgumentParser is deprecated. """\r
+ """Please use """\r
+ """"add_argument(..., action='version', version="N", ...)" """\r
+ """instead""", DeprecationWarning)\r
+\r
+ superinit = super(ArgumentParser, self).__init__\r
+ superinit(description=description,\r
+ prefix_chars=prefix_chars,\r
+ argument_default=argument_default,\r
+ conflict_handler=conflict_handler)\r
+\r
+ # default setting for prog\r
+ if prog is None:\r
+ prog = _os.path.basename(_sys.argv[0])\r
+\r
+ self.prog = prog\r
+ self.usage = usage\r
+ self.epilog = epilog\r
+ self.version = version\r
+ self.formatter_class = formatter_class\r
+ self.fromfile_prefix_chars = fromfile_prefix_chars\r
+ self.add_help = add_help\r
+\r
+ add_group = self.add_argument_group\r
+ self._positionals = add_group(_('positional arguments'))\r
+ self._optionals = add_group(_('optional arguments'))\r
+ self._subparsers = None\r
+\r
+ # register types\r
+ def identity(string):\r
+ return string\r
+ self.register('type', None, identity)\r
+\r
+ # add help and version arguments if necessary\r
+ # (using explicit default to override global argument_default)\r
+ if self.add_help:\r
+ self.add_argument(\r
+ '-h', '--help', action='help', default=SUPPRESS,\r
+ help=_('show this help message and exit'))\r
+ if self.version:\r
+ self.add_argument(\r
+ '-v', '--version', action='version', default=SUPPRESS,\r
+ version=self.version,\r
+ help=_("show program's version number and exit"))\r
+\r
+ # add parent arguments and defaults\r
+ for parent in parents:\r
+ self._add_container_actions(parent)\r
+ try:\r
+ defaults = parent._defaults\r
+ except AttributeError:\r
+ pass\r
+ else:\r
+ self._defaults.update(defaults)\r
+\r
+ # =======================\r
+ # Pretty __repr__ methods\r
+ # =======================\r
+ def _get_kwargs(self):\r
+ names = [\r
+ 'prog',\r
+ 'usage',\r
+ 'description',\r
+ 'version',\r
+ 'formatter_class',\r
+ 'conflict_handler',\r
+ 'add_help',\r
+ ]\r
+ return [(name, getattr(self, name)) for name in names]\r
+\r
+ # ==================================\r
+ # Optional/Positional adding methods\r
+ # ==================================\r
+ def add_subparsers(self, **kwargs):\r
+ if self._subparsers is not None:\r
+ self.error(_('cannot have multiple subparser arguments'))\r
+\r
+ # add the parser class to the arguments if it's not present\r
+ kwargs.setdefault('parser_class', type(self))\r
+\r
+ if 'title' in kwargs or 'description' in kwargs:\r
+ title = _(kwargs.pop('title', 'subcommands'))\r
+ description = _(kwargs.pop('description', None))\r
+ self._subparsers = self.add_argument_group(title, description)\r
+ else:\r
+ self._subparsers = self._positionals\r
+\r
+ # prog defaults to the usage message of this parser, skipping\r
+ # optional arguments and with no "usage:" prefix\r
+ if kwargs.get('prog') is None:\r
+ formatter = self._get_formatter()\r
+ positionals = self._get_positional_actions()\r
+ groups = self._mutually_exclusive_groups\r
+ formatter.add_usage(self.usage, positionals, groups, '')\r
+ kwargs['prog'] = formatter.format_help().strip()\r
+\r
+ # create the parsers action and add it to the positionals list\r
+ parsers_class = self._pop_action_class(kwargs, 'parsers')\r
+ action = parsers_class(option_strings=[], **kwargs)\r
+ self._subparsers._add_action(action)\r
+\r
+ # return the created parsers action\r
+ return action\r
+\r
+ def _add_action(self, action):\r
+ if action.option_strings:\r
+ self._optionals._add_action(action)\r
+ else:\r
+ self._positionals._add_action(action)\r
+ return action\r
+\r
+ def _get_optional_actions(self):\r
+ return [action\r
+ for action in self._actions\r
+ if action.option_strings]\r
+\r
+ def _get_positional_actions(self):\r
+ return [action\r
+ for action in self._actions\r
+ if not action.option_strings]\r
+\r
+ # =====================================\r
+ # Command line argument parsing methods\r
+ # =====================================\r
+ def parse_args(self, args=None, namespace=None):\r
+ args, argv = self.parse_known_args(args, namespace)\r
+ if argv:\r
+ msg = _('unrecognized arguments: %s')\r
+ self.error(msg % ' '.join(argv))\r
+ return args\r
+\r
+ def parse_known_args(self, args=None, namespace=None):\r
+ # args default to the system args\r
+ if args is None:\r
+ args = _sys.argv[1:]\r
+\r
+ # default Namespace built from parser defaults\r
+ if namespace is None:\r
+ namespace = Namespace()\r
+\r
+ # add any action defaults that aren't present\r
+ for action in self._actions:\r
+ if action.dest is not SUPPRESS:\r
+ if not hasattr(namespace, action.dest):\r
+ if action.default is not SUPPRESS:\r
+ default = action.default\r
+ if isinstance(action.default, _basestring):\r
+ default = self._get_value(action, default)\r
+ setattr(namespace, action.dest, default)\r
+\r
+ # add any parser defaults that aren't present\r
+ for dest in self._defaults:\r
+ if not hasattr(namespace, dest):\r
+ setattr(namespace, dest, self._defaults[dest])\r
+\r
+ # parse the arguments and exit if there are any errors\r
+ try:\r
+ return self._parse_known_args(args, namespace)\r
+ except ArgumentError:\r
+ err = _sys.exc_info()[1]\r
+ self.error(str(err))\r
+\r
+ def _parse_known_args(self, arg_strings, namespace):\r
+ # replace arg strings that are file references\r
+ if self.fromfile_prefix_chars is not None:\r
+ arg_strings = self._read_args_from_files(arg_strings)\r
+\r
+ # map all mutually exclusive arguments to the other arguments\r
+ # they can't occur with\r
+ action_conflicts = {}\r
+ for mutex_group in self._mutually_exclusive_groups:\r
+ group_actions = mutex_group._group_actions\r
+ for i, mutex_action in enumerate(mutex_group._group_actions):\r
+ conflicts = action_conflicts.setdefault(mutex_action, [])\r
+ conflicts.extend(group_actions[:i])\r
+ conflicts.extend(group_actions[i + 1:])\r
+\r
+ # find all option indices, and determine the arg_string_pattern\r
+ # which has an 'O' if there is an option at an index,\r
+ # an 'A' if there is an argument, or a '-' if there is a '--'\r
+ option_string_indices = {}\r
+ arg_string_pattern_parts = []\r
+ arg_strings_iter = iter(arg_strings)\r
+ for i, arg_string in enumerate(arg_strings_iter):\r
+\r
+ # all args after -- are non-options\r
+ if arg_string == '--':\r
+ arg_string_pattern_parts.append('-')\r
+ for arg_string in arg_strings_iter:\r
+ arg_string_pattern_parts.append('A')\r
+\r
+ # otherwise, add the arg to the arg strings\r
+ # and note the index if it was an option\r
+ else:\r
+ option_tuple = self._parse_optional(arg_string)\r
+ if option_tuple is None:\r
+ pattern = 'A'\r
+ else:\r
+ option_string_indices[i] = option_tuple\r
+ pattern = 'O'\r
+ arg_string_pattern_parts.append(pattern)\r
+\r
+ # join the pieces together to form the pattern\r
+ arg_strings_pattern = ''.join(arg_string_pattern_parts)\r
+\r
+ # converts arg strings to the appropriate and then takes the action\r
+ seen_actions = _set()\r
+ seen_non_default_actions = _set()\r
+\r
+ def take_action(action, argument_strings, option_string=None):\r
+ seen_actions.add(action)\r
+ argument_values = self._get_values(action, argument_strings)\r
+\r
+ # error if this argument is not allowed with other previously\r
+ # seen arguments, assuming that actions that use the default\r
+ # value don't really count as "present"\r
+ if argument_values is not action.default:\r
+ seen_non_default_actions.add(action)\r
+ for conflict_action in action_conflicts.get(action, []):\r
+ if conflict_action in seen_non_default_actions:\r
+ msg = _('not allowed with argument %s')\r
+ action_name = _get_action_name(conflict_action)\r
+ raise ArgumentError(action, msg % action_name)\r
+\r
+ # take the action if we didn't receive a SUPPRESS value\r
+ # (e.g. from a default)\r
+ if argument_values is not SUPPRESS:\r
+ action(self, namespace, argument_values, option_string)\r
+\r
+ # function to convert arg_strings into an optional action\r
+ def consume_optional(start_index):\r
+\r
+ # get the optional identified at this index\r
+ option_tuple = option_string_indices[start_index]\r
+ action, option_string, explicit_arg = option_tuple\r
+\r
+ # identify additional optionals in the same arg string\r
+ # (e.g. -xyz is the same as -x -y -z if no args are required)\r
+ match_argument = self._match_argument\r
+ action_tuples = []\r
+ while True:\r
+\r
+ # if we found no optional action, skip it\r
+ if action is None:\r
+ extras.append(arg_strings[start_index])\r
+ return start_index + 1\r
+\r
+ # if there is an explicit argument, try to match the\r
+ # optional's string arguments to only this\r
+ if explicit_arg is not None:\r
+ arg_count = match_argument(action, 'A')\r
+\r
+ # if the action is a single-dash option and takes no\r
+ # arguments, try to parse more single-dash options out\r
+ # of the tail of the option string\r
+ chars = self.prefix_chars\r
+ if arg_count == 0 and option_string[1] not in chars:\r
+ action_tuples.append((action, [], option_string))\r
+ for char in self.prefix_chars:\r
+ option_string = char + explicit_arg[0]\r
+ explicit_arg = explicit_arg[1:] or None\r
+ optionals_map = self._option_string_actions\r
+ if option_string in optionals_map:\r
+ action = optionals_map[option_string]\r
+ break\r
+ else:\r
+ msg = _('ignored explicit argument %r')\r
+ raise ArgumentError(action, msg % explicit_arg)\r
+\r
+ # if the action expect exactly one argument, we've\r
+ # successfully matched the option; exit the loop\r
+ elif arg_count == 1:\r
+ stop = start_index + 1\r
+ args = [explicit_arg]\r
+ action_tuples.append((action, args, option_string))\r
+ break\r
+\r
+ # error if a double-dash option did not use the\r
+ # explicit argument\r
+ else:\r
+ msg = _('ignored explicit argument %r')\r
+ raise ArgumentError(action, msg % explicit_arg)\r
+\r
+ # if there is no explicit argument, try to match the\r
+ # optional's string arguments with the following strings\r
+ # if successful, exit the loop\r
+ else:\r
+ start = start_index + 1\r
+ selected_patterns = arg_strings_pattern[start:]\r
+ arg_count = match_argument(action, selected_patterns)\r
+ stop = start + arg_count\r
+ args = arg_strings[start:stop]\r
+ action_tuples.append((action, args, option_string))\r
+ break\r
+\r
+ # add the Optional to the list and return the index at which\r
+ # the Optional's string args stopped\r
+ assert action_tuples\r
+ for action, args, option_string in action_tuples:\r
+ take_action(action, args, option_string)\r
+ return stop\r
+\r
+ # the list of Positionals left to be parsed; this is modified\r
+ # by consume_positionals()\r
+ positionals = self._get_positional_actions()\r
+\r
+ # function to convert arg_strings into positional actions\r
+ def consume_positionals(start_index):\r
+ # match as many Positionals as possible\r
+ match_partial = self._match_arguments_partial\r
+ selected_pattern = arg_strings_pattern[start_index:]\r
+ arg_counts = match_partial(positionals, selected_pattern)\r
+\r
+ # slice off the appropriate arg strings for each Positional\r
+ # and add the Positional and its args to the list\r
+ for action, arg_count in zip(positionals, arg_counts):\r
+ args = arg_strings[start_index: start_index + arg_count]\r
+ start_index += arg_count\r
+ take_action(action, args)\r
+\r
+ # slice off the Positionals that we just parsed and return the\r
+ # index at which the Positionals' string args stopped\r
+ positionals[:] = positionals[len(arg_counts):]\r
+ return start_index\r
+\r
+ # consume Positionals and Optionals alternately, until we have\r
+ # passed the last option string\r
+ extras = []\r
+ start_index = 0\r
+ if option_string_indices:\r
+ max_option_string_index = max(option_string_indices)\r
+ else:\r
+ max_option_string_index = -1\r
+ while start_index <= max_option_string_index:\r
+\r
+ # consume any Positionals preceding the next option\r
+ next_option_string_index = min([\r
+ index\r
+ for index in option_string_indices\r
+ if index >= start_index])\r
+ if start_index != next_option_string_index:\r
+ positionals_end_index = consume_positionals(start_index)\r
+\r
+ # only try to parse the next optional if we didn't consume\r
+ # the option string during the positionals parsing\r
+ if positionals_end_index > start_index:\r
+ start_index = positionals_end_index\r
+ continue\r
+ else:\r
+ start_index = positionals_end_index\r
+\r
+ # if we consumed all the positionals we could and we're not\r
+ # at the index of an option string, there were extra arguments\r
+ if start_index not in option_string_indices:\r
+ strings = arg_strings[start_index:next_option_string_index]\r
+ extras.extend(strings)\r
+ start_index = next_option_string_index\r
+\r
+ # consume the next optional and any arguments for it\r
+ start_index = consume_optional(start_index)\r
+\r
+ # consume any positionals following the last Optional\r
+ stop_index = consume_positionals(start_index)\r
+\r
+ # if we didn't consume all the argument strings, there were extras\r
+ extras.extend(arg_strings[stop_index:])\r
+\r
+ # if we didn't use all the Positional objects, there were too few\r
+ # arg strings supplied.\r
+ if positionals:\r
+ self.error(_('too few arguments'))\r
+\r
+ # make sure all required actions were present\r
+ for action in self._actions:\r
+ if action.required:\r
+ if action not in seen_actions:\r
+ name = _get_action_name(action)\r
+ self.error(_('argument %s is required') % name)\r
+\r
+ # make sure all required groups had one option present\r
+ for group in self._mutually_exclusive_groups:\r
+ if group.required:\r
+ for action in group._group_actions:\r
+ if action in seen_non_default_actions:\r
+ break\r
+\r
+ # if no actions were used, report the error\r
+ else:\r
+ names = [_get_action_name(action)\r
+ for action in group._group_actions\r
+ if action.help is not SUPPRESS]\r
+ msg = _('one of the arguments %s is required')\r
+ self.error(msg % ' '.join(names))\r
+\r
+ # return the updated namespace and the extra arguments\r
+ return namespace, extras\r
+\r
+ def _read_args_from_files(self, arg_strings):\r
+ # expand arguments referencing files\r
+ new_arg_strings = []\r
+ for arg_string in arg_strings:\r
+\r
+ # for regular arguments, just add them back into the list\r
+ if arg_string[0] not in self.fromfile_prefix_chars:\r
+ new_arg_strings.append(arg_string)\r
+\r
+ # replace arguments referencing files with the file content\r
+ else:\r
+ try:\r
+ args_file = open(arg_string[1:])\r
+ try:\r
+ arg_strings = []\r
+ for arg_line in args_file.read().splitlines():\r
+ for arg in self.convert_arg_line_to_args(arg_line):\r
+ arg_strings.append(arg)\r
+ arg_strings = self._read_args_from_files(arg_strings)\r
+ new_arg_strings.extend(arg_strings)\r
+ finally:\r
+ args_file.close()\r
+ except IOError:\r
+ err = _sys.exc_info()[1]\r
+ self.error(str(err))\r
+\r
+ # return the modified argument list\r
+ return new_arg_strings\r
+\r
+ def convert_arg_line_to_args(self, arg_line):\r
+ return [arg_line]\r
+\r
+ def _match_argument(self, action, arg_strings_pattern):\r
+ # match the pattern for this action to the arg strings\r
+ nargs_pattern = self._get_nargs_pattern(action)\r
+ match = _re.match(nargs_pattern, arg_strings_pattern)\r
+\r
+ # raise an exception if we weren't able to find a match\r
+ if match is None:\r
+ nargs_errors = {\r
+ None: _('expected one argument'),\r
+ OPTIONAL: _('expected at most one argument'),\r
+ ONE_OR_MORE: _('expected at least one argument'),\r
+ }\r
+ default = _('expected %s argument(s)') % action.nargs\r
+ msg = nargs_errors.get(action.nargs, default)\r
+ raise ArgumentError(action, msg)\r
+\r
+ # return the number of arguments matched\r
+ return len(match.group(1))\r
+\r
+ def _match_arguments_partial(self, actions, arg_strings_pattern):\r
+ # progressively shorten the actions list by slicing off the\r
+ # final actions until we find a match\r
+ result = []\r
+ for i in range(len(actions), 0, -1):\r
+ actions_slice = actions[:i]\r
+ pattern = ''.join([self._get_nargs_pattern(action)\r
+ for action in actions_slice])\r
+ match = _re.match(pattern, arg_strings_pattern)\r
+ if match is not None:\r
+ result.extend([len(string) for string in match.groups()])\r
+ break\r
+\r
+ # return the list of arg string counts\r
+ return result\r
+\r
+ def _parse_optional(self, arg_string):\r
+ # if it's an empty string, it was meant to be a positional\r
+ if not arg_string:\r
+ return None\r
+\r
+ # if it doesn't start with a prefix, it was meant to be positional\r
+ if not arg_string[0] in self.prefix_chars:\r
+ return None\r
+\r
+ # if the option string is present in the parser, return the action\r
+ if arg_string in self._option_string_actions:\r
+ action = self._option_string_actions[arg_string]\r
+ return action, arg_string, None\r
+\r
+ # if it's just a single character, it was meant to be positional\r
+ if len(arg_string) == 1:\r
+ return None\r
+\r
+ # if the option string before the "=" is present, return the action\r
+ if '=' in arg_string:\r
+ option_string, explicit_arg = arg_string.split('=', 1)\r
+ if option_string in self._option_string_actions:\r
+ action = self._option_string_actions[option_string]\r
+ return action, option_string, explicit_arg\r
+\r
+ # search through all possible prefixes of the option string\r
+ # and all actions in the parser for possible interpretations\r
+ option_tuples = self._get_option_tuples(arg_string)\r
+\r
+ # if multiple actions match, the option string was ambiguous\r
+ if len(option_tuples) > 1:\r
+ options = ', '.join([option_string\r
+ for action, option_string, explicit_arg in option_tuples])\r
+ tup = arg_string, options\r
+ self.error(_('ambiguous option: %s could match %s') % tup)\r
+\r
+ # if exactly one action matched, this segmentation is good,\r
+ # so return the parsed action\r
+ elif len(option_tuples) == 1:\r
+ option_tuple, = option_tuples\r
+ return option_tuple\r
+\r
+ # if it was not found as an option, but it looks like a negative\r
+ # number, it was meant to be positional\r
+ # unless there are negative-number-like options\r
+ if self._negative_number_matcher.match(arg_string):\r
+ if not self._has_negative_number_optionals:\r
+ return None\r
+\r
+ # if it contains a space, it was meant to be a positional\r
+ if ' ' in arg_string:\r
+ return None\r
+\r
+ # it was meant to be an optional but there is no such option\r
+ # in this parser (though it might be a valid option in a subparser)\r
+ return None, arg_string, None\r
+\r
+ def _get_option_tuples(self, option_string):\r
+ result = []\r
+\r
+ # option strings starting with two prefix characters are only\r
+ # split at the '='\r
+ chars = self.prefix_chars\r
+ if option_string[0] in chars and option_string[1] in chars:\r
+ if '=' in option_string:\r
+ option_prefix, explicit_arg = option_string.split('=', 1)\r
+ else:\r
+ option_prefix = option_string\r
+ explicit_arg = None\r
+ for option_string in self._option_string_actions:\r
+ if option_string.startswith(option_prefix):\r
+ action = self._option_string_actions[option_string]\r
+ tup = action, option_string, explicit_arg\r
+ result.append(tup)\r
+\r
+ # single character options can be concatenated with their arguments\r
+ # but multiple character options always have to have their argument\r
+ # separate\r
+ elif option_string[0] in chars and option_string[1] not in chars:\r
+ option_prefix = option_string\r
+ explicit_arg = None\r
+ short_option_prefix = option_string[:2]\r
+ short_explicit_arg = option_string[2:]\r
+\r
+ for option_string in self._option_string_actions:\r
+ if option_string == short_option_prefix:\r
+ action = self._option_string_actions[option_string]\r
+ tup = action, option_string, short_explicit_arg\r
+ result.append(tup)\r
+ elif option_string.startswith(option_prefix):\r
+ action = self._option_string_actions[option_string]\r
+ tup = action, option_string, explicit_arg\r
+ result.append(tup)\r
+\r
+ # shouldn't ever get here\r
+ else:\r
+ self.error(_('unexpected option string: %s') % option_string)\r
+\r
+ # return the collected option tuples\r
+ return result\r
+\r
+ def _get_nargs_pattern(self, action):\r
+ # in all examples below, we have to allow for '--' args\r
+ # which are represented as '-' in the pattern\r
+ nargs = action.nargs\r
+\r
+ # the default (None) is assumed to be a single argument\r
+ if nargs is None:\r
+ nargs_pattern = '(-*A-*)'\r
+\r
+ # allow zero or one arguments\r
+ elif nargs == OPTIONAL:\r
+ nargs_pattern = '(-*A?-*)'\r
+\r
+ # allow zero or more arguments\r
+ elif nargs == ZERO_OR_MORE:\r
+ nargs_pattern = '(-*[A-]*)'\r
+\r
+ # allow one or more arguments\r
+ elif nargs == ONE_OR_MORE:\r
+ nargs_pattern = '(-*A[A-]*)'\r
+\r
+ # allow any number of options or arguments\r
+ elif nargs == REMAINDER:\r
+ nargs_pattern = '([-AO]*)'\r
+\r
+ # allow one argument followed by any number of options or arguments\r
+ elif nargs == PARSER:\r
+ nargs_pattern = '(-*A[-AO]*)'\r
+\r
+ # all others should be integers\r
+ else:\r
+ nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)\r
+\r
+ # if this is an optional action, -- is not allowed\r
+ if action.option_strings:\r
+ nargs_pattern = nargs_pattern.replace('-*', '')\r
+ nargs_pattern = nargs_pattern.replace('-', '')\r
+\r
+ # return the pattern\r
+ return nargs_pattern\r
+\r
+ # ========================\r
+ # Value conversion methods\r
+ # ========================\r
+ def _get_values(self, action, arg_strings):\r
+ # for everything but PARSER args, strip out '--'\r
+ if action.nargs not in [PARSER, REMAINDER]:\r
+ arg_strings = [s for s in arg_strings if s != '--']\r
+\r
+ # optional argument produces a default when not present\r
+ if not arg_strings and action.nargs == OPTIONAL:\r
+ if action.option_strings:\r
+ value = action.const\r
+ else:\r
+ value = action.default\r
+ if isinstance(value, _basestring):\r
+ value = self._get_value(action, value)\r
+ self._check_value(action, value)\r
+\r
+ # when nargs='*' on a positional, if there were no command-line\r
+ # args, use the default if it is anything other than None\r
+ elif (not arg_strings and action.nargs == ZERO_OR_MORE and\r
+ not action.option_strings):\r
+ if action.default is not None:\r
+ value = action.default\r
+ else:\r
+ value = arg_strings\r
+ self._check_value(action, value)\r
+\r
+ # single argument or optional argument produces a single value\r
+ elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:\r
+ arg_string, = arg_strings\r
+ value = self._get_value(action, arg_string)\r
+ self._check_value(action, value)\r
+\r
+ # REMAINDER arguments convert all values, checking none\r
+ elif action.nargs == REMAINDER:\r
+ value = [self._get_value(action, v) for v in arg_strings]\r
+\r
+ # PARSER arguments convert all values, but check only the first\r
+ elif action.nargs == PARSER:\r
+ value = [self._get_value(action, v) for v in arg_strings]\r
+ self._check_value(action, value[0])\r
+\r
+ # all other types of nargs produce a list\r
+ else:\r
+ value = [self._get_value(action, v) for v in arg_strings]\r
+ for v in value:\r
+ self._check_value(action, v)\r
+\r
+ # return the converted value\r
+ return value\r
+\r
+ def _get_value(self, action, arg_string):\r
+ type_func = self._registry_get('type', action.type, action.type)\r
+ if not _callable(type_func):\r
+ msg = _('%r is not callable')\r
+ raise ArgumentError(action, msg % type_func)\r
+\r
+ # convert the value to the appropriate type\r
+ try:\r
+ result = type_func(arg_string)\r
+\r
+ # ArgumentTypeErrors indicate errors\r
+ except ArgumentTypeError:\r
+ name = getattr(action.type, '__name__', repr(action.type))\r
+ msg = str(_sys.exc_info()[1])\r
+ raise ArgumentError(action, msg)\r
+\r
+ # TypeErrors or ValueErrors also indicate errors\r
+ except (TypeError, ValueError):\r
+ name = getattr(action.type, '__name__', repr(action.type))\r
+ msg = _('invalid %s value: %r')\r
+ raise ArgumentError(action, msg % (name, arg_string))\r
+\r
+ # return the converted value\r
+ return result\r
+\r
+ def _check_value(self, action, value):\r
+ # converted value must be one of the choices (if specified)\r
+ if action.choices is not None and value not in action.choices:\r
+ tup = value, ', '.join(map(repr, action.choices))\r
+ msg = _('invalid choice: %r (choose from %s)') % tup\r
+ raise ArgumentError(action, msg)\r
+\r
+ # =======================\r
+ # Help-formatting methods\r
+ # =======================\r
+ def format_usage(self):\r
+ formatter = self._get_formatter()\r
+ formatter.add_usage(self.usage, self._actions,\r
+ self._mutually_exclusive_groups)\r
+ return formatter.format_help()\r
+\r
+ def format_help(self):\r
+ formatter = self._get_formatter()\r
+\r
+ # usage\r
+ formatter.add_usage(self.usage, self._actions,\r
+ self._mutually_exclusive_groups)\r
+\r
+ # description\r
+ formatter.add_text(self.description)\r
+\r
+ # positionals, optionals and user-defined groups\r
+ for action_group in self._action_groups:\r
+ formatter.start_section(action_group.title)\r
+ formatter.add_text(action_group.description)\r
+ formatter.add_arguments(action_group._group_actions)\r
+ formatter.end_section()\r
+\r
+ # epilog\r
+ formatter.add_text(self.epilog)\r
+\r
+ # determine help from format above\r
+ return formatter.format_help()\r
+\r
+ def format_version(self):\r
+ import warnings\r
+ warnings.warn(\r
+ 'The format_version method is deprecated -- the "version" '\r
+ 'argument to ArgumentParser is no longer supported.',\r
+ DeprecationWarning)\r
+ formatter = self._get_formatter()\r
+ formatter.add_text(self.version)\r
+ return formatter.format_help()\r
+\r
+ def _get_formatter(self):\r
+ return self.formatter_class(prog=self.prog)\r
+\r
+ # =====================\r
+ # Help-printing methods\r
+ # =====================\r
+ def print_usage(self, file=None):\r
+ if file is None:\r
+ file = _sys.stdout\r
+ self._print_message(self.format_usage(), file)\r
+\r
+ def print_help(self, file=None):\r
+ if file is None:\r
+ file = _sys.stdout\r
+ self._print_message(self.format_help(), file)\r
+\r
+ def print_version(self, file=None):\r
+ import warnings\r
+ warnings.warn(\r
+ 'The print_version method is deprecated -- the "version" '\r
+ 'argument to ArgumentParser is no longer supported.',\r
+ DeprecationWarning)\r
+ self._print_message(self.format_version(), file)\r
+\r
+ def _print_message(self, message, file=None):\r
+ if message:\r
+ if file is None:\r
+ file = _sys.stderr\r
+ file.write(message)\r
+\r
+ # ===============\r
+ # Exiting methods\r
+ # ===============\r
+ def exit(self, status=0, message=None):\r
+ if message:\r
+ self._print_message(message, _sys.stderr)\r
+ _sys.exit(status)\r
+\r
+ def error(self, message):\r
+ """error(message: string)\r
+\r
+ Prints a usage message incorporating the message to stderr and\r
+ exits.\r
+\r
+ If you override this in a subclass, it should not return -- it\r
+ should either exit or raise an exception.\r
+ """\r
+ self.print_usage(_sys.stderr)\r
+ self.exit(2, _('%s: error: %s\n') % (self.prog, message))\r
--- /dev/null
+#!/bin/bash
+#
+# get_cloog.sh - retrieve cloog from git repo to current directory, configure, build
+# and install into <destdir>, which defaults to cwd.
+#
+# Basic process is:
+# 1. git clone git://repo.or.cz/cloog.git
+# 2. cd cloog
+# 3. ./get_submodules.sh
+# 4. ./autogen.sh
+# 5. ./configure --prefix=<destdir>
+#
+
+this=$0
+verb=false
+destDir=none
+libGMPDir=/usr
+forceClone=false
+cmdPre=""
+
+usage() {
+ echo usage: $this '[--verbose --dry-run --force --gmp=<gmpdir> <install-directory>]'
+ echo 'where: <install-directory> must exist, defaults to cwd'
+ echo ' <gmpdir>: path to GMP library, defaults to /usr'
+ exit $1
+}
+
+vsay() {
+ if [[ $verb = true ]] ; then
+ echo "$@"
+ fi
+}
+
+complain() {
+ echo "$@"
+ exit 1
+}
+
+# Function to make a directory including its ancestors.
+makedir() {
+ if [[ $1 == "" ]] ; then
+ :
+ elif [[ -d $1 ]] ; then
+ :
+ else
+ makedirtmp=`dirname "$1"`
+ makedir "$makedirtmp"
+ vsay "$this: Making directory $1"
+ if mkdir "$1" ; then
+ :
+ else
+ complain "$this: mkdir $1 failed"
+ fi
+ fi
+}
+
+# echo/run command line, complain if it fails.
+runCmd() {
+ $cmdPre $*
+ if [[ $? != 0 ]] ; then
+ complain $* failed
+ fi
+}
+
+ACTUAL_PWD=`pwd`
+ROOT=${PWD:-$ACTUAL_PWD}
+vsay $this: Polylibs root is $ROOT.
+
+while [[ $# != 0 ]] ; do
+ tmp=`echo $1 | sed -e 's;^[-]*;;g'`
+ if [[ $tmp == $1 ]] ; then
+ if [[ $destDir == none ]] ; then
+ destDir=$tmp
+ fi
+ else
+ switchArg=`echo $tmp | cut -s -d= -f2`
+ if [[ $switchArg != "" ]] ; then
+ tmp=`echo $tmp | cut -d= -f1`
+ fi
+ case $tmp in
+ dry-run)
+ cmdPre=echo
+ ;;
+ force)
+ forceClone=true
+ ;;
+ gmp)
+ if [[ $switchArg == "" ]] ; then
+ echo "$this: --gmp requires a pathname argument"
+ usage 1
+ fi
+ libGMPDir=$switchArg
+ ;;
+ help)
+ usage 0
+ ;;
+ verbose)
+ verb=true
+ ;;
+ *)
+ usage 1
+ ;;
+ esac
+ fi
+ shift
+done
+
+if [[ $destDir == none ]] ; then
+ destDir=$ACTUAL_PWD
+else
+ # Create specified install directory if it doesn't exist.
+ makedir $destDir
+fi
+
+destDir=`(cd $destDir ; echo $PWD)`
+
+if [[ ! -d $libGMPDir ]] ; then
+ complain GMP dir $libGMPDIR not found.
+fi
+if [[ ! -f $libGMPDir/include/gmp.h ]] ; then
+ complain $libGMPDir does not appear to contain a GMP library.
+fi
+
+# Check for libtoolize, required by cloog/autogen.sh
+tmp=`which libtoolize`
+if [[ $tmp == "" ]] ; then
+ complain libtoolize '(needed by cloog/autogen.sh)' not found
+fi
+
+# 1. Get cloog, remove existing cloog tree if forcing.
+if [[ $forceClone == true ]] ; then
+ vsay removing existing cloog tree
+ rm -rf ./cloog
+fi
+
+# Allow reuse of existing cloog tree.
+if [[ ! -d cloog ]] ; then
+ vsay cloning git repo into $ROOT/cloog
+ runCmd git clone git://repo.or.cz/cloog.git
+else
+ vsay using existing cloog tree: $ROOT/cloog
+fi
+
+runCmd cd cloog
+
+# 2. Get bundled isl library
+runCmd ./get_submodules.sh
+
+# 3. Generate configure scripts for cloog and isl
+runCmd ./autogen.sh
+
+configArgs="--without-polylib --with-isl=bundled"
+configArgs="$configArgs --with-gmp-prefix=$libGMPDir --prefix=$destDir"
+
+# 4. Configure cloog and isl
+runCmd ./configure $configArgs
+
+exit 0
+
+
--- /dev/null
+#!/usr/bin/env python
+
+import argparse
+import subprocess
+import tempfile
+import os
+import sys
+
+def createAssemblyFile(tmpDir, file, number, args, polly):
+ # Check if file exists
+ if not os.path.isfile(file):
+ print "File '" + file + "' does not exist. Compilation aborted."
+ sys.exit(1)
+
+ # Create an LLVM-IR .ll file
+ tmpDir = tmpDir + "/" + str(number)
+ subprocess.call(["mkdir", tmpDir])
+ llFile = tmpDir + '/output.ll'
+ includeFlags = ['-I' + x for x in args.includes]
+ preprocessorFlags = ['-D' + x for x in args.preprocessor]
+
+ if args.progress:
+ print "Optimizing file: " + file
+ print "- Compiling C to LLVM-IR"
+
+ commandLine = ["clang","-emit-llvm", "-S", file, '-o', llFile,
+ '-std=' + args.standard] + includeFlags + preprocessorFlags \
+ + args.unknown_args
+
+ if args.commands:
+ print ' '.join(commandLine)
+
+ exit = subprocess.call(commandLine)
+
+ if exit:
+ print 'Translation from C to LLVM-IR failed. This command did not work:'
+ print ' '.join(commandLine)
+ sys.exit(1)
+
+ # Preprocess the programm such that as many optimization opportunities
+ # as possible are exposed.
+ preoptFile = tmpDir + '/output.preopt.ll'
+ preoptPasses = '-basicaa -mem2reg -simplify-libcalls ' \
+ '-simplifycfg -instcombine -tailcallelim -loop-simplify ' \
+ '-lcssa -loop-rotate -lcssa -loop-unswitch -instcombine ' \
+ '-loop-simplify -lcssa -indvars -loop-deletion -instcombine ' \
+ '-polly-prepare -polly-region-simplify -indvars'
+
+ if args.progress:
+ print "- Preoptimizing to expose optimization opportunities"
+
+ commandLine = ['opt', '-load', polly] + preoptPasses.split(' ') \
+ + ['-S', llFile, '-o', preoptFile]
+
+ if args.commands:
+ print ' '.join(commandLine)
+
+ exit = subprocess.call(commandLine)
+
+ if exit:
+ print 'Preoptimizing failed: This command did not work'
+ print ' '.join(commandLine)
+ sys.exit(1)
+
+ # Run the Polly optimizers
+ pollyFile = tmpDir + '/output.polly.ll'
+
+ if args.view or args.viewonly:
+ commandLine = ['opt', '-load', polly, '-basicaa'] \
+ + [preoptFile, '-disable-output']
+
+ if args.view:
+ commandLine.append('-view-scops')
+ else:
+ commandLine.append('-view-scops-only')
+
+ if args.commands:
+ print ' '.join(commandLine)
+
+ exit = subprocess.call(commandLine)
+
+ if exit:
+ print 'Polly optimizations failed: This command did not work'
+ print ' '.join(commandLine)
+ sys.exit(1)
+
+ if args.fpolly:
+ commandLine = ['opt', '-load', polly, '-basicaa'] \
+ + [preoptFile, '-disable-polly-legality']
+
+ if args.pollyimport:
+ commandLine.append('-polly-import-jscop')
+
+ if args.fpluto:
+ commandLine.append('-polly-optimize')
+
+ if args.faligned:
+ commandLine.append('-enable-polly-aligned')
+
+ if args.ftile:
+ commandLine.append('-enable-pluto-tile')
+
+ if args.pluto_fuse:
+ commandLine.append('-pluto-fuse')
+ commandLine.append(args.pluto_fuse)
+
+ if args.fparallel:
+ commandLine.append('-enable-polly-openmp')
+
+ if args.fvector:
+ commandLine.append('-enable-polly-vector')
+ commandLine.append('-enable-pluto-prevector')
+
+ if args.pollyexport:
+ commandLine.append('-polly-export-jscop')
+
+ if args.debug:
+ debugCommandLine = commandLine + ['-polly-cloog', '-analyze', '-q']
+ subprocess.call(debugCommandLine)
+
+ if args.progress:
+ print "- Running polly",
+
+ if args.fpluto:
+ print "with pluto",
+
+ if args.ftile:
+ print "and tiling",
+
+ if args.fparallel:
+ print "and parallel",
+
+ print ""
+
+ commandLine = commandLine + ['-polly-codegen', '-S', '-o', pollyFile]
+
+ if args.commands:
+ print ' '.join(commandLine)
+
+ exit = subprocess.call(commandLine)
+
+ if exit:
+ print 'Polly optimizations failed: This command did not work'
+ print ' '.join(commandLine)
+ sys.exit(1)
+
+
+ # Run optimizations to clean up the redundant calculations Polly introduced
+ # and to take advantage of non polyhedral optimizations.
+ optFile = tmpDir + '/output.opt.ll'
+ commandLine = ['opt', '-S', '-o', optFile + "tmp"]
+ commandLine2 = ['opt', '-S', '-o', optFile]
+
+ if args.optlevel != '0':
+ commandLine.append('-O' + args.optlevel)
+ commandLine2.append('-O' + args.optlevel)
+
+ if args.fpolly:
+ commandLine.append(pollyFile)
+ else:
+ commandLine.append(preoptFile)
+
+ commandLine2.append(optFile + "tmp");
+
+ if args.progress:
+ print "- Running normal LLVM -O3 passes"
+
+ exit = subprocess.call(commandLine)
+
+ if exit:
+ print 'LLVM -O3 optimizations failed: This command did not work'
+ print ' '.join(commandLine)
+ sys.exit(1)
+
+ exit = subprocess.call(commandLine2)
+
+ if exit:
+ print 'LLVM -O3 optimizations failed: This command did not work'
+ print ' '.join(commandLine)
+ sys.exit(1)
+
+
+ if args.emitllvm:
+ return optFile
+
+
+ # Create assembly file
+ assemblyFile = tmpDir + '/output.opt.s'
+ commandLine = ['llc', optFile, '-o', assemblyFile]
+
+ if args.progress:
+ print "- Translating LLVM-IR to assembly"
+
+ subprocess.call(commandLine)
+
+ if exit:
+ print 'Translating LLVM-IR to assembly failed: This command did not work'
+ print ' '.join(commandLine)
+ sys.exit(1)
+
+ return assemblyFile
+
+def parseArguments():
+ description = 'pollycc is a simple replacement for compiler drivers like ' \
+ 'gcc, clang or icc. It uses clang to compile C code and can ' \
+ 'optimize the code with Polly. It will either produce an ' \
+ 'optimized binary or an optimized \'.o\' file.'
+
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument('files', nargs='+')
+ parser.add_argument('-o', dest='output', help='the name of the output file')
+ parser.add_argument('-I', action='append', dest='includes', default=[],
+ help='include path to pass to clang')
+ parser.add_argument('-D', action='append', dest='preprocessor', default=[],
+ help='preprocessor directives to pass to clang')
+ parser.add_argument('-l', action='append', dest='libraries', default=[],
+ help='library flags to pass to the linker')
+ parser.add_argument('-L', action='append', dest='librarypath', default=[],
+ help='library paths to pass to the linker')
+ parser.add_argument('-O', dest='optlevel', choices='0123s', default='3',
+ help='optimization level.')
+ parser.add_argument('-S', action='store_true',
+ help='compile only; do not link or assemble')
+ parser.add_argument('-emit-llvm', action='store_true', dest='emitllvm',
+ help='output LLVM-IR instead of assembly if -S is set')
+ parser.add_argument('-std', dest='standard', help='The C standard to use',
+ default='gnu89')
+ parser.add_argument('-p', '--progress', action='store_true',
+ help='Show the compilation progress')
+ parser.add_argument('-c', action='store_true',
+ help='compile and assemble, but do not link')
+ parser.add_argument('-fpolly', help='enable polly', action='store_true')
+ parser.add_argument('-fpluto', help='enable pluto', action='store_true')
+ parser.add_argument('-fpluto-fuse', dest='pluto_fuse', help='enable pluto')
+ parser.add_argument('-faligned', help='Assume aligned vector accesses',
+ action='store_true')
+ parser.add_argument('-fview-scops', dest='view',
+ help='Show the scops with graphviz',
+ action='store_true')
+ parser.add_argument('-fview-scops-only', dest='viewonly',
+ help='Show the scops with graphviz (Only Basic Blocks)',
+ action='store_true')
+ parser.add_argument('-ftile', '-fpluto-tile',
+ help='enable pluto tiling', action='store_true')
+ parser.add_argument('-fparallel',
+ help='enable openmp code generation (in development)',
+ action='store_true')
+ parser.add_argument('-fvector',
+ help='enable SIMD code generation (in development)',
+ action='store_true')
+ parser.add_argument('-fpolly-export', dest='pollyexport',
+ help='Export Polly jscop', action='store_true')
+ parser.add_argument('-fpolly-import', dest='pollyimport',
+ help='Import Polly jscop', action='store_true')
+ parser.add_argument('-commands', help='print command lines executed',
+ action='store_true')
+ parser.add_argument('-d', '--debug', help='print debugging output',
+ action='store_true')
+ parser.add_argument('-v', '--version', dest='version', action='store_true',
+ help='print version info')
+
+ arguments, argv = parser.parse_known_args()
+
+ if argv:
+ arguments.unknown_args = filter(lambda x: x[0] == '-', argv)
+ arguments.files = arguments.files + filter(lambda x: x[0] != '-', argv)
+
+ if arguments.unknown_args:
+ print 'warning: The following arguments are unknown and will \n' \
+ ' be passed directly to clang: ' + \
+ ' '.join(arguments.unknown_args)
+ else:
+ arguments.unknown_args = []
+
+ # Post process arguments
+ if arguments.ftile:
+ arguments.fpluto = True
+
+ if arguments.pollyimport:
+ arguments.fpolly = True
+
+ if arguments.view or arguments.viewonly:
+ arguments.fpolly = True
+
+ if arguments.fpluto:
+ arguments.fpolly = True
+
+ return arguments
+
+def createAssemblyFiles(files, args, pollyLib):
+ assemblyFiles = []
+
+ tmpDir = tempfile.mkdtemp(prefix='pollycc-');
+
+ number = 0
+ for file in args.files:
+ assemblyFiles.append(createAssemblyFile(tmpDir, file, number, args, pollyLib))
+ if args.progress:
+ print ""
+
+ number = number + 1
+
+ return assemblyFiles
+
+def createOutputFiles(assemblyFiles, args):
+ if args.output:
+ outputFile = args.output
+ elif len(args.files) == 1 and args.c:
+ outputFile = args.files[0].replace('.c', '.o')
+ elif len(args.files) == 1 and args.S:
+ outputFile = args.files[0].replace('.c', '.s')
+ else:
+ outputFile = 'a.out'
+
+ linkerFlags = ['-l' + x for x in args.libraries]
+ libraryPath = ['-L' + x for x in args.librarypath]
+
+ commandLine = ['gcc', '-o', outputFile] + assemblyFiles
+
+ if args.S:
+ subprocess.call(['mv', assemblyFiles[0], outputFile])
+ return
+
+ if args.c:
+ commandLine.append('-c')
+ else:
+ commandLine = commandLine + linkerFlags + libraryPath
+
+ if args.fparallel:
+ commandLine.append('-lgomp')
+
+ if args.progress:
+ print "Final linking"
+
+ subprocess.call(commandLine)
+
+def checkExecutables(pollyLib):
+ commandLine = ['opt', '-load', pollyLib, '-help']
+ try:
+ proc = subprocess.Popen(commandLine, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout_value = proc.communicate()[0]
+
+ if not stdout_value.count('polly-prepare'):
+ sys.exit('Polly support not available in opt')
+
+ if not stdout_value.count('polly-optimize'):
+ sys.exit('Polly compiled without POCC/Pluto support')
+ except OSError:
+ print 'error: opt cannot be executed: '
+ print 'failing command: \n' + " ".join(commandLine)
+ sys.exit(1)
+
+ commandLine = ['clang', '-v']
+ try:
+ subprocess.call(commandLine, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except OSError:
+ print 'error: clang cannot be executed: '
+ print 'failing command: \n' + " ".join(commandLine)
+ sys.exit(1)
+
+ commandLine = ['lli', '-help']
+ try:
+ subprocess.call(commandLine, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except OSError:
+ print 'error: lli cannot be executed: '
+ print 'failing command: \n' + " ".join(commandLine)
+ sys.exit(1)
+
+def main():
+ args = parseArguments()
+
+ if not 'LIBPOLLY' in os.environ:
+ sys.exit('Polly library not provided. Please set LIBPOLLY environment ' + \
+ 'variable to the LLVMPolly.so file')
+
+ pollyLib = os.environ['LIBPOLLY']
+
+ checkExecutables(pollyLib)
+
+ assemblyFiles = createAssemblyFiles(args.files, args, pollyLib)
+ createOutputFiles(assemblyFiles, args)
+
+if __name__ == '__main__':
+ main()
--- /dev/null
+from ctypes import *
+
+isl = cdll.LoadLibrary("libisl.so")
+
+class Context:
+ defaultInstance = None
+ instances = {}
+
+ def __init__(self):
+ ptr = isl.isl_ctx_alloc()
+ self.ptr = ptr
+ Context.instances[ptr] = self
+
+ def __del__(self):
+ isl.isl_ctx_free(self)
+
+ def from_param(self):
+ return self.ptr
+
+ @staticmethod
+ def from_ptr(ptr):
+ return Context.instances[ptr]
+
+ @staticmethod
+ def getDefaultInstance():
+ if Context.defaultInstance == None:
+ Context.defaultInstance = Context()
+
+ return Context.defaultInstance
+
+class IslObject:
+ def __init__(self, string = "", ctx = None, ptr = None):
+ self.initialize_isl_methods()
+ if ptr != None:
+ self.ptr = ptr
+ self.ctx = self.get_isl_method("get_ctx")(self)
+ return
+
+ if ctx == None:
+ ctx = Context.getDefaultInstance()
+
+ self.ctx = ctx
+ self.ptr = self.get_isl_method("read_from_str")(ctx, string, -1)
+
+ def __del__(self):
+ self.get_isl_method("free")(self)
+
+ def from_param(self):
+ return self.ptr
+
+ @property
+ def context(self):
+ return self.ctx
+
+ def __repr__(self):
+ p = Printer(self.ctx)
+ self.to_printer(p)
+ return p.getString();
+
+ def __str__(self):
+ p = Printer(self.ctx)
+ self.to_printer(p)
+ return p.getString();
+
+ @staticmethod
+ def isl_name():
+ return "No isl name available"
+
+ def initialize_isl_methods(self):
+ if hasattr(self.__class__, "initialized"):
+ return
+
+ self.__class__.initalized = True
+ self.get_isl_method("read_from_str").argtypes = [Context, c_char_p, c_int]
+ self.get_isl_method("copy").argtypes = [self.__class__]
+ self.get_isl_method("copy").restype = c_int
+ self.get_isl_method("free").argtypes = [self.__class__]
+ self.get_isl_method("get_ctx").argtypes = [self.__class__]
+ self.get_isl_method("get_ctx").restype = Context.from_ptr
+ getattr(isl, "isl_printer_print_" + self.isl_name()).argtypes = [Printer, self.__class__]
+
+ def get_isl_method(self, name):
+ return getattr(isl, "isl_" + self.isl_name() + "_" + name)
+
+ def to_printer(self, printer):
+ getattr(isl, "isl_printer_print_" + self.isl_name())(printer, self)
+
+class BSet(IslObject):
+ @staticmethod
+ def from_ptr(ptr):
+ if not ptr:
+ return
+ return BSet(ptr = ptr)
+
+ @staticmethod
+ def isl_name():
+ return "basic_set"
+
+class Set(IslObject):
+ @staticmethod
+ def from_ptr(ptr):
+ if not ptr:
+ return
+ return Set(ptr = ptr)
+
+ @staticmethod
+ def isl_name():
+ return "set"
+
+class USet(IslObject):
+ @staticmethod
+ def from_ptr(ptr):
+ if not ptr:
+ return
+ return USet(ptr = ptr)
+
+ @staticmethod
+ def isl_name():
+ return "union_set"
+
+
+class BMap(IslObject):
+ @staticmethod
+ def from_ptr(ptr):
+ if not ptr:
+ return
+ return BMap(ptr = ptr)
+
+ def __mul__(self, set):
+ return self.intersect_domain(set)
+
+ @staticmethod
+ def isl_name():
+ return "basic_map"
+
+class Map(IslObject):
+ @staticmethod
+ def from_ptr(ptr):
+ if not ptr:
+ return
+ return Map(ptr = ptr)
+
+ def __mul__(self, set):
+ return self.intersect_domain(set)
+
+ @staticmethod
+ def isl_name():
+ return "map"
+
+ @staticmethod
+ def lex_lt(dim):
+ dim = isl.isl_dim_copy(dim)
+ return isl.isl_map_lex_lt(dim)
+
+ @staticmethod
+ def lex_le(dim):
+ dim = isl.isl_dim_copy(dim)
+ return isl.isl_map_lex_le(dim)
+
+ @staticmethod
+ def lex_gt(dim):
+ dim = isl.isl_dim_copy(dim)
+ return isl.isl_map_lex_gt(dim)
+
+ @staticmethod
+ def lex_ge(dim):
+ dim = isl.isl_dim_copy(dim)
+ return isl.isl_map_lex_ge(dim)
+
+class UMap(IslObject):
+ @staticmethod
+ def from_ptr(ptr):
+ if not ptr:
+ return
+ return UMap(ptr = ptr)
+
+ @staticmethod
+ def isl_name():
+ return "union_map"
+
+class Dim(IslObject):
+ @staticmethod
+ def from_ptr(ptr):
+ if not ptr:
+ return
+ return Dim(ptr = ptr)
+
+ @staticmethod
+ def isl_name():
+ return "dim"
+
+ def initialize_isl_methods(self):
+ if hasattr(self.__class__, "initialized"):
+ return
+
+ self.__class__.initalized = True
+ self.get_isl_method("copy").argtypes = [self.__class__]
+ self.get_isl_method("copy").restype = c_int
+ self.get_isl_method("free").argtypes = [self.__class__]
+ self.get_isl_method("get_ctx").argtypes = [self.__class__]
+ self.get_isl_method("get_ctx").restype = Context.from_ptr
+
+ def __repr__(self):
+ return str(self)
+
+ def __str__(self):
+
+ dimParam = isl.isl_dim_size(self, 1)
+ dimIn = isl.isl_dim_size(self, 2)
+ dimOut = isl.isl_dim_size(self, 3)
+
+ if dimIn:
+ return "<dim In:%s, Out:%s, Param:%s>" % (dimIn, dimOut, dimParam)
+
+ return "<dim Set:%s, Param:%s>" % (dimOut, dimParam)
+
+class Printer:
+ FORMAT_ISL = 0
+ FORMAT_POLYLIB = 1
+ FORMAT_POLYLIB_CONSTRAINTS = 2
+ FORMAT_OMEGA = 3
+ FORMAT_C = 4
+ FORMAT_LATEX = 5
+ FORMAT_EXT_POLYLIB = 6
+
+ def __init__(self, ctx = None):
+ if ctx == None:
+ ctx = Context.getDefaultInstance()
+
+ self.ctx = ctx
+ self.ptr = isl.isl_printer_to_str(ctx)
+
+ def setFormat(self, format):
+ self.ptr = isl.isl_printer_set_output_format(self, format);
+
+ def from_param(self):
+ return self.ptr
+
+ def __del__(self):
+ isl.isl_printer_free(self)
+
+ def getString(self):
+ return isl.isl_printer_get_str(self)
+
+functions = [
+ # Unary properties
+ ("is_empty", BSet, [BSet], c_int),
+ ("is_empty", Set, [Set], c_int),
+ ("is_empty", USet, [USet], c_int),
+ ("is_empty", BMap, [BMap], c_int),
+ ("is_empty", Map, [Map], c_int),
+ ("is_empty", UMap, [UMap], c_int),
+
+ # ("is_universe", Set, [Set], c_int),
+ # ("is_universe", Map, [Map], c_int),
+
+ ("is_single_valued", Map, [Map], c_int),
+
+ ("is_bijective", Map, [Map], c_int),
+
+ ("is_wrapping", BSet, [BSet], c_int),
+ ("is_wrapping", Set, [Set], c_int),
+
+ # Binary properties
+ ("is_equal", BSet, [BSet, BSet], c_int),
+ ("is_equal", Set, [Set, Set], c_int),
+ ("is_equal", USet, [USet, USet], c_int),
+ ("is_equal", BMap, [BMap, BMap], c_int),
+ ("is_equal", Map, [Map, Map], c_int),
+ ("is_equal", UMap, [UMap, UMap], c_int),
+
+ # is_disjoint missing
+
+ # ("is_subset", BSet, [BSet, BSet], c_int),
+ ("is_subset", Set, [Set, Set], c_int),
+ ("is_subset", USet, [USet, USet], c_int),
+ ("is_subset", BMap, [BMap, BMap], c_int),
+ ("is_subset", Map, [Map, Map], c_int),
+ ("is_subset", UMap, [UMap, UMap], c_int),
+ #("is_strict_subset", BSet, [BSet, BSet], c_int),
+ ("is_strict_subset", Set, [Set, Set], c_int),
+ ("is_strict_subset", USet, [USet, USet], c_int),
+ ("is_strict_subset", BMap, [BMap, BMap], c_int),
+ ("is_strict_subset", Map, [Map, Map], c_int),
+ ("is_strict_subset", UMap, [UMap, UMap], c_int),
+
+ # Unary Operations
+ ("complement", Set, [Set], Set),
+ ("reverse", BMap, [BMap], BMap),
+ ("reverse", Map, [Map], Map),
+ ("reverse", UMap, [UMap], UMap),
+
+ # Projection missing
+ ("range", BMap, [BMap], BSet),
+ ("range", Map, [Map], Set),
+ ("range", UMap, [UMap], USet),
+ ("domain", BMap, [BMap], BSet),
+ ("domain", Map, [Map], Set),
+ ("domain", UMap, [UMap], USet),
+
+ ("identity", Set, [Set], Map),
+ ("identity", USet, [USet], UMap),
+
+ ("deltas", BMap, [BMap], BSet),
+ ("deltas", Map, [Map], Set),
+ ("deltas", UMap, [UMap], USet),
+
+ ("coalesce", Set, [Set], Set),
+ ("coalesce", USet, [USet], USet),
+ ("coalesce", Map, [Map], Map),
+ ("coalesce", UMap, [UMap], UMap),
+
+ ("detect_equalities", BSet, [BSet], BSet),
+ ("detect_equalities", Set, [Set], Set),
+ ("detect_equalities", USet, [USet], USet),
+ ("detect_equalities", BMap, [BMap], BMap),
+ ("detect_equalities", Map, [Map], Map),
+ ("detect_equalities", UMap, [UMap], UMap),
+
+ ("convex_hull", Set, [Set], Set),
+ ("convex_hull", Map, [Map], Map),
+
+ ("simple_hull", Set, [Set], Set),
+ ("simple_hull", Map, [Map], Map),
+
+ ("affine_hull", BSet, [BSet], BSet),
+ ("affine_hull", Set, [Set], BSet),
+ ("affine_hull", USet, [USet], USet),
+ ("affine_hull", BMap, [BMap], BMap),
+ ("affine_hull", Map, [Map], BMap),
+ ("affine_hull", UMap, [UMap], UMap),
+
+ ("polyhedral_hull", Set, [Set], Set),
+ ("polyhedral_hull", USet, [USet], USet),
+ ("polyhedral_hull", Map, [Map], Map),
+ ("polyhedral_hull", UMap, [UMap], UMap),
+
+ # Power missing
+ # Transitive closure missing
+ # Reaching path lengths missing
+
+ ("wrap", BMap, [BMap], BSet),
+ ("wrap", Map, [Map], Set),
+ ("wrap", UMap, [UMap], USet),
+ ("unwrap", BSet, [BMap], BMap),
+ ("unwrap", Set, [Map], Map),
+ ("unwrap", USet, [UMap], UMap),
+
+ ("flatten", Set, [Set], Set),
+ ("flatten", Map, [Map], Map),
+ ("flatten_map", Set, [Set], Map),
+
+ # Dimension manipulation missing
+
+ # Binary Operations
+ ("intersect", BSet, [BSet, BSet], BSet),
+ ("intersect", Set, [Set, Set], Set),
+ ("intersect", USet, [USet, USet], USet),
+ ("intersect", BMap, [BMap, BMap], BMap),
+ ("intersect", Map, [Map, Map], Map),
+ ("intersect", UMap, [UMap, UMap], UMap),
+ ("intersect_domain", BMap, [BMap, BSet], BMap),
+ ("intersect_domain", Map, [Map, Set], Map),
+ ("intersect_domain", UMap, [UMap, USet], UMap),
+ ("intersect_range", BMap, [BMap, BSet], BMap),
+ ("intersect_range", Map, [Map, Set], Map),
+ ("intersect_range", UMap, [UMap, USet], UMap),
+
+ ("union", BSet, [BSet, BSet], Set),
+ ("union", Set, [Set, Set], Set),
+ ("union", USet, [USet, USet], USet),
+ ("union", BMap, [BMap, BMap], Map),
+ ("union", Map, [Map, Map], Map),
+ ("union", UMap, [UMap, UMap], UMap),
+
+ ("subtract", Set, [Set, Set], Set),
+ ("subtract", Map, [Map, Map], Map),
+ ("subtract", USet, [USet, USet], USet),
+ ("subtract", UMap, [UMap, UMap], UMap),
+
+ ("apply", BSet, [BSet, BMap], BSet),
+ ("apply", Set, [Set, Map], Set),
+ ("apply", USet, [USet, UMap], USet),
+ ("apply_domain", BMap, [BMap, BMap], BMap),
+ ("apply_domain", Map, [Map, Map], Map),
+ ("apply_domain", UMap, [UMap, UMap], UMap),
+ ("apply_range", BMap, [BMap, BMap], BMap),
+ ("apply_range", Map, [Map, Map], Map),
+ ("apply_range", UMap, [UMap, UMap], UMap),
+
+ ("gist", BSet, [BSet, BSet], BSet),
+ ("gist", Set, [Set, Set], Set),
+ ("gist", USet, [USet, USet], USet),
+ ("gist", BMap, [BMap, BMap], BMap),
+ ("gist", Map, [Map, Map], Map),
+ ("gist", UMap, [UMap, UMap], UMap),
+
+ # Lexicographic Optimizations
+ # partial_lexmin missing
+ ("lexmin", BSet, [BSet], BSet),
+ ("lexmin", Set, [Set], Set),
+ ("lexmin", USet, [USet], USet),
+ ("lexmin", BMap, [BMap], BMap),
+ ("lexmin", Map, [Map], Map),
+ ("lexmin", UMap, [UMap], UMap),
+
+ ("lexmax", BSet, [BSet], BSet),
+ ("lexmax", Set, [Set], Set),
+ ("lexmax", USet, [USet], USet),
+ ("lexmax", BMap, [BMap], BMap),
+ ("lexmax", Map, [Map], Map),
+ ("lexmax", UMap, [UMap], UMap),
+
+ # Undocumented
+ ("lex_lt_union_set", USet, [USet, USet], UMap),
+ ("lex_le_union_set", USet, [USet, USet], UMap),
+ ("lex_gt_union_set", USet, [USet, USet], UMap),
+ ("lex_ge_union_set", USet, [USet, USet], UMap),
+
+ ]
+keep_functions = [
+ # Unary properties
+ ("get_dim", BSet, [BSet], Dim),
+ ("get_dim", Set, [Set], Dim),
+ ("get_dim", USet, [USet], Dim),
+ ("get_dim", BMap, [BMap], Dim),
+ ("get_dim", Map, [Map], Dim),
+ ("get_dim", UMap, [UMap], Dim)
+ ]
+
+def addIslFunction(object, name):
+ functionName = "isl_" + object.isl_name() + "_" + name
+ islFunction = getattr(isl, functionName)
+ if len(islFunction.argtypes) == 1:
+ f = lambda a: islFunctionOneOp(islFunction, a)
+ elif len(islFunction.argtypes) == 2:
+ f = lambda a, b: islFunctionTwoOp(islFunction, a, b)
+ object.__dict__[name] = f
+
+
+def islFunctionOneOp(islFunction, ops):
+ ops = getattr(isl, "isl_" + ops.isl_name() + "_copy")(ops)
+ return islFunction(ops)
+
+def islFunctionTwoOp(islFunction, opOne, opTwo):
+ opOne = getattr(isl, "isl_" + opOne.isl_name() + "_copy")(opOne)
+ opTwo = getattr(isl, "isl_" + opTwo.isl_name() + "_copy")(opTwo)
+ return islFunction(opOne, opTwo)
+
+for (operation, base, operands, ret) in functions:
+ functionName = "isl_" + base.isl_name() + "_" + operation
+ islFunction = getattr(isl, functionName)
+ if len(operands) == 1:
+ islFunction.argtypes = [c_int]
+ elif len(operands) == 2:
+ islFunction.argtypes = [c_int, c_int]
+
+ if ret == c_int:
+ islFunction.restype = ret
+ else:
+ islFunction.restype = ret.from_ptr
+
+ addIslFunction(base, operation)
+
+def addIslFunctionKeep(object, name):
+ functionName = "isl_" + object.isl_name() + "_" + name
+ islFunction = getattr(isl, functionName)
+ if len(islFunction.argtypes) == 1:
+ f = lambda a: islFunctionOneOpKeep(islFunction, a)
+ elif len(islFunction.argtypes) == 2:
+ f = lambda a, b: islFunctionTwoOpKeep(islFunction, a, b)
+ object.__dict__[name] = f
+
+def islFunctionOneOpKeep(islFunction, ops):
+ return islFunction(ops)
+
+def islFunctionTwoOpKeep(islFunction, opOne, opTwo):
+ return islFunction(opOne, opTwo)
+
+for (operation, base, operands, ret) in keep_functions:
+ functionName = "isl_" + base.isl_name() + "_" + operation
+ islFunction = getattr(isl, functionName)
+ if len(operands) == 1:
+ islFunction.argtypes = [c_int]
+ elif len(operands) == 2:
+ islFunction.argtypes = [c_int, c_int]
+
+ if ret == c_int:
+ islFunction.restype = ret
+ else:
+ islFunction.restype = ret.from_ptr
+
+ addIslFunctionKeep(base, operation)
+
+isl.isl_ctx_free.argtypes = [Context]
+isl.isl_basic_set_read_from_str.argtypes = [Context, c_char_p, c_int]
+isl.isl_set_read_from_str.argtypes = [Context, c_char_p, c_int]
+isl.isl_basic_set_copy.argtypes = [BSet]
+isl.isl_basic_set_copy.restype = c_int
+isl.isl_set_copy.argtypes = [Set]
+isl.isl_set_copy.restype = c_int
+isl.isl_set_copy.argtypes = [Set]
+isl.isl_set_copy.restype = c_int
+isl.isl_set_free.argtypes = [Set]
+isl.isl_basic_set_get_ctx.argtypes = [BSet]
+isl.isl_basic_set_get_ctx.restype = Context.from_ptr
+isl.isl_set_get_ctx.argtypes = [Set]
+isl.isl_set_get_ctx.restype = Context.from_ptr
+isl.isl_basic_set_get_dim.argtypes = [BSet]
+isl.isl_basic_set_get_dim.restype = Dim.from_ptr
+isl.isl_set_get_dim.argtypes = [Set]
+isl.isl_set_get_dim.restype = Dim.from_ptr
+isl.isl_union_set_get_dim.argtypes = [USet]
+isl.isl_union_set_get_dim.restype = Dim.from_ptr
+
+isl.isl_basic_map_read_from_str.argtypes = [Context, c_char_p, c_int]
+isl.isl_map_read_from_str.argtypes = [Context, c_char_p, c_int]
+isl.isl_basic_map_free.argtypes = [BMap]
+isl.isl_map_free.argtypes = [Map]
+isl.isl_basic_map_copy.argtypes = [BMap]
+isl.isl_basic_map_copy.restype = c_int
+isl.isl_map_copy.argtypes = [Map]
+isl.isl_map_copy.restype = c_int
+isl.isl_map_get_ctx.argtypes = [Map]
+isl.isl_basic_map_get_ctx.argtypes = [BMap]
+isl.isl_basic_map_get_ctx.restype = Context.from_ptr
+isl.isl_map_get_ctx.argtypes = [Map]
+isl.isl_map_get_ctx.restype = Context.from_ptr
+isl.isl_basic_map_get_dim.argtypes = [BMap]
+isl.isl_basic_map_get_dim.restype = Dim.from_ptr
+isl.isl_map_get_dim.argtypes = [Map]
+isl.isl_map_get_dim.restype = Dim.from_ptr
+isl.isl_union_map_get_dim.argtypes = [UMap]
+isl.isl_union_map_get_dim.restype = Dim.from_ptr
+isl.isl_printer_free.argtypes = [Printer]
+isl.isl_printer_to_str.argtypes = [Context]
+isl.isl_printer_print_basic_set.argtypes = [Printer, BSet]
+isl.isl_printer_print_set.argtypes = [Printer, Set]
+isl.isl_printer_print_basic_map.argtypes = [Printer, BMap]
+isl.isl_printer_print_map.argtypes = [Printer, Map]
+isl.isl_printer_get_str.argtypes = [Printer]
+isl.isl_printer_get_str.restype = c_char_p
+isl.isl_printer_set_output_format.argtypes = [Printer, c_int]
+isl.isl_printer_set_output_format.restype = c_int
+isl.isl_dim_size.argtypes = [Dim, c_int]
+isl.isl_dim_size.restype = c_int
+
+isl.isl_map_lex_lt.argtypes = [c_int]
+isl.isl_map_lex_lt.restype = Map.from_ptr
+isl.isl_map_lex_le.argtypes = [c_int]
+isl.isl_map_lex_le.restype = Map.from_ptr
+isl.isl_map_lex_gt.argtypes = [c_int]
+isl.isl_map_lex_gt.restype = Map.from_ptr
+isl.isl_map_lex_ge.argtypes = [c_int]
+isl.isl_map_lex_ge.restype = Map.from_ptr
+
+isl.isl_union_map_compute_flow.argtypes = [c_int, c_int, c_int, c_int, c_void_p,
+ c_void_p, c_void_p, c_void_p]
+
+def dependences(sink, must_source, may_source, schedule):
+ sink = getattr(isl, "isl_" + sink.isl_name() + "_copy")(sink)
+ must_source = getattr(isl, "isl_" + must_source.isl_name() + "_copy")(must_source)
+ may_source = getattr(isl, "isl_" + may_source.isl_name() + "_copy")(may_source)
+ schedule = getattr(isl, "isl_" + schedule.isl_name() + "_copy")(schedule)
+ must_dep = c_int()
+ may_dep = c_int()
+ must_no_source = c_int()
+ may_no_source = c_int()
+ isl.isl_union_map_compute_flow(sink, must_source, may_source, schedule, \
+ byref(must_dep), byref(may_dep),
+ byref(must_no_source),
+ byref(may_no_source))
+
+ return (UMap.from_ptr(must_dep), UMap.from_ptr(may_dep), \
+ USet.from_ptr(must_no_source), USet.from_ptr(may_no_source))
+
+
+__all__ = ['Set', 'Map', 'Printer', 'Context']
--- /dev/null
+import json
+from isl import *
+
+class Scop:
+ def __init__(self, filename):
+ f = open(filename, 'r')
+ self.json = json.load(f)
+ return
+
+ def __str__(self):
+ return json.dumps(self.json, indent=2)
+
+ def __repr__(self):
+ return str(self)
+
+ @property
+ def statements(self):
+ return self.json['statements']
+
+class Transforms:
+ """
+ Create a map that interchanges two dimensions 'A' and 'B'
+
+ numberDimensions: The overall number of dimensions
+ dimensionA: The dimension of dimension 'A'
+ dimensionB: The dimension of dimension 'B'
+
+ getInterchange(2, 0, 1):
+ {[d0, d1] -> [d1, d0]}
+ """
+ @staticmethod
+ def getInterchange(numberDimensions, dimensionA, dimensionB):
+
+ dims = ['d' + str(i) for i in range(numberDimensions)]
+ dimString = ",".join(dims)
+
+ changedDims = dims
+ first = dims[dimensionA]
+ second = dims[dimensionB]
+ changedDims[dimensionA] = second
+ changedDims[dimensionB] = first
+ changedDimString = ",".join(changedDims)
+
+ return Map("{[%s] -> [%s]}" % (dimString, changedDimString))
+
+ """
+ Create a map that strip mines one dimension
+
+ numberDimensions: The overall number of dimensions
+ stripMineDim: The dimension to strip mine
+ factor: The strip mining factor
+
+ getStripMine(2, 1, 64):
+ {[d0, d1] -> [d0, o, d1] : o % 64 = 0 and o <= d1 <= d1 + 63}
+ """
+ @staticmethod
+ def getStripMine(numberDimensions, stripMineDim, factor):
+
+ dims = ['d' + str(i) for i in range(numberDimensions)]
+ dimString = ",".join(dims)
+
+ changedDims = dims
+ smd = dims[stripMineDim]
+ changedDims[stripMineDim] = "o,%s" % smd
+ changedDimString = ",".join(changedDims)
+ string = "{[%s] -> [%s]: o %% %i = 0 and o <= %s <= o + %i}" % \
+ (dimString, changedDimString, factor, smd, factor - 1)
+ return Map(string)