Creating release candidate rc1 from release_35 branch

git-svn-id: https://llvm.org/svn/llvm-project/polly/tags/RELEASE_35@213632 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/rc1/.gitattributes b/rc1/.gitattributes
new file mode 100644
index 0000000..7105fff
--- /dev/null
+++ b/rc1/.gitattributes
@@ -0,0 +1,4 @@
+# Auto detect text files and perform LF normalization
+* text eol=lf
+*.png -text
+*.pdf -text
diff --git a/rc1/CMakeLists.txt b/rc1/CMakeLists.txt
new file mode 100644
index 0000000..628c761
--- /dev/null
+++ b/rc1/CMakeLists.txt
@@ -0,0 +1,191 @@
+# 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)
+  #FileCheck is not install by default, warn the user to Copy FileCheck
+  if( NOT EXISTS ${LLVM_INSTALL_ROOT}/bin/FileCheck
+      OR NOT EXISTS ${LLVM_INSTALL_ROOT}/bin/not)
+    message(WARNING "FileCheck or not are requred by running regress tests, "
+                    "but they are not installed! Please copy it to "
+                    "${LLVM_INSTALL_ROOT}/bin.")
+  endif(NOT EXISTS ${LLVM_INSTALL_ROOT}/bin/FileCheck
+        OR NOT EXISTS ${LLVM_INSTALL_ROOT}/bin/not)
+  # 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} )
+
+  # Get the TARGET_TRIPLE
+  execute_process(COMMAND "${LLVM_INSTALL_ROOT}/bin/llvm-config" --host-target
+                  OUTPUT_VARIABLE TARGET_TRIPLE
+                  OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  # 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 path for custom modules
+set(CMAKE_MODULE_PATH
+  ${CMAKE_MODULE_PATH}
+  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+  )
+
+include("polly_macros")
+
+# Add appropriate flags for GCC
+if (CMAKE_COMPILER_IS_GNUCXX)
+  # FIXME: Turn off exceptions, RTTI:
+  # -fno-exceptions -fno-rtti
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -fno-exceptions -fno-rtti")
+endif ()
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
+
+# Add path for custom modules
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${POLLY_SOURCE_DIR}/cmake")
+
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+FIND_PACKAGE(Isl REQUIRED)
+set(POLLY_LINK_LIBS ${ISL_LIBRARY})
+
+FIND_PACKAGE(Pluto)
+if(PLUTO_FOUND)
+  set(POLLY_LINK_LIBS ${POLLY_LINK_LIBS} ${PLUTO_LIBRARY})
+endif(PLUTO_FOUND)
+
+option(POLLY_USE_CLOOG "Build Polly with Cloog support" ON)
+if(POLLY_USE_CLOOG)
+  # Build Cloog support in Polly (default is for cloog-isl).
+  FIND_PACKAGE(Cloog)
+  FIND_PACKAGE(Gmp REQUIRED)
+  if(CLOOG_FOUND)
+    set(POLLY_LINK_LIBS ${POLLY_LINK_LIBS} ${CLOOG_LIBRARY})
+  endif(CLOOG_FOUND)
+endif(POLLY_USE_CLOOG)
+
+if(GMP_FOUND)
+  set(POLLY_LINK_LIBS ${POLLY_LINK_LIBS} ${GMP_LIBRARY})
+endif(GMP_FOUND)
+
+option(POLLY_ENABLE_GPGPU_CODEGEN "Enable GPGPU code generation feature" OFF)
+if (POLLY_ENABLE_GPGPU_CODEGEN)
+  # Do not require CUDA, as GPU code generation test cases can be run without
+  # a cuda library.
+  FIND_PACKAGE(CUDA)
+  set(GPU_CODEGEN TRUE)
+endif(POLLY_ENABLE_GPGPU_CODEGEN)
+
+option(POLLY_ENABLE_SCOPLIB "Enable SCoPLib library for scop import/export" ON)
+if (POLLY_ENABLE_SCOPLIB)
+  FIND_PACKAGE(SCoPLib)
+  if(SCOPLIB_FOUND)
+    set(POLLY_LINK_LIBS ${POLLY_LINK_LIBS} ${SCOPLIB_LIBRARY})
+  endif(SCOPLIB_FOUND)
+endif(POLLY_ENABLE_SCOPLIB)
+
+if (CLOOG_FOUND)
+  INCLUDE_DIRECTORIES( ${CLOOG_INCLUDE_DIR} )
+endif(CLOOG_FOUND)
+if (PLUTO_FOUND)
+  INCLUDE_DIRECTORIES( ${PLUTO_INCLUDE_DIR} )
+endif(PLUTO_FOUND)
+INCLUDE_DIRECTORIES( ${ISL_INCLUDE_DIR} )
+if (GMP_FOUND)
+  INCLUDE_DIRECTORIES( ${GMP_INCLUDE_DIR} )
+endif(GMP_FOUND)
+
+# Support GPGPU code generation if the library is available.
+if (CUDALIB_FOUND)
+  INCLUDE_DIRECTORIES( ${CUDALIB_INCLUDE_DIR} )
+endif(CUDALIB_FOUND)
+
+if (SCOPLIB_FOUND)
+  INCLUDE_DIRECTORIES( ${SCOPLIB_INCLUDE_DIR} )
+endif(SCOPLIB_FOUND)
+
+
+include_directories(
+  BEFORE
+  ${CMAKE_CURRENT_SOURCE_DIR}/include
+  ${CMAKE_CURRENT_SOURCE_DIR}/lib/JSON/include
+  ${CMAKE_CURRENT_BINARY_DIR}/include
+  )
+
+install(DIRECTORY include/
+  DESTINATION include
+  FILES_MATCHING
+  PATTERN "*.h"
+  PATTERN ".svn" EXCLUDE
+  )
+
+install(DIRECTORY ${POLLY_BINARY_DIR}/include/
+  DESTINATION include
+  FILES_MATCHING
+  PATTERN "*.h"
+  PATTERN "CMakeFiles" EXCLUDE
+  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 )
+
+# Add target to check formatting of polly files
+file( GLOB_RECURSE files *.h *.cpp)
+file( GLOB_RECURSE jsonfiles lib/JSON/*.h lib/JSON/*.cpp)
+list( REMOVE_ITEM files ${jsonfiles} )
+add_custom_command( OUTPUT formatting COMMAND
+  CLANG_FORMAT=${LLVM_BINARY_DIR}/bin/clang-format
+  ${CMAKE_CURRENT_SOURCE_DIR}/utils/check_format.sh ${files})
+add_custom_target(polly-check-format DEPENDS formatting)
+add_custom_command( OUTPUT formatting-update COMMAND
+  CLANG_FORMAT=${LLVM_BINARY_DIR}/bin/clang-format
+  ${CMAKE_CURRENT_SOURCE_DIR}/utils/update_format.sh ${files})
+add_custom_target(polly-update-format DEPENDS formatting-update)
+
+# Set the variable POLLY_LINK_LIBS in the llvm/tools/ dir.
+set(POLLY_LINK_LIBS ${POLLY_LINK_LIBS} PARENT_SCOPE)
diff --git a/rc1/CREDITS.txt b/rc1/CREDITS.txt
new file mode 100644
index 0000000..d010906
--- /dev/null
+++ b/rc1/CREDITS.txt
@@ -0,0 +1,35 @@
+This file is a partial list of people who have contributed to Polly.
+If you have contributed a patch or made some other contribution to
+Polly, please submit a patch to this file to add yourself, and it will be
+done!
+
+The list is sorted by surname and formatted to allow easy grepping and
+beautification by scripts.  The fields are: name (N), email (E), web-address
+(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
+(S).
+
+N: Raghesh Aloor
+E: raghesh.a@gmail.com
+D: OpenMP code generation
+D: Google Summer of Code student 2011
+
+N: Tobias Grosser
+E: tobias@grosser.es
+W: http://www.grosser.es
+D: Co-founder, design of the overall architecture
+
+N: Yabin Hu
+E: yabin.hwu@gmail.com
+D: GPGPU code generation
+D: Google Summer of Code student 2012, 2014
+
+N: Andreas Simbuerger
+E: simbuerg@fim.uni-passau.de
+W: http://www.infosun.fim.uni-passau.de/cl/staff/simbuerger/
+D: Profiling infrastructure
+
+N: Hongbin Zheng
+E: etherzhhb@gmail.com
+D: Co-founder
+D: scop detection, automake/cmake infrastructure, scopinfo, scoppasses, ...
+D: Google Summer of Code student 2010
diff --git a/rc1/LICENSE.txt b/rc1/LICENSE.txt
new file mode 100644
index 0000000..86d29f5
--- /dev/null
+++ b/rc1/LICENSE.txt
@@ -0,0 +1,61 @@
+==============================================================================
+Polly Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2014 Polly Team
+All rights reserved.
+
+Developed by:
+
+    Polly Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the Polly Team, copyright holders, nor the names of
+      its contributors may be used to endorse or promote products derived from
+      this Software without specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The Polly software contains code written by third parties.   Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the Polly Distribution, and nothing in any of the other
+licenses gives permission to use the names of the Polly Team or promote products
+derived from this Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+jsoncpp             lib/JSON
+
+
+
diff --git a/rc1/Makefile b/rc1/Makefile
new file mode 100644
index 0000000..2ad5b36
--- /dev/null
+++ b/rc1/Makefile
@@ -0,0 +1,17 @@
+##===- projects/polly/Makefile -----------------------------*- Makefile -*-===##
+#
+# This is a polly Makefile for a project that uses LLVM.
+#
+##===----------------------------------------------------------------------===##
+
+#
+# Indicates our relative path to the top of the project's root directory.
+#
+LEVEL = .
+DIRS = lib test tools
+EXTRA_DIST = include
+
+#
+# Include the Master Makefile that knows how to build all.
+#
+include $(LEVEL)/Makefile.common
diff --git a/rc1/Makefile.common.in b/rc1/Makefile.common.in
new file mode 100644
index 0000000..8a5b945
--- /dev/null
+++ b/rc1/Makefile.common.in
@@ -0,0 +1,34 @@
+#===-- Makefile.common - Common make rules for Polly -------*- Makefile -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+#
+# Configuration file to set paths specific to local installation of LLVM
+#
+PROJECT_NAME := polly
+PROJ_VERSION := 0.9
+# Set this variable to the top of the LLVM source tree.
+LLVM_SRC_ROOT = @LLVM_SRC@
+
+# Set the name of the project here
+
+# (this is *not* the same as OBJ_ROOT as defined in LLVM's Makefile.config).
+LLVM_OBJ_ROOT = @LLVM_OBJ@
+
+PROJ_SRC_ROOT := $(subst //,/,@abs_top_srcdir@)
+
+# Set the root directory of this project's object files
+PROJ_OBJ_ROOT := $(subst //,/,@abs_top_builddir@)
+
+ifndef LLVM_OBJ_ROOT
+include $(LEVEL)/Makefile.config
+else
+include $(PROJ_OBJ_ROOT)/Makefile.config
+endif
+
+# Include LLVM's Master Makefile.
+include $(LLVM_SRC_ROOT)/Makefile.common
diff --git a/rc1/Makefile.config.in b/rc1/Makefile.config.in
new file mode 100644
index 0000000..f151570
--- /dev/null
+++ b/rc1/Makefile.config.in
@@ -0,0 +1,45 @@
+#===-- Makefile.config - Local configuration for LLVM ------*- Makefile -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+#
+# This file is included by Makefile.common.  It defines paths and other
+# values specific to a particular installation of LLVM.
+#
+#===------------------------------------------------------------------------===#
+
+# Set the root directory of this polly's object files
+POLLY_SRC_ROOT := $(subst //,/,@abs_top_srcdir@)
+
+# Set this variable to the top level directory where LLVM was built
+POLLY_OBJ_ROOT := $(subst //,/,@abs_top_builddir@)
+
+# Set the root directory of this project's install prefix
+PROJ_INSTALL_ROOT := @prefix@
+
+# Set the C++ flags
+ifeq (@GXX@,yes)
+POLLY_CXXFLAGS := "-fno-common -Woverloaded-virtual -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings"
+endif
+
+POLLY_CXXFLAGS += "-fno-rtti -fno-exceptions"
+
+PLUTO_FOUND := @pluto_found@
+CLOOG_FOUND := @cloog_found@
+SCOPLIB_FOUND := @scoplib_found@
+CUDALIB_FOUND := @cuda_found@
+
+# Set include directroys
+POLLY_INC :=  @gmp_inc@ @isl_inc@ \
+              @cloog_inc@ @scoplib_inc@ @cuda_inc@\
+	      @pluto_inc@ -I$(POLLY_SRC_ROOT)/lib/JSON/include
+
+POLLY_LD := @gmp_ld@ @isl_ld@ @cloog_ld@ @scoplib_ld@ \
+            @scoplib_rpath@ @cuda_ld@ @pluto_ld@
+
+POLLY_LIB := @gmp_lib@ @isl_lib@ @cloog_lib@ @scoplib_lib@ \
+             @cuda_lib@ @pluto_lib@
diff --git a/rc1/README b/rc1/README
new file mode 100644
index 0000000..09a4a54
--- /dev/null
+++ b/rc1/README
@@ -0,0 +1,12 @@
+Polly - Polyhedral optimizations for LLVM
+-----------------------------------------
+http://polly.llvm.org/
+
+Polly uses a mathematical representation, the polyhedral model, to represent and
+transform loops and other control flow structures. Using an abstract
+representation it is possible to reason about transformations in a more general
+way and to use highly optimized linear programming libraries to figure out the
+optimal loop structure. These transformations can be used to do constant
+propagation through arrays, remove dead loop iterations, optimize loops for
+cache locality, optimize arrays, apply advanced automatic parallelization, drive
+vectorization, or they can be used to do software pipelining.
diff --git a/rc1/autoconf/AutoRegen.sh b/rc1/autoconf/AutoRegen.sh
new file mode 100755
index 0000000..bafef34
--- /dev/null
+++ b/rc1/autoconf/AutoRegen.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+die () {
+	echo "$@" 1>&2
+	exit 1
+}
+
+test -d autoconf && test -f autoconf/configure.ac && cd autoconf
+test -f configure.ac || die "Can't find 'autoconf' dir; please cd into it first"
+autoconf --version | egrep '2\.[5-6][0-9]' > /dev/null
+if test $? -ne 0 ; then
+	die "Your autoconf was not detected as being 2.5x"
+fi
+cwd=`pwd`
+if test -d ../../../autoconf/m4 ; then
+  cd ../../../autoconf/m4
+  llvm_m4=`pwd`
+  cd $cwd
+elif test -d ../../llvm/autoconf/m4 ; then
+  cd ../../llvm/autoconf/m4
+  llvm_m4=`pwd`
+  cd $cwd
+else
+  die "Can't find the LLVM autoconf/m4 directory. polly should be checked out to projects directory"
+fi
+echo "Regenerating aclocal.m4 with aclocal"
+rm -f aclocal.m4
+aclocal -I $llvm_m4 -I "$llvm_m4/.." -I $(pwd)/m4 || die "aclocal failed"
+echo "Regenerating configure with autoconf 2.5x"
+autoconf --force --warnings=all -o ../configure configure.ac || die "autoconf failed"
+cd ..
+echo "Regenerating config.h.in with autoheader"
+autoheader --warnings=all -I autoconf -I autoconf/m4 -I $llvm_m4 -I "$llvm_m4/.." autoconf/configure.ac || die "autoheader failed"
+exit 0
diff --git a/rc1/autoconf/LICENSE.TXT b/rc1/autoconf/LICENSE.TXT
new file mode 100644
index 0000000..72fdd39
--- /dev/null
+++ b/rc1/autoconf/LICENSE.TXT
@@ -0,0 +1,24 @@
+------------------------------------------------------------------------------
+Autoconf Files
+------------------------------------------------------------------------------
+All autoconf files are licensed under the LLVM license with the following
+additions:
+
+llvm/autoconf/install-sh:
+	This script is licensed under the LLVM license, with the following
+	additional copyrights and restrictions:
+
+	Copyright 1991 by the Massachusetts Institute of Technology
+
+	Permission to use, copy, modify, distribute, and sell this software and its
+	documentation for any purpose is hereby granted without fee, provided that
+	the above copyright notice appear in all copies and that both that
+	copyright notice and this permission notice appear in supporting 
+	documentation, and that the name of M.I.T. not be used in advertising or
+	publicity pertaining to distribution of the software without specific,
+	written prior permission.  M.I.T. makes no representations about the
+	suitability of this software for any purpose.  It is provided "as is"
+	without express or implied warranty.
+
+Please see the source files for additional copyrights.
+
diff --git a/rc1/autoconf/aclocal.m4 b/rc1/autoconf/aclocal.m4
new file mode 100644
index 0000000..d503064
--- /dev/null
+++ b/rc1/autoconf/aclocal.m4
@@ -0,0 +1,77 @@
+# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 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: $2 in $given_inc_path, and lib$3 in $given_lib_path])
+
+  # try to compile a file that includes a header of the library
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <$2>]], [[;]])],
+    [AC_MSG_RESULT([ok])
+    AC_SUBST([$1_found],["yes"])
+    AS_IF([test "x$given_inc_path" != "xinc_not_give_$1"],
+      [AC_SUBST([$1_inc],["-I$given_inc_path"])])
+    AC_SUBST([$1_lib],["-l$3"])
+    AS_IF([test "x$given_lib_path" != "xlib_not_give_$1"],
+      [AC_SUBST([$1_ld],["-L$given_lib_path"])])],
+    [AS_IF([test "x$4" = "xrequired"],
+      [AC_MSG_ERROR([$1 required but not found])],
+      [AC_MSG_RESULT([not found])])]
+  )
+
+  # reset original CXXFLAGS
+  CXXFLAGS=$OLD_CXXFLAGS
+  LDFLAGS=$OLD_LDFLAGS;
+  LIBS=$OLD_LIBS
+  AC_LANG_POP(C++)
+])
+
+#
+# Provide the arguments and other processing needed for an LLVM project
+#
+AC_DEFUN([LLVM_CONFIG_PROJECT],
+  [AC_ARG_WITH([llvmsrc],
+    AS_HELP_STRING([--with-llvmsrc],[Location of LLVM Source Code]),
+    [llvm_src="$withval"],[llvm_src="]$1["])
+  AC_SUBST(LLVM_SRC,$llvm_src)
+  AC_ARG_WITH([llvmobj],
+    AS_HELP_STRING([--with-llvmobj],[Location of LLVM Object Code]),
+    [llvm_obj="$withval"],[llvm_obj="]$2["])
+  AC_SUBST(LLVM_OBJ,$llvm_obj)
+  AC_CONFIG_COMMANDS([setup],,[llvm_src="${LLVM_SRC}"])
+])
+
diff --git a/rc1/autoconf/config.guess b/rc1/autoconf/config.guess
new file mode 100644
index 0000000..cc726cd
--- /dev/null
+++ b/rc1/autoconf/config.guess
@@ -0,0 +1,1388 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-02-22'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <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:
diff --git a/rc1/autoconf/config.sub b/rc1/autoconf/config.sub
new file mode 100644
index 0000000..9772e87
--- /dev/null
+++ b/rc1/autoconf/config.sub
@@ -0,0 +1,1489 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-02-22'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <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:
diff --git a/rc1/autoconf/configure.ac b/rc1/autoconf/configure.ac
new file mode 100644
index 0000000..f2be9e4
--- /dev/null
+++ b/rc1/autoconf/configure.ac
@@ -0,0 +1,139 @@
+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])
+
+dnl Find Isl
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS"
+find_lib_and_headers([isl], [isl/val.h], [isl], [required])
+CXXFLAGS=$saved_CXXFLAGS
+
+dnl Check that we have cloog.
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $gmp_inc $isl_inc"
+find_lib_and_headers([cloog], [cloog/isl/cloog.h], [cloog-isl])
+CXXFLAGS=$saved_CXXFLAGS
+AS_IF([test "x$cloog_found" = "xyes"],
+  [AC_DEFINE([CLOOG_FOUND],[1],[Define if cloog found])])
+
+dnl Check that we have libpluto.
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $gmp_inc $isl_inc"
+find_lib_and_headers([pluto], [pluto/libpluto.h], [pluto])
+CXXFLAGS=$saved_CXXFLAGS
+AS_IF([test "x$pluto_found" = "xyes"],
+  [AC_DEFINE([PLUTO_FOUND],[1],[Define if pluto found])])
+
+dnl Check that we have scoplib.
+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 Check if CUDA lib there
+dnl Disable the build of polly, even if it is checked out into tools/polly.
+AC_ARG_ENABLE(polly_gpu_codegen,
+              AS_HELP_STRING([--enable-polly-gpu-codegen],
+                             [Enable GPU code generation in Polly(default is NO)]),,
+                             enableval=default)
+case "$enableval" in
+  yes) AC_DEFINE([GPU_CODEGEN],[1], [Define if gpu codegen is enabled]) ;;
+  no) ;;
+  default) ;;
+  *) AC_MSG_ERROR([Invalid setting for --enable-polly-gpu-codegen. Use "yes" or "no"]) ;;
+esac
+
+find_lib_and_headers([cuda], [cuda.h], [cuda])
+
+AS_IF([test "x$cuda_found" = "xyes"],
+  [AC_DEFINE([CUDALIB_FOUND],[1],[Define if cudalib found])])
+
+dnl **************************************************************************
+dnl * Create the output files
+dnl **************************************************************************
+
+dnl This must be last
+AC_CONFIG_HEADERS(include/polly/Config/config.h)
+AC_OUTPUT
diff --git a/rc1/autoconf/configure.bak b/rc1/autoconf/configure.bak
new file mode 100644
index 0000000..1f16056
--- /dev/null
+++ b/rc1/autoconf/configure.bak
@@ -0,0 +1,65 @@
+dnl **************************************************************************
+dnl * Initialize
+dnl **************************************************************************
+AC_INIT([Polly],[0.01],[etherzhhb@gmail.com grosser@fim.uni-passau.de ojomojo@gmail.com])
+
+dnl Identify where LLVM source tree is
+LLVM_SRC_ROOT="../.."
+LLVM_OBJ_ROOT="../.."
+dnl Tell autoconf that the auxilliary files are actually located in
+dnl the LLVM autoconf directory, not here.
+AC_CONFIG_AUX_DIR($LLVM_SRC_ROOT/autoconf)
+
+dnl Tell autoconf that this is an LLVM project being configured
+dnl This provides the --with-llvmsrc and --with-llvmobj options
+LLVM_CONFIG_PROJECT($LLVM_SRC_ROOT,$LLVM_OBJ_ROOT)
+
+dnl Verify that the source directory is valid
+AC_CONFIG_SRCDIR(["Makefile.common.in"])
+
+dnl Configure a common Makefile
+AC_CONFIG_FILES(Makefile.common)
+
+dnl Configure project makefiles
+dnl List every Makefile that exists within your source tree
+AC_CONFIG_MAKEFILE(Makefile)
+AC_CONFIG_MAKEFILE(lib/Makefile)
+
+dnl **************************************************************************
+dnl * Determine which system we are building on
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Check for programs.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Check for libraries.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for header files.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for typedefs, structures, and compiler characteristics.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Checks for library functions.
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Enable various compile-time options
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Set the location of various third-party software packages
+dnl **************************************************************************
+
+dnl **************************************************************************
+dnl * Create the output files
+dnl **************************************************************************
+
+dnl This must be last
+AC_OUTPUT
diff --git a/rc1/autoconf/m4/find_lib_and_headers.m4 b/rc1/autoconf/m4/find_lib_and_headers.m4
new file mode 100644
index 0000000..e872819
--- /dev/null
+++ b/rc1/autoconf/m4/find_lib_and_headers.m4
@@ -0,0 +1,47 @@
+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: $2 in $given_inc_path, and lib$3 in $given_lib_path])
+
+  # try to compile a file that includes a header of the library
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <$2>]], [[;]])],
+    [AC_MSG_RESULT([ok])
+    AC_SUBST([$1_found],["yes"])
+    AS_IF([test "x$given_inc_path" != "xinc_not_give_$1"],
+      [AC_SUBST([$1_inc],["-I$given_inc_path"])])
+    AC_SUBST([$1_lib],["-l$3"])
+    AS_IF([test "x$given_lib_path" != "xlib_not_give_$1"],
+      [AC_SUBST([$1_ld],["-L$given_lib_path"])])],
+    [AS_IF([test "x$4" = "xrequired"],
+      [AC_MSG_ERROR([$1 required but not found])],
+      [AC_MSG_RESULT([not found])])]
+  )
+
+  # reset original CXXFLAGS
+  CXXFLAGS=$OLD_CXXFLAGS
+  LDFLAGS=$OLD_LDFLAGS;
+  LIBS=$OLD_LIBS
+  AC_LANG_POP(C++)
+])
diff --git a/rc1/cmake/FindCUDA.cmake b/rc1/cmake/FindCUDA.cmake
new file mode 100644
index 0000000..37592f9
--- /dev/null
+++ b/rc1/cmake/FindCUDA.cmake
@@ -0,0 +1,23 @@
+IF (NOT CUDA_HEADER_PREFIX)
+  SET(CUDA_HEADER_PREFIX "/usr/local/cuda/include")
+ENDIF (NOT CUDA_HEADER_PREFIX)
+
+FIND_PATH(CUDALIB_INCLUDE_DIR
+  NAMES cuda.h
+  PATHS ${CUDA_HEADER_PREFIX})
+
+FIND_LIBRARY(CUDALIB_LIBRARY NAMES cuda)
+
+IF (CUDALIB_INCLUDE_DIR)
+  SET(CUDALIB_FOUND TRUE)
+ENDIF (CUDALIB_INCLUDE_DIR)
+
+IF (CUDALIB_FOUND)
+  IF (NOT CUDA_FIND_QUIETLY)
+    MESSAGE(STATUS "Found CUDA: ${CUDALIB_INCLUDE_DIR}")
+  ENDIF (NOT CUDA_FIND_QUIETLY)
+ELSE (CUDALIB_FOUND)
+  IF (CUDA_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find CUDA")
+  ENDIF (CUDA_FIND_REQUIRED)
+ENDIF (CUDALIB_FOUND)
diff --git a/rc1/cmake/FindCloog.cmake b/rc1/cmake/FindCloog.cmake
new file mode 100644
index 0000000..057756f
--- /dev/null
+++ b/rc1/cmake/FindCloog.cmake
@@ -0,0 +1,19 @@
+FIND_PATH(CLOOG_INCLUDE_DIR cloog/isl/cloog.h)
+
+FIND_LIBRARY(CLOOG_LIBRARY NAMES cloog-isl)
+
+IF (CLOOG_INCLUDE_DIR AND CLOOG_LIBRARY)
+  SET(CLOOG_FOUND TRUE)
+ENDIF (CLOOG_INCLUDE_DIR AND CLOOG_LIBRARY)
+
+
+IF (CLOOG_FOUND)
+  IF (NOT CLOOG_FIND_QUIETLY)
+    MESSAGE(STATUS "Found Cloog: ${CLOOG_LIBRARY}")
+  ENDIF (NOT CLOOG_FIND_QUIETLY)
+ELSE (CLOOG_FOUND)
+  IF (CLOOG_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find Cloog")
+  ENDIF (CLOOG_FIND_REQUIRED)
+ENDIF (CLOOG_FOUND)
+
diff --git a/rc1/cmake/FindGmp.cmake b/rc1/cmake/FindGmp.cmake
new file mode 100644
index 0000000..60def58
--- /dev/null
+++ b/rc1/cmake/FindGmp.cmake
@@ -0,0 +1,19 @@
+FIND_PATH(GMP_INCLUDE_DIR gmp.h)
+
+FIND_LIBRARY(GMP_LIBRARY NAMES gmp)
+
+IF (GMP_INCLUDE_DIR AND GMP_LIBRARY)
+  SET(GMP_FOUND TRUE)
+ENDIF (GMP_INCLUDE_DIR AND GMP_LIBRARY)
+
+
+IF (GMP_FOUND)
+  IF (NOT GMP_FIND_QUIETLY)
+    MESSAGE(STATUS "Found GMP: ${GMP_LIBRARY}")
+  ENDIF (NOT GMP_FIND_QUIETLY)
+ELSE (GMP_FOUND)
+  IF (GMP_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find GMP")
+  ENDIF (GMP_FIND_REQUIRED)
+ENDIF (GMP_FOUND)
+
diff --git a/rc1/cmake/FindIsl.cmake b/rc1/cmake/FindIsl.cmake
new file mode 100644
index 0000000..1c46e72
--- /dev/null
+++ b/rc1/cmake/FindIsl.cmake
@@ -0,0 +1,19 @@
+FIND_PATH(ISL_INCLUDE_DIR isl/val.h)
+
+FIND_LIBRARY(ISL_LIBRARY NAMES isl)
+
+IF (ISL_INCLUDE_DIR AND ISL_LIBRARY)
+  SET(ISL_FOUND TRUE)
+ENDIF (ISL_INCLUDE_DIR AND ISL_LIBRARY)
+
+
+IF (ISL_FOUND)
+  IF (NOT Isl_FIND_QUIETLY)
+    MESSAGE(STATUS "Found Isl: ${ISL_LIBRARY}")
+  ENDIF (NOT Isl_FIND_QUIETLY)
+ELSE (ISL_FOUND)
+  IF (Isl_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find Isl")
+  ENDIF (Isl_FIND_REQUIRED)
+ENDIF (ISL_FOUND)
+
diff --git a/rc1/cmake/FindPluto.cmake b/rc1/cmake/FindPluto.cmake
new file mode 100644
index 0000000..78d8563
--- /dev/null
+++ b/rc1/cmake/FindPluto.cmake
@@ -0,0 +1,19 @@
+FIND_PATH(PLUTO_INCLUDE_DIR pluto/libpluto.h)
+
+FIND_LIBRARY(PLUTO_LIBRARY NAMES pluto)
+
+IF (PLUTO_INCLUDE_DIR AND PLUTO_LIBRARY)
+  SET(PLUTO_FOUND TRUE)
+ENDIF (PLUTO_INCLUDE_DIR AND PLUTO_LIBRARY)
+
+
+IF (PLUTO_FOUND)
+  IF (NOT PLUTO_FIND_QUIETLY)
+    MESSAGE(STATUS "Found Pluto: ${PLUTO_LIBRARY}")
+  ENDIF (NOT PLUTO_FIND_QUIETLY)
+ELSE (PLUTO_FOUND)
+  IF (PLUTO_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find Pluto")
+  ENDIF (PLUTO_FIND_REQUIRED)
+ENDIF (PLUTO_FOUND)
+
diff --git a/rc1/cmake/FindSCoPLib.cmake b/rc1/cmake/FindSCoPLib.cmake
new file mode 100644
index 0000000..cb8307f
--- /dev/null
+++ b/rc1/cmake/FindSCoPLib.cmake
@@ -0,0 +1,19 @@
+FIND_PATH(SCOPLIB_INCLUDE_DIR scoplib/scop.h)
+
+FIND_LIBRARY(SCOPLIB_LIBRARY NAMES scoplib)
+
+IF (SCOPLIB_INCLUDE_DIR AND SCOPLIB_LIBRARY)
+  SET(SCOPLIB_FOUND TRUE)
+ENDIF (SCOPLIB_INCLUDE_DIR AND SCOPLIB_LIBRARY)
+
+
+IF (SCOPLIB_FOUND)
+  IF (NOT Isl_FIND_QUIETLY)
+    MESSAGE(STATUS "Found SCoPLib: ${SCOPLIB_LIBRARY}")
+  ENDIF (NOT Isl_FIND_QUIETLY)
+ELSE (SCOPLIB_FOUND)
+  IF (Isl_FIND_REQUIRED)
+    MESSAGE(FATAL_ERROR "Could not find SCoPLib")
+  ENDIF (Isl_FIND_REQUIRED)
+ENDIF (SCOPLIB_FOUND)
+
diff --git a/rc1/cmake/polly_macros.cmake b/rc1/cmake/polly_macros.cmake
new file mode 100644
index 0000000..da65dcd
--- /dev/null
+++ b/rc1/cmake/polly_macros.cmake
@@ -0,0 +1,71 @@
+
+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 )
+
+  if(POLLY_LINK_LIBS)
+    foreach(lib ${POLLY_LINK_LIBS})
+      target_link_libraries(${name} ${lib})
+    endforeach(lib)
+  endif(POLLY_LINK_LIBS)
+
+  if( LLVM_LINK_COMPONENTS )
+    llvm_config(${name} ${LLVM_LINK_COMPONENTS})
+  endif( LLVM_LINK_COMPONENTS )
+  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)
+
+macro(add_polly_loadable_module name)
+  set(srcs ${ARGN})
+  # klduge: pass different values for MODULE with multiple targets in same dir
+  # this allows building shared-lib and module in same dir
+  # there must be a cleaner way to achieve this....
+  if (MODULE)
+  else()
+    set(GLOBAL_NOT_MODULE TRUE)
+  endif()
+  set(MODULE TRUE)
+  add_polly_library(${name} ${srcs})
+  if (GLOBAL_NOT_MODULE)
+    unset (MODULE)
+  endif()
+  if (APPLE)
+    # Darwin-specific linker flags for loadable modules.
+    set_target_properties(${name} PROPERTIES
+      LINK_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
+  endif()
+endmacro(add_polly_loadable_module)
diff --git a/rc1/configure b/rc1/configure
new file mode 100755
index 0000000..4849a73
--- /dev/null
+++ b/rc1/configure
@@ -0,0 +1,4248 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for Polly 0.01.
+#
+# Report bugs to <polly-dev@googlegroups.com>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 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.
+as_myself=
+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
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+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
+test -x / || 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 :
+  export CONFIG_SHELL
+             # 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.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+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_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_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; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # 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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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
+cuda_ld
+cuda_lib
+cuda_inc
+cuda_found
+scoplib_rpath
+scoplib_ld
+scoplib_lib
+scoplib_inc
+scoplib_found
+pluto_ld
+pluto_lib
+pluto_inc
+pluto_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_pluto
+with_scoplib
+enable_polly_gpu_codegen
+with_cuda
+'
+      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
+  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 Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-polly-gpu-codegen
+                          Enable GPU code generation in Polly(default is NO)
+
+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-pluto            prefix of pluto
+  --with-scoplib          prefix of scoplib
+  --with-cuda             prefix of cuda
+
+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.69
+
+Copyright (C) 2012 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; ${as_lineno_stack:+:} 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 ||
+	 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; ${as_lineno_stack:+:} 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.69.  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 ${ac_cv_prog_CXX+:} false; 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 as_fn_executable_p "$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 ${ac_cv_prog_ac_ct_CXX+:} false; 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 as_fn_executable_p "$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 ${ac_cv_objext+:} false; 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 ${ac_cv_cxx_compiler_gnu+:} false; 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 ${ac_cv_prog_cxx_g+:} false; 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: gmp.h in $given_inc_path, and libgmp in $given_lib_path" >&5
+$as_echo_n "checking for gmp: gmp.h in $given_inc_path, and libgmp in $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 "x" = "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
+
+
+
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$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 -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: isl/val.h in $given_inc_path, and libisl in $given_lib_path" >&5
+$as_echo_n "checking for isl: isl/val.h in $given_inc_path, and libisl in $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/val.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
+
+
+CXXFLAGS=$saved_CXXFLAGS
+
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $gmp_inc $isl_inc"
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  OLD_CXXFLAGS=$CXXFLAGS;
+  OLD_LDFLAGS=$LDFLAGS;
+  OLD_LIBS=$LIBS;
+
+  LIBS="$LIBS -lcloog-isl";
+
+  # Get include path and lib path
+
+# Check whether --with-cloog was given.
+if test "${with_cloog+set}" = set; then :
+  withval=$with_cloog; given_inc_path="$withval/include"; CXXFLAGS="-I$given_inc_path $CXXFLAGS";
+       given_lib_path="$withval/lib"; LDFLAGS="-L$given_lib_path $LDFLAGS"
+else
+  given_inc_path=inc_not_give_cloog;
+       given_lib_path=lib_not_give_cloog
+
+fi
+
+  # Check for library and headers works
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cloog: cloog/isl/cloog.h in $given_inc_path, and libcloog-isl in $given_lib_path" >&5
+$as_echo_n "checking for cloog: cloog/isl/cloog.h in $given_inc_path, and libcloog-isl in $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 "x" = "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
+if test "x$cloog_found" = "xyes"; then :
+
+$as_echo "#define CLOOG_FOUND 1" >>confdefs.h
+
+fi
+
+saved_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="$CXXFLAGS $gmp_inc $isl_inc"
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  OLD_CXXFLAGS=$CXXFLAGS;
+  OLD_LDFLAGS=$LDFLAGS;
+  OLD_LIBS=$LIBS;
+
+  LIBS="$LIBS -lpluto";
+
+  # Get include path and lib path
+
+# Check whether --with-pluto was given.
+if test "${with_pluto+set}" = set; then :
+  withval=$with_pluto; 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_pluto;
+       given_lib_path=lib_not_give_pluto
+
+fi
+
+  # Check for library and headers works
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pluto: pluto/libpluto.h in $given_inc_path, and libpluto in $given_lib_path" >&5
+$as_echo_n "checking for pluto: pluto/libpluto.h in $given_inc_path, and libpluto in $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 <pluto/libpluto.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; }
+    pluto_found="yes"
+
+    if test "x$given_inc_path" != "xinc_not_give_pluto"; then :
+  pluto_inc="-I$given_inc_path"
+
+fi
+    pluto_lib="-lpluto"
+
+    if test "x$given_lib_path" != "xlib_not_give_pluto"; then :
+  pluto_ld="-L$given_lib_path"
+
+fi
+else
+  if test "x" = "xrequired"; then :
+  as_fn_error $? "pluto 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
+if test "x$pluto_found" = "xyes"; then :
+
+$as_echo "#define PLUTO_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: scoplib/scop.h in $given_inc_path, and libscoplib in $given_lib_path" >&5
+$as_echo_n "checking for scoplib: scoplib/scop.h in $given_inc_path, and libscoplib in $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
+
+
+
+# Check whether --enable-polly_gpu_codegen was given.
+if test "${enable_polly_gpu_codegen+set}" = set; then :
+  enableval=$enable_polly_gpu_codegen;
+else
+  enableval=default
+fi
+
+case "$enableval" in
+  yes)
+$as_echo "#define GPU_CODEGEN 1" >>confdefs.h
+ ;;
+  no) ;;
+  default) ;;
+  *) as_fn_error $? "Invalid setting for --enable-polly-gpu-codegen. Use \"yes\" or \"no\"" "$LINENO" 5 ;;
+esac
+
+
+  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 -lcuda";
+
+  # Get include path and lib path
+
+# Check whether --with-cuda was given.
+if test "${with_cuda+set}" = set; then :
+  withval=$with_cuda; 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_cuda;
+       given_lib_path=lib_not_give_cuda
+
+fi
+
+  # Check for library and headers works
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cuda: cuda.h in $given_inc_path, and libcuda in $given_lib_path" >&5
+$as_echo_n "checking for cuda: cuda.h in $given_inc_path, and libcuda in $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 <cuda.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; }
+    cuda_found="yes"
+
+    if test "x$given_inc_path" != "xinc_not_give_cuda"; then :
+  cuda_inc="-I$given_inc_path"
+
+fi
+    cuda_lib="-lcuda"
+
+    if test "x$given_lib_path" != "xlib_not_give_cuda"; then :
+  cuda_ld="-L$given_lib_path"
+
+fi
+else
+  if test "x" = "xrequired"; then :
+  as_fn_error $? "cuda 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$cuda_found" = "xyes"; then :
+
+$as_echo "#define CUDALIB_FOUND 1" >>confdefs.h
+
+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
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  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.
+as_myself=
+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 -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+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
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# 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.69.  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.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 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= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_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 -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# 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 {' >"$ac_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 >>"\$ac_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 >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_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 >"$ac_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_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; 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 = ""
+}
+/^[\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="$ac_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 >"$ac_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 "$ac_tmp/subs.awk" \
+  >$ac_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' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_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 "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_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 "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_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 "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/rc1/docs/index.html b/rc1/docs/index.html
new file mode 100644
index 0000000..d2e6786
--- /dev/null
+++ b/rc1/docs/index.html
@@ -0,0 +1,6 @@
+<html>
+  <body>
+    <h1>SAMPLE PROJECT DOCUMENTATION</h1>
+    <p>This is just a placeholder</p>
+  </body>
+</html>
diff --git a/rc1/docs/polly.png b/rc1/docs/polly.png
new file mode 100644
index 0000000..fedec56
--- /dev/null
+++ b/rc1/docs/polly.png
Binary files differ
diff --git a/rc1/docs/polly.svg b/rc1/docs/polly.svg
new file mode 100644
index 0000000..7326ae5
--- /dev/null
+++ b/rc1/docs/polly.svg
@@ -0,0 +1,149 @@
+<?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>
diff --git a/rc1/include/CMakeLists.txt b/rc1/include/CMakeLists.txt
new file mode 100644
index 0000000..abe73d1
--- /dev/null
+++ b/rc1/include/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(polly)
diff --git a/rc1/include/polly/CMakeLists.txt b/rc1/include/polly/CMakeLists.txt
new file mode 100644
index 0000000..ef92163
--- /dev/null
+++ b/rc1/include/polly/CMakeLists.txt
@@ -0,0 +1,9 @@
+if( MSVC_IDE OR XCODE )
+  # Creates a dummy target containing all headers for the benefit of
+  # Visual Studio users.
+  file(GLOB_RECURSE headers *.h)
+  add_library(polly_headers_do_not_build EXCLUDE_FROM_ALL
+    # We need at least one source file:
+    ${POLLY_SOURCE_DIR}/lib/Support/GICHelper.cpp
+    ${headers})
+endif()
diff --git a/rc1/include/polly/Canonicalization.h b/rc1/include/polly/Canonicalization.h
new file mode 100755
index 0000000..b32931c
--- /dev/null
+++ b/rc1/include/polly/Canonicalization.h
@@ -0,0 +1,28 @@
+//===--- Canonicalization.h - Set of canonicalization passes ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_CANONICALIZATION_H
+#define POLLY_CANONICALIZATION_H
+
+#include "llvm/PassManager.h"
+
+namespace polly {
+
+/// @brief Schedule a set of canonicalization passes to prepare for Polly
+///
+/// The set of optimization passes was partially taken/copied from the
+/// set of default optimization passes in LLVM. It is used to bring the code
+/// into a canonical form that simplifies the analysis and optimization passes
+/// of Polly. The set of optimization passes scheduled here is probably not yet
+/// optimal. TODO: Optimize the set of canonicalization passes.
+void registerCanonicalicationPasses(llvm::PassManagerBase &PM,
+                                    bool SCEVCodegen = false);
+}
+
+#endif
diff --git a/rc1/include/polly/CodeGen/BlockGenerators.h b/rc1/include/polly/CodeGen/BlockGenerators.h
new file mode 100644
index 0000000..2ee0090
--- /dev/null
+++ b/rc1/include/polly/CodeGen/BlockGenerators.h
@@ -0,0 +1,330 @@
+//===-BlockGenerators.h - Helper to generate code for statements-*- 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 BlockGenerator and VectorBlockGenerator classes, which
+// generate sequential code and vectorized code for a polyhedral statement,
+// respectively.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_BLOCK_GENERATORS_H
+#define POLLY_BLOCK_GENERATORS_H
+
+#include "polly/CodeGen/IRBuilder.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+
+#include "isl/map.h"
+
+#include <vector>
+
+namespace llvm {
+class Pass;
+class Region;
+class ScalarEvolution;
+}
+
+namespace polly {
+extern bool SCEVCodegen;
+
+using namespace llvm;
+class ScopStmt;
+
+typedef DenseMap<const Value *, Value *> ValueMapT;
+typedef std::vector<ValueMapT> VectorValueMapT;
+
+/// @brief Check whether an instruction can be synthesized by the code
+///        generator.
+///
+/// Some instructions will be recalculated only from information that is code
+/// generated from the polyhedral representation. For such instructions we do
+/// not need to ensure that their operands are available during code generation.
+///
+/// @param I The instruction to check.
+/// @param LI The LoopInfo analysis.
+/// @param SE The scalar evolution database.
+/// @param R The region out of which SSA names are parameters.
+/// @return If the instruction I can be regenerated from its
+///         scalar evolution representation, return true,
+///         otherwise return false.
+bool canSynthesize(const llvm::Instruction *I, const llvm::LoopInfo *LI,
+                   llvm::ScalarEvolution *SE, const llvm::Region *R);
+
+/// @brief Generate a new basic block for a polyhedral statement.
+///
+/// The only public function exposed is generate().
+class BlockGenerator {
+public:
+  /// @brief Generate a new BasicBlock for a ScopStmt.
+  ///
+  /// @param Builder   The LLVM-IR Builder used to generate the statement. The
+  ///                  code is generated at the location, the Builder points to.
+  /// @param Stmt      The statement to code generate.
+  /// @param GlobalMap A map that defines for certain Values referenced from the
+  ///                  original code new Values they should be replaced with.
+  /// @param P         A reference to the pass this function is called from.
+  ///                  The pass is needed to update other analysis.
+  static void generate(PollyIRBuilder &Builder, ScopStmt &Stmt,
+                       ValueMapT &GlobalMap, LoopToScevMapT &LTS, Pass *P) {
+    BlockGenerator Generator(Builder, Stmt, P);
+    Generator.copyBB(GlobalMap, LTS);
+  }
+
+protected:
+  PollyIRBuilder &Builder;
+  ScopStmt &Statement;
+  Pass *P;
+  ScalarEvolution &SE;
+
+  BlockGenerator(PollyIRBuilder &B, ScopStmt &Stmt, Pass *P);
+
+  /// @brief Get the new version of a Value.
+  ///
+  /// @param Old       The old Value.
+  /// @param BBMap     A mapping from old values to their new values
+  ///                  (for values recalculated within this basic block).
+  /// @param GlobalMap A mapping from old values to their new values
+  ///                  (for values recalculated in the new ScoP, but not
+  ///                   within this basic block).
+  /// @param LTS       A mapping from loops virtual canonical induction
+  ///                  variable to their new values
+  ///                  (for values recalculated in the new ScoP, but not
+  ///                   within this basic block).
+  /// @param L         The loop that surrounded the instruction that referenced
+  ///                  this value in the original code. This loop is used to
+  ///                  evaluate the scalar evolution at the right scope.
+  ///
+  /// @returns  o The old value, if it is still valid.
+  ///           o The new value, if available.
+  ///           o NULL, if no value is found.
+  Value *getNewValue(const Value *Old, ValueMapT &BBMap, ValueMapT &GlobalMap,
+                     LoopToScevMapT &LTS, Loop *L);
+
+  /// @brief Get the new version of a Value if it is available.
+  ///
+  /// @param Old       The old Value.
+  /// @param BBMap     A mapping from old values to their new values
+  ///                  (for values recalculated within this basic block).
+  /// @param GlobalMap A mapping from old values to their new values
+  ///                  (for values recalculated in the new ScoP, but not
+  ///                   within this basic block).
+  ///
+  /// @returns  The new value, if available.
+  Value *lookupAvailableValue(const Value *Old, ValueMapT &BBMap,
+                              ValueMapT &GlobalMap) const;
+
+  void copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
+                      ValueMapT &GlobalMap, LoopToScevMapT &LTS);
+
+  /// @brief Get the innermost loop that surrounds an instruction.
+  ///
+  /// @param Inst The instruction for which we get the loop.
+  /// @return The innermost loop that surrounds the instruction.
+  Loop *getLoopForInst(const Instruction *Inst);
+
+  /// @brief Get the memory access offset to be added to the base address
+  ///
+  /// @param L The loop that surrounded the instruction that referenced this
+  ///          memory subscript in the original code.
+  std::vector<Value *> getMemoryAccessIndex(__isl_keep isl_map *AccessRelation,
+                                            Value *BaseAddress,
+                                            ValueMapT &BBMap,
+                                            ValueMapT &GlobalMap,
+                                            LoopToScevMapT &LTS, Loop *L);
+
+  /// @brief Get the new operand address according to the changed access in
+  ///        JSCOP file.
+  ///
+  /// @param L The loop that surrounded the instruction that used this operand
+  ///          in the original code.
+  Value *getNewAccessOperand(__isl_keep isl_map *NewAccessRelation,
+                             Value *BaseAddress, ValueMapT &BBMap,
+                             ValueMapT &GlobalMap, LoopToScevMapT &LTS,
+                             Loop *L);
+
+  /// @brief Generate the operand address
+  Value *generateLocationAccessed(const Instruction *Inst, const Value *Pointer,
+                                  ValueMapT &BBMap, ValueMapT &GlobalMap,
+                                  LoopToScevMapT &LTS);
+
+  Value *generateScalarLoad(const LoadInst *load, ValueMapT &BBMap,
+                            ValueMapT &GlobalMap, LoopToScevMapT &LTS);
+
+  Value *generateScalarStore(const StoreInst *store, ValueMapT &BBMap,
+                             ValueMapT &GlobalMap, LoopToScevMapT &LTS);
+
+  /// @brief Copy a single Instruction.
+  ///
+  /// This copies a single Instruction and updates references to old values
+  /// with references to new values, as defined by GlobalMap and BBMap.
+  ///
+  /// @param BBMap     A mapping from old values to their new values
+  ///                  (for values recalculated within this basic block).
+  /// @param GlobalMap A mapping from old values to their new values
+  ///                  (for values recalculated in the new ScoP, but not
+  ///                  within this basic block).
+  void copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
+                       ValueMapT &GlobalMap, LoopToScevMapT &LTS);
+
+  /// @brief Copy the basic block.
+  ///
+  /// This copies the entire basic block and updates references to old values
+  /// with references to new values, as defined by GlobalMap.
+  ///
+  /// @param GlobalMap A mapping from old values to their new values
+  ///                  (for values recalculated in the new ScoP, but not
+  ///                  within this basic block).
+  void copyBB(ValueMapT &GlobalMap, LoopToScevMapT &LTS);
+};
+
+/// @brief Generate a new vector basic block for a polyhedral statement.
+///
+/// The only public function exposed is generate().
+class VectorBlockGenerator : BlockGenerator {
+public:
+  /// @brief Generate a new vector basic block for a ScoPStmt.
+  ///
+  /// This code generation is similar to the normal, scalar code generation,
+  /// except that each instruction is code generated for several vector lanes
+  /// at a time. If possible instructions are issued as actual vector
+  /// instructions, but e.g. for address calculation instructions we currently
+  /// generate scalar instructions for each vector lane.
+  ///
+  /// @param Stmt       The statement to code generate.
+  /// @param GlobalMaps A vector of maps that define for certain Values
+  ///                   referenced from the original code new Values they should
+  ///                   be replaced with. Each map in the vector of maps is
+  ///                   used for one vector lane. The number of elements in the
+  ///                   vector defines the width of the generated vector
+  ///                   instructions.
+  /// @param Schedule   A map from the statement to a schedule where the
+  ///                   innermost dimension is the dimension of the innermost
+  ///                   loop containing the statemenet.
+  /// @param P          A reference to the pass this function is called from.
+  ///                   The pass is needed to update other analysis.
+  static void generate(PollyIRBuilder &B, ScopStmt &Stmt,
+                       VectorValueMapT &GlobalMaps,
+                       std::vector<LoopToScevMapT> &VLTS,
+                       __isl_keep isl_map *Schedule, Pass *P) {
+    VectorBlockGenerator Generator(B, GlobalMaps, VLTS, Stmt, Schedule, P);
+    Generator.copyBB();
+  }
+
+private:
+  // This is a vector of global value maps.  The first map is used for the first
+  // vector lane, ...
+  // Each map, contains information about Instructions in the old ScoP, which
+  // are recalculated in the new SCoP. When copying the basic block, we replace
+  // all referenes to the old instructions with their recalculated values.
+  VectorValueMapT &GlobalMaps;
+
+  // This is a vector of loop->scev maps.  The first map is used for the first
+  // vector lane, ...
+  // Each map, contains information about Instructions in the old ScoP, which
+  // are recalculated in the new SCoP. When copying the basic block, we replace
+  // all referenes to the old instructions with their recalculated values.
+  //
+  // For example, when the code generator produces this AST:
+  //
+  //   for (int c1 = 0; c1 <= 1023; c1 += 1)
+  //     for (int c2 = 0; c2 <= 1023; c2 += VF)
+  //       for (int lane = 0; lane <= VF; lane += 1)
+  //         Stmt(c2 + lane + 3, c1);
+  //
+  // VLTS[lane] contains a map:
+  //   "outer loop in the old loop nest" -> SCEV("c2 + lane + 3"),
+  //   "inner loop in the old loop nest" -> SCEV("c1").
+  std::vector<LoopToScevMapT> &VLTS;
+
+  // A map from the statement to a schedule where the innermost dimension is the
+  // dimension of the innermost loop containing the statemenet.
+  isl_map *Schedule;
+
+  VectorBlockGenerator(PollyIRBuilder &B, VectorValueMapT &GlobalMaps,
+                       std::vector<LoopToScevMapT> &VLTS, ScopStmt &Stmt,
+                       __isl_keep isl_map *Schedule, Pass *P);
+
+  int getVectorWidth();
+
+  Value *getVectorValue(const Value *Old, ValueMapT &VectorMap,
+                        VectorValueMapT &ScalarMaps, Loop *L);
+
+  Type *getVectorPtrTy(const Value *V, int Width);
+
+  /// @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
+  ///
+  /// @param NegativeStride This is used to indicate a -1 stride. In such
+  ///                       a case we load the end of a base address and
+  ///                       shuffle the accesses in reverse order into the
+  ///                       vector. By default we would do only positive
+  ///                       strides.
+  ///
+  Value *generateStrideOneLoad(const LoadInst *Load,
+                               VectorValueMapT &ScalarMaps,
+                               bool NegativeStride);
+
+  /// @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);
+
+  /// @brief 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);
+
+  void generateLoad(const LoadInst *Load, ValueMapT &VectorMap,
+                    VectorValueMapT &ScalarMaps);
+
+  void copyUnaryInst(const UnaryInstruction *Inst, ValueMapT &VectorMap,
+                     VectorValueMapT &ScalarMaps);
+
+  void copyBinaryInst(const BinaryOperator *Inst, ValueMapT &VectorMap,
+                      VectorValueMapT &ScalarMaps);
+
+  void copyStore(const StoreInst *Store, ValueMapT &VectorMap,
+                 VectorValueMapT &ScalarMaps);
+
+  void copyInstScalarized(const Instruction *Inst, ValueMapT &VectorMap,
+                          VectorValueMapT &ScalarMaps);
+
+  bool extractScalarValues(const Instruction *Inst, ValueMapT &VectorMap,
+                           VectorValueMapT &ScalarMaps);
+
+  bool hasVectorOperands(const Instruction *Inst, ValueMapT &VectorMap);
+
+  void copyInstruction(const Instruction *Inst, ValueMapT &VectorMap,
+                       VectorValueMapT &ScalarMaps);
+
+  void copyBB();
+};
+}
+#endif
diff --git a/rc1/include/polly/CodeGen/Cloog.h b/rc1/include/polly/CodeGen/Cloog.h
new file mode 100644
index 0000000..20c7525
--- /dev/null
+++ b/rc1/include/polly/CodeGen/Cloog.h
@@ -0,0 +1,91 @@
+//===- 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/Config/config.h"
+#ifdef CLOOG_FOUND
+
+#include "polly/ScopPass.h"
+
+#define CLOOG_INT_GMP 1
+#include "cloog/cloog.h"
+
+struct clast_name;
+namespace llvm {
+class raw_ostream;
+}
+
+namespace polly {
+class Scop;
+class Cloog;
+
+class CloogInfo : public ScopPass {
+  Cloog *C;
+  Scop *scop;
+
+public:
+  static char ID;
+  CloogInfo() : ScopPass(ID), C(0) {}
+
+  /// Write a .cloog input file
+  void dump(FILE *F);
+
+  /// Print a source code representation of the program.
+  void pprint(llvm::raw_ostream &OS);
+
+  /// Create the CLooG AST from this program.
+  const struct clast_root *getClast();
+
+  bool runOnScop(Scop &S);
+  void printScop(llvm::raw_ostream &OS) const;
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void releaseMemory();
+};
+
+// Visitor class for clasts.
+// Only 'visitUser' has to be implemented by subclasses; the default
+// implementations of the other methods traverse the clast recursively.
+class ClastVisitor {
+public:
+  virtual void visit(const clast_stmt *stmt);
+
+  virtual void visitAssignment(const clast_assignment *stmt);
+  virtual void visitBlock(const clast_block *stmt);
+  virtual void visitFor(const clast_for *stmt);
+  virtual void visitGuard(const clast_guard *stmt);
+
+  virtual void visitUser(const clast_user_stmt *stmt) = 0;
+  virtual ~ClastVisitor() {}
+};
+}
+
+namespace llvm {
+class PassRegistry;
+void initializeCloogInfoPass(llvm::PassRegistry &);
+}
+
+#endif /* CLOOG_FOUND */
+#endif /* POLLY_CLOOG_H */
diff --git a/rc1/include/polly/CodeGen/CodeGeneration.h b/rc1/include/polly/CodeGen/CodeGeneration.h
new file mode 100644
index 0000000..f5be373
--- /dev/null
+++ b/rc1/include/polly/CodeGen/CodeGeneration.h
@@ -0,0 +1,71 @@
+//===------ polly/CodeGeneration.h - The Polly code generator *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_CODEGENERATION_H
+#define POLLY_CODEGENERATION_H
+
+#include "polly/Config/config.h"
+
+#include "isl/set.h"
+#include "isl/map.h"
+
+namespace polly {
+enum VectorizerChoice {
+  VECTORIZER_NONE,
+  VECTORIZER_POLLY,
+  VECTORIZER_UNROLL_ONLY,
+  VECTORIZER_FIRST_NEED_GROUPED_UNROLL = VECTORIZER_UNROLL_ONLY,
+  VECTORIZER_BB
+};
+extern VectorizerChoice PollyVectorizerChoice;
+
+static inline int getNumberOfIterations(__isl_take isl_set *Domain) {
+  int Dim = isl_set_dim(Domain, isl_dim_set);
+
+  // Calculate a map similar to the identity map, but with the last input
+  // and output dimension not related.
+  //  [i0, i1, i2, i3] -> [i0, i1, i2, o0]
+  isl_space *Space = isl_set_get_space(Domain);
+  Space = isl_space_drop_dims(Space, isl_dim_out, Dim - 1, 1);
+  Space = isl_space_map_from_set(Space);
+  isl_map *Identity = isl_map_identity(Space);
+  Identity = isl_map_add_dims(Identity, isl_dim_in, 1);
+  Identity = isl_map_add_dims(Identity, isl_dim_out, 1);
+
+  isl_map *Map =
+      isl_map_from_domain_and_range(isl_set_copy(Domain), isl_set_copy(Domain));
+  isl_set_free(Domain);
+  Map = isl_map_intersect(Map, Identity);
+
+  isl_map *LexMax = isl_map_lexmax(isl_map_copy(Map));
+  isl_map *LexMin = isl_map_lexmin(Map);
+  isl_map *Sub = isl_map_sum(LexMax, isl_map_neg(LexMin));
+
+  isl_set *Elements = isl_map_range(Sub);
+
+  if (!isl_set_is_singleton(Elements)) {
+    isl_set_free(Elements);
+    return -1;
+  }
+
+  isl_point *P = isl_set_sample_point(Elements);
+
+  isl_val *V;
+  V = isl_point_get_coordinate_val(P, isl_dim_set, Dim - 1);
+  int NumberIterations = isl_val_get_num_si(V);
+  isl_val_free(V);
+  isl_point_free(P);
+
+  return NumberIterations;
+}
+}
+
+#endif // POLLY_CODEGENERATION_H
diff --git a/rc1/include/polly/CodeGen/IRBuilder.h b/rc1/include/polly/CodeGen/IRBuilder.h
new file mode 100644
index 0000000..a2b7e31
--- /dev/null
+++ b/rc1/include/polly/CodeGen/IRBuilder.h
@@ -0,0 +1,105 @@
+//===- Codegen/IRBuilder.h - The IR builder used by Polly -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The Polly IRBuilder file contains Polly specific extensions for the IRBuilder
+// that are used e.g. to emit the llvm.loop.parallel metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_CODEGEN_IRBUILDER_H
+#define POLLY_CODEGEN_IRBUILDER_H
+
+#include "llvm/IR/IRBuilder.h"
+namespace polly {
+
+/// @brief Keeps information about generated loops.
+class PollyLoopInfo {
+public:
+  PollyLoopInfo(llvm::BasicBlock *Header)
+      : LoopID(0), Header(Header), Parallel(false) {}
+
+  /// @brief Get the loop id metadata node.
+  ///
+  /// Each loop is identified by a self referencing metadata node of the form:
+  ///
+  ///    '!n = metadata !{metadata !n}'
+  ///
+  /// This functions creates such metadata on demand if not yet available.
+  ///
+  /// @return The loop id metadata node.
+  llvm::MDNode *GetLoopID() const;
+
+  /// @brief Get the head basic block of this loop.
+  llvm::BasicBlock *GetHeader() const { return Header; }
+
+  /// @brief Check if the loop is parallel.
+  ///
+  /// @return True, if the loop is parallel.
+  bool IsParallel() const { return Parallel; }
+
+  /// @brief Set a loop as parallel.
+  ///
+  /// @IsParallel True, if the loop is to be marked as parallel. False, if the
+  //              loop should be marked sequential.
+  void SetParallel(bool IsParallel = true) { Parallel = IsParallel; }
+
+private:
+  mutable llvm::MDNode *LoopID;
+  llvm::BasicBlock *Header;
+  bool Parallel;
+};
+
+class LoopAnnotator {
+public:
+  void Begin(llvm::BasicBlock *Header);
+  void SetCurrentParallel();
+  void End();
+  void Annotate(llvm::Instruction *I);
+
+private:
+  std::vector<PollyLoopInfo> Active;
+};
+
+/// @brief Add Polly specifics when running IRBuilder.
+///
+/// This is used to add additional items such as e.g. the llvm.loop.parallel
+/// metadata.
+template <bool PreserveNames>
+class PollyBuilderInserter
+    : protected llvm::IRBuilderDefaultInserter<PreserveNames> {
+public:
+  PollyBuilderInserter() : Annotator(0) {}
+  PollyBuilderInserter(class LoopAnnotator &A) : Annotator(&A) {}
+
+protected:
+  void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
+                    llvm::BasicBlock *BB,
+                    llvm::BasicBlock::iterator InsertPt) const {
+    llvm::IRBuilderDefaultInserter<PreserveNames>::InsertHelper(I, Name, BB,
+                                                                InsertPt);
+    if (Annotator)
+      Annotator->Annotate(I);
+  }
+
+private:
+  class LoopAnnotator *Annotator;
+};
+
+// TODO: We should not name instructions in NDEBUG builds.
+//
+// We currently always name instructions, as the polly test suite currently
+// matches for certain names.
+//
+// typedef PollyBuilderInserter<false> IRInserter;
+// typedef llvm::IRBuilder<false, llvm::ConstantFolder, IRInserter>
+// PollyIRBuilder;
+typedef PollyBuilderInserter<true> IRInserter;
+typedef llvm::IRBuilder<true, llvm::ConstantFolder, IRInserter> PollyIRBuilder;
+}
+#endif
diff --git a/rc1/include/polly/CodeGen/IslAst.h b/rc1/include/polly/CodeGen/IslAst.h
new file mode 100644
index 0000000..e717ba7
--- /dev/null
+++ b/rc1/include/polly/CodeGen/IslAst.h
@@ -0,0 +1,110 @@
+//===- IslAst.h - Interface to the isl code generator-------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The isl code generator interface takes a Scop and generates a isl_ast. This
+// ist_ast can either be returned directly or it can be pretty printed to
+// stdout.
+//
+// A typical isl_ast output looks like this:
+//
+// for (c2 = max(0, ceild(n + m, 2); c2 <= min(511, floord(5 * n, 3)); c2++) {
+//   bb2(c2);
+// }
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_ISL_AST_H
+#define POLLY_ISL_AST_H
+
+#include "polly/Config/config.h"
+#include "polly/ScopPass.h"
+
+#include "isl/ast.h"
+
+namespace llvm {
+class raw_ostream;
+}
+
+struct isl_ast_node;
+struct isl_ast_expr;
+struct isl_ast_build;
+struct isl_pw_multi_aff;
+
+namespace polly {
+class Scop;
+class IslAst;
+
+// Information about an ast node.
+struct IslAstUserPayload {
+  struct isl_ast_build *Context;
+  // The node is the outermost parallel loop.
+  int IsOutermostParallel;
+
+  // The node is the innermost parallel loop.
+  int IsInnermostParallel;
+
+  // The node is only parallel because of reductions
+  bool IsReductionParallel;
+};
+
+class IslAstInfo : public ScopPass {
+  Scop *S;
+  IslAst *Ast;
+
+public:
+  static char ID;
+  IslAstInfo() : ScopPass(ID), Ast(NULL) {}
+
+  /// Print a source code representation of the program.
+  void pprint(llvm::raw_ostream &OS);
+
+  isl_ast_node *getAst();
+
+  /// @brief Get the run conditon.
+  ///
+  /// Only if the run condition evaluates at run-time to a non-zero value, the
+  /// assumptions that have been taken hold. If the run condition evaluates to
+  /// zero/false some assumptions do not hold and the original code needs to
+  /// be executed.
+  __isl_give isl_ast_expr *getRunCondition();
+
+  bool runOnScop(Scop &S);
+  void printScop(llvm::raw_ostream &OS) const;
+
+  /// @name Extract information attached to an isl ast (for) node.
+  ///
+  ///{
+
+  /// @brief Get the complete payload attached to @p Node.
+  static IslAstUserPayload *getNodePayload(__isl_keep isl_ast_node *Node);
+
+  /// @brief Is this loop a parallel loop?
+  static bool isParallel(__isl_keep isl_ast_node *Node);
+
+  /// @brief Is this loop an outer parallel loop?
+  static bool isOuterParallel(__isl_keep isl_ast_node *Node);
+
+  /// @brief Is this loop an innermost parallel loop?
+  static bool isInnermostParallel(__isl_keep isl_ast_node *Node);
+
+  /// @brief Is this loop a reduction parallel loop?
+  static bool isReductionParallel(__isl_keep isl_ast_node *Node);
+
+  ///}
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void releaseMemory();
+};
+}
+
+namespace llvm {
+class PassRegistry;
+void initializeIslAstInfoPass(llvm::PassRegistry &);
+}
+#endif /* POLLY_ISL_AST_H */
diff --git a/rc1/include/polly/CodeGen/LoopGenerators.h b/rc1/include/polly/CodeGen/LoopGenerators.h
new file mode 100644
index 0000000..37d5dc9
--- /dev/null
+++ b/rc1/include/polly/CodeGen/LoopGenerators.h
@@ -0,0 +1,119 @@
+//===- LoopGenerators.h - IR helper to create loops -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions to create scalar and OpenMP parallel loops
+// as LLVM-IR.
+//
+//===----------------------------------------------------------------------===//
+#ifndef POLLY_LOOP_GENERATORS_H
+#define POLLY_LOOP_GENERATORS_H
+#include "polly/CodeGen/IRBuilder.h"
+#include "llvm/ADT/SetVector.h"
+
+#include <map>
+
+namespace llvm {
+class Value;
+class Pass;
+class BasicBlock;
+}
+
+namespace polly {
+using namespace llvm;
+
+/// @brief Create a scalar loop.
+///
+/// @param LowerBound The starting value of the induction variable.
+/// @param UpperBound The upper bound of the induction variable.
+/// @param Stride     The value by which the induction variable is incremented.
+///
+/// @param Builder    The builder used to create the loop.
+/// @param P          A pointer to the pass that uses this function. It is used
+///                   to update analysis information.
+/// @param ExitBlock  The block the loop will exit to.
+/// @param Predicate  The predicate used to generate the upper loop bound.
+/// @param Annotator  This function can (optionally) take a LoopAnnotator which
+///                   tracks the loop structure.
+/// @param Parallel   If this loop should be marked parallel in the Annotator.
+/// @return Value*    The newly created induction variable for this loop.
+Value *createLoop(Value *LowerBound, Value *UpperBound, Value *Stride,
+                  PollyIRBuilder &Builder, Pass *P, BasicBlock *&ExitBlock,
+                  ICmpInst::Predicate Predicate,
+                  LoopAnnotator *Annotator = NULL, bool Parallel = false);
+
+class OMPGenerator {
+public:
+  typedef std::map<Value *, Value *> ValueToValueMapTy;
+
+  OMPGenerator(PollyIRBuilder &Builder, Pass *P) : Builder(Builder), P(P) {}
+
+  /// @brief Create an OpenMP parallel loop.
+  ///
+  ///
+  /// @param LowerBound  The starting value of the induction variable.
+  /// @param UpperBound  The upper bound of the induction variable.
+  /// @param Stride      The value by which the induction variable is
+  ///                    incremented.
+  ///
+  /// @param UsedValues  A set of LLVM-IR Values that should be available to
+  ///                    the new loop body.
+  /// @param VMap        This map is filled by createParallelLoop(). It
+  ///                    maps the values in UsedValues to Values through which
+  ///                    their content is available within the loop body.
+  /// @param LoopBody    A pointer to an iterator that is set to point to the
+  ///                    body of the created loop. It should be used to insert
+  ///                    instructions that form the actual loop body.
+  ///
+  /// @return Value*     The newly created induction variable for this loop.
+  Value *createParallelLoop(Value *LowerBound, Value *UpperBound, Value *Stride,
+                            SetVector<Value *> &UsedValues,
+                            ValueToValueMapTy &VMap,
+                            BasicBlock::iterator *LoopBody);
+
+private:
+  PollyIRBuilder &Builder;
+  Pass *P;
+
+  IntegerType *getIntPtrTy();
+  Module *getModule();
+
+  void createCallParallelLoopStart(Value *SubFunction, Value *SubfunctionParam,
+                                   Value *NumberOfThreads, Value *LowerBound,
+                                   Value *UpperBound, Value *Stride);
+  Value *createCallLoopNext(Value *LowerBoundPtr, Value *UpperBoundPtr);
+  void createCallParallelEnd();
+  void createCallLoopEndNowait();
+
+  Value *loadValuesIntoStruct(SetVector<Value *> &Values);
+  void extractValuesFromStruct(SetVector<Value *> OldValues, Value *Struct,
+                               ValueToValueMapTy &Map);
+
+  /// @brief Create the OpenMP subfunction.
+  ///
+  /// @param Stride       The value by which the induction variable is
+  ///                     incremented.
+  /// @param Struct       The structure that is used to make Values available to
+  ///                     the loop body.
+  /// @param UsedValues   A set of LLVM-IR Values that should be available to
+  ///                     the new loop body.
+  /// @param VMap         This map that is filled by createSubfunction(). It
+  ///                     maps the values in UsedValues to Values through which
+  ///                     their content is available within the loop body.
+  /// @param SubFunction  The newly created SubFunction is returned here.
+  ///
+  /// @return Value*      The newly created induction variable.
+  Value *createSubfunction(Value *Stride, Value *Struct,
+                           SetVector<Value *> UsedValues,
+                           ValueToValueMapTy &VMap, Function **SubFunction);
+
+  /// @brief Create the definition of the OpenMP subfunction.
+  Function *createSubfunctionDefinition();
+};
+} // end namespace polly
+#endif
diff --git a/rc1/include/polly/CodeGen/PTXGenerator.h b/rc1/include/polly/CodeGen/PTXGenerator.h
new file mode 100644
index 0000000..f4c5038
--- /dev/null
+++ b/rc1/include/polly/CodeGen/PTXGenerator.h
@@ -0,0 +1,184 @@
+//===- PTXGenerator.h - IR helper to create GPGPU LLVM-IR -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions to create GPGPU parallel loops as LLVM-IR.
+//
+//===----------------------------------------------------------------------===//
+#ifndef POLLY_CODEGEN_PTXGENERATOR_H
+#define POLLY_CODEGEN_PTXGENERATOR_H
+
+#include "polly/Config/config.h"
+
+#ifdef GPU_CODEGEN
+#include "polly/CodeGen/IRBuilder.h"
+#include "llvm/ADT/SetVector.h"
+
+#include <map>
+
+namespace llvm {
+class Value;
+class Pass;
+class BasicBlock;
+}
+
+namespace polly {
+using namespace llvm;
+
+class PTXGenerator {
+public:
+  typedef std::map<Value *, Value *> ValueToValueMapTy;
+
+  PTXGenerator(PollyIRBuilder &Builder, Pass *P, const std::string &Triple);
+
+  /// @brief Create a GPGPU parallel loop.
+  ///
+  /// @param UsedValues   A set of LLVM-IR Values that should be available to
+  ///                     the new loop body.
+  /// @param OriginalIVS  The new values of the original induction variables.
+  /// @param VMap         This map is filled by createParallelLoop(). It
+  ///                     maps the values in UsedValues to Values through which
+  ///                     their content is available within the loop body.
+  /// @param LoopBody     A pointer to an iterator that is set to point to the
+  ///                     body of the created loop. It should be used to insert
+  ///                     instructions that form the actual loop body.
+  void startGeneration(SetVector<Value *> &UsedValues,
+                       SetVector<Value *> &OriginalIVS, ValueToValueMapTy &VMap,
+                       BasicBlock::iterator *LoopBody);
+
+  /// @brief Execute the post-operations to build a GPGPU parallel loop.
+  ///
+  void finishGeneration(Function *SubFunction);
+
+  /// @brief Set the parameters for launching PTX kernel.
+  ///
+  /// @param GridW    A value of the width of a GPU grid.
+  /// @param GridH    A value of the height of a GPU grid.
+  /// @param BlockW   A value of the width of a GPU block.
+  /// @param BlockH   A value of the height of a GPU block.
+  void setLaunchingParameters(int GridW, int GridH, int BlockW, int BlockH) {
+    GridWidth = GridW;
+    GridHeight = GridH;
+    BlockWidth = BlockW;
+    BlockHeight = BlockH;
+  }
+
+  /// @brief Set the size of the output array.
+  ///
+  /// This size is used to allocate memory on the device and the host.
+  ///
+  /// @param Bytes        Output array size in bytes.
+  void setOutputBytes(unsigned Bytes) { OutputBytes = Bytes; }
+
+private:
+  PollyIRBuilder &Builder;
+  Pass *P;
+
+  /// @brief The target triple of the device.
+  const std::string &GPUTriple;
+
+  ///@brief Parameters used for launching PTX kernel.
+  int GridWidth, GridHeight, BlockWidth, BlockHeight;
+
+  /// @brief Size of the output array in bytes.
+  unsigned OutputBytes;
+
+  /// @brief Polly's GPU data types.
+  StructType *ContextTy, *ModuleTy, *KernelTy, *DeviceTy, *DevDataTy, *EventTy;
+
+  void InitializeGPUDataTypes();
+  IntegerType *getInt64Type();           // i64
+  PointerType *getI8PtrType();           // char *
+  PointerType *getPtrI8PtrType();        // char **
+  PointerType *getFloatPtrType();        // float *
+  PointerType *getGPUContextPtrType();   // %struct.PollyGPUContextT *
+  PointerType *getGPUModulePtrType();    // %struct.PollyGPUModuleT *
+  PointerType *getGPUDevicePtrType();    // %struct.PollyGPUDeviceT *
+  PointerType *getPtrGPUDevicePtrType(); // %struct.PollyGPUDevicePtrT *
+  PointerType *getGPUFunctionPtrType();  // %struct.PollyGPUFunctionT *
+  PointerType *getGPUEventPtrType();     // %struct.PollyGPUEventT *
+
+  Module *getModule();
+
+  /// @brief Create the kernel string containing LLVM IR.
+  ///
+  /// @param SubFunction  A pointer to the device code function.
+  /// @return             A global string variable containing the LLVM IR codes
+  //                      of the SubFunction.
+  Value *createPTXKernelFunction(Function *SubFunction);
+
+  /// @brief Get the entry name of the device kernel function.
+  ///
+  /// @param SubFunction  A pointer to the device code function.
+  /// @return             A global string variable containing the entry name of
+  ///                     the SubFunction.
+  Value *getPTXKernelEntryName(Function *SubFunction);
+
+  void createCallInitDevice(Value *Context, Value *Device);
+  void createCallGetPTXModule(Value *Buffer, Value *Module);
+  void createCallGetPTXKernelEntry(Value *Entry, Value *Module, Value *Kernel);
+  void createCallAllocateMemoryForHostAndDevice(Value *HostData,
+                                                Value *DeviceData, Value *Size);
+  void createCallCopyFromHostToDevice(Value *DeviceData, Value *HostData,
+                                      Value *Size);
+  void createCallCopyFromDeviceToHost(Value *HostData, Value *DeviceData,
+                                      Value *Size);
+  void createCallSetKernelParameters(Value *Kernel, Value *BlockWidth,
+                                     Value *BlockHeight, Value *DeviceData);
+  void createCallLaunchKernel(Value *Kernel, Value *GridWidth,
+                              Value *GridHeight);
+  void createCallStartTimerByCudaEvent(Value *StartEvent, Value *StopEvent);
+  void createCallStopTimerByCudaEvent(Value *StartEvent, Value *StopEvent,
+                                      Value *Timer);
+  void createCallCleanupGPGPUResources(Value *HostData, Value *DeviceData,
+                                       Value *Module, Value *Context,
+                                       Value *Kernel);
+
+  /// @brief Create the CUDA subfunction.
+  ///
+  /// @param UsedValues   A set of LLVM-IR Values that should be available to
+  ///                     the new loop body.
+  /// @param VMap         This map that is filled by createSubfunction(). It
+  ///                     maps the values in UsedValues to Values through which
+  ///                     their content is available within the loop body.
+  /// @param OriginalIVS  The new values of the original induction variables.
+  /// @param SubFunction  The newly created SubFunction is returned here.
+  void createSubfunction(SetVector<Value *> &UsedValues,
+                         SetVector<Value *> &OriginalIVS,
+                         ValueToValueMapTy &VMap, Function **SubFunction);
+
+  /// @brief Create the definition of the CUDA subfunction.
+  ///
+  /// @param NumArgs      The number of parameters of this subfunction. This is
+  ///                     usually set to the number of memory accesses which
+  ///                     will be copied from host to device.
+  Function *createSubfunctionDefinition(int NumArgs);
+
+  /// @brief Get the Value of CUDA block width.
+  Value *getCUDABlockWidth();
+
+  /// @brief Get the Value of CUDA block height.
+  Value *getCUDABlockHeight();
+
+  /// @brief Get the Value of CUDA Gird width.
+  Value *getCUDAGridWidth();
+
+  /// @brief Get the Value of CUDA grid height.
+  Value *getCUDAGridHeight();
+
+  /// @brief Get the Value of the bytes of the output array.
+  Value *getOutputArraySizeInBytes();
+
+  /// @brief Erase the ptx-related subfunctions and declarations.
+  ///
+  /// @param SubFunction  A pointer to the device code function.
+  void eraseUnusedFunctions(Function *SubFunction);
+};
+} // end namespace polly
+#endif /* GPU_CODEGEN */
+#endif /* POLLY_CODEGEN_PTXGENERATOR_H */
diff --git a/rc1/include/polly/CodeGen/Utils.h b/rc1/include/polly/CodeGen/Utils.h
new file mode 100644
index 0000000..341ba05
--- /dev/null
+++ b/rc1/include/polly/CodeGen/Utils.h
@@ -0,0 +1,61 @@
+//===- Utils.h - Utility functions for code generation ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains utility functions for the code generation.
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_CODEGEN_UTILS_H
+#define POLLY_CODEGEN_UTILS_H
+
+namespace llvm {
+class Pass;
+class BasicBlock;
+}
+
+namespace polly {
+
+class Scop;
+
+/// @brief Execute a Scop conditionally.
+///
+/// In the CFG the optimized code of the Scop is generated next to the
+/// original code. Both the new and the original version of the code remain
+/// in the CFG. A branch statement decides which version is executed.
+/// For now, we always execute the new version (the old one is dead code
+/// eliminated by the cleanup passes). In the future we may decide to execute
+/// the new version only if certain run time checks succeed. This will be
+/// useful to support constructs for which we cannot prove all assumptions at
+/// compile time.
+///
+/// Before transformation:
+///
+///                        bb0
+///                         |
+///                     orig_scop
+///                         |
+///                        bb1
+///
+/// After transformation:
+///                        bb0
+///                         |
+///                  polly.splitBlock
+///                     /       \.
+///                     |     startBlock
+///                     |        |
+///               orig_scop   new_scop
+///                     \      /
+///                      \    /
+///                        bb1 (joinBlock)
+///
+/// @param S The Scop to execute conditionally.
+/// @param PassInfo A reference to the pass calling this function.
+/// @return BasicBlock The 'StartBlock' to which new code can be added.
+llvm::BasicBlock *executeScopConditionally(Scop &S, llvm::Pass *PassInfo);
+}
+#endif
diff --git a/rc1/include/polly/Config/config.h.cmake b/rc1/include/polly/Config/config.h.cmake
new file mode 100755
index 0000000..ea58925
--- /dev/null
+++ b/rc1/include/polly/Config/config.h.cmake
@@ -0,0 +1,22 @@
+//===- 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 CLOOG_FOUND
+#cmakedefine PLUTO_FOUND
+#cmakedefine SCOPLIB_FOUND
+#cmakedefine CUDALIB_FOUND
+#cmakedefine GPU_CODEGEN
+
+#endif
diff --git a/rc1/include/polly/Config/config.h.in b/rc1/include/polly/Config/config.h.in
new file mode 100644
index 0000000..d6de05a
--- /dev/null
+++ b/rc1/include/polly/Config/config.h.in
@@ -0,0 +1,37 @@
+/* include/polly/Config/config.h.in.  Generated from autoconf/configure.ac by autoheader.  */
+
+/* Define if cloog found */
+#undef CLOOG_FOUND
+
+/* Use gmp for isl */
+#undef CLOOG_INT_GMP
+
+/* Define if cudalib found */
+#undef CUDALIB_FOUND
+
+/* Define if gpu codegen is enabled */
+#undef GPU_CODEGEN
+
+/* 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 pluto found */
+#undef PLUTO_FOUND
+
+/* Define if scoplib found */
+#undef SCOPLIB_FOUND
diff --git a/rc1/include/polly/Dependences.h b/rc1/include/polly/Dependences.h
new file mode 100755
index 0000000..b305660
--- /dev/null
+++ b/rc1/include/polly/Dependences.h
@@ -0,0 +1,146 @@
+//===------ 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>
+#include "isl/ctx.h"
+
+struct isl_union_map;
+struct isl_union_set;
+struct isl_map;
+struct isl_set;
+struct clast_for;
+
+using namespace llvm;
+
+namespace polly {
+
+class Scop;
+class ScopStmt;
+
+class Dependences : public ScopPass {
+public:
+  static char ID;
+
+  /// @brief The type of the dependences.
+  ///
+  /// Reduction dependences are separated from RAW/WAW/WAR dependences because
+  /// we can ignore them during the scheduling. This is the case since the order
+  /// in which the reduction statements are executed does not matter. However,
+  /// if they are executed in parallel we need to take additional measures
+  /// (e.g, privatization) to ensure a correct result. The (reverse) transitive
+  /// closure of the reduction dependences are used to check for parallel
+  /// executed reduction statements during code generation. These dependences
+  /// connect all instances of a reduction with each other, they are therefor
+  /// cyclic and possibly "reversed".
+  enum Type {
+    // Write after read
+    TYPE_WAR = 1 << 0,
+
+    // Read after write
+    TYPE_RAW = 1 << 1,
+
+    // Write after write
+    TYPE_WAW = 1 << 2,
+
+    // Reduction dependences
+    TYPE_RED = 1 << 3,
+
+    // Transitive closure of the reduction dependences (& the reverse)
+    TYPE_TC_RED = 1 << 4,
+  };
+
+  typedef std::map<ScopStmt *, isl_map *> StatementToIslMapTy;
+
+  Dependences();
+
+  // @brief Check if a new scattering is valid.
+  //
+  // @param NewScattering The new scatterings
+  //
+  // @return bool True if the new scattering is valid, false it it reverses
+  //              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_take isl_set *LoopDomain,
+                           unsigned ParallelDimension);
+
+  /// @brief Get the dependences in this Scop.
+  ///
+  /// @param Kinds This integer defines the different kinds of dependences
+  ///              that will be returned. To return more than one kind, the
+  ///              different kinds are 'ored' together.
+  isl_union_map *getDependences(int Kinds);
+
+  /// @brief Report if valid dependences are available.
+  bool hasValidDependences();
+
+  bool runOnScop(Scop &S);
+  void printScop(raw_ostream &OS) const;
+  virtual void releaseMemory();
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+private:
+  // The different kinds of dependences we calculate.
+  isl_union_map *RAW;
+  isl_union_map *WAR;
+  isl_union_map *WAW;
+
+  /// @brief The map of reduction dependences
+  isl_union_map *RED = nullptr;
+
+  /// @brief The (reverse) transitive closure of reduction dependences
+  isl_union_map *TC_RED = nullptr;
+
+  /// @brief Collect information about the SCoP.
+  void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
+                   isl_union_map **MayWrite, isl_union_map **AccessSchedule,
+                   isl_union_map **StmtSchedule);
+
+  /// @brief Calculate and add at the privatization dependences
+  void addPrivatizationDependences();
+
+  // @brief Calculate the dependences for a certain SCoP.
+  void calculateDependences(Scop &S);
+};
+
+} // End polly namespace.
+
+namespace llvm {
+class PassRegistry;
+void initializeDependencesPass(llvm::PassRegistry &);
+}
+
+#endif
diff --git a/rc1/include/polly/LinkAllPasses.h b/rc1/include/polly/LinkAllPasses.h
new file mode 100644
index 0000000..edce2b0
--- /dev/null
+++ b/rc1/include/polly/LinkAllPasses.h
@@ -0,0 +1,135 @@
+//===- 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 PassRegistry;
+class RegionPass;
+}
+
+namespace polly {
+#ifdef CLOOG_FOUND
+llvm::Pass *createCloogExporterPass();
+llvm::Pass *createCloogInfoPass();
+llvm::Pass *createCodeGenerationPass();
+#endif
+llvm::Pass *createCodePreparationPass();
+llvm::Pass *createDeadCodeElimPass();
+llvm::Pass *createDependencesPass();
+llvm::Pass *createDOTOnlyPrinterPass();
+llvm::Pass *createDOTOnlyViewerPass();
+llvm::Pass *createDOTPrinterPass();
+llvm::Pass *createDOTViewerPass();
+llvm::Pass *createIndependentBlocksPass();
+llvm::Pass *createIndVarSimplifyPass();
+llvm::Pass *createJSONExporterPass();
+llvm::Pass *createJSONImporterPass();
+#ifdef PLUTO_FOUND
+llvm::Pass *createPlutoOptimizerPass();
+#endif
+llvm::Pass *createPollyCanonicalizePass();
+llvm::Pass *createScopDetectionPass();
+llvm::Pass *createScopInfoPass();
+llvm::Pass *createIslAstInfoPass();
+llvm::Pass *createIslCodeGenerationPass();
+llvm::Pass *createIslScheduleOptimizerPass();
+llvm::Pass *createTempScopInfoPass();
+
+#ifdef SCOPLIB_FOUND
+llvm::Pass *createPoccPass();
+llvm::Pass *createScopLibExporterPass();
+llvm::Pass *createScopLibImporterPass();
+#endif
+
+extern char &IndependentBlocksID;
+extern char &CodePreparationID;
+}
+
+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;
+
+#ifdef CLOOG_FOUND
+    polly::createCloogExporterPass();
+    polly::createCloogInfoPass();
+    polly::createCodeGenerationPass();
+#endif
+    polly::createCodePreparationPass();
+    polly::createDeadCodeElimPass();
+    polly::createDependencesPass();
+    polly::createDOTOnlyPrinterPass();
+    polly::createDOTOnlyViewerPass();
+    polly::createDOTPrinterPass();
+    polly::createDOTViewerPass();
+    polly::createIndependentBlocksPass();
+    polly::createIndVarSimplifyPass();
+    polly::createJSONExporterPass();
+    polly::createJSONImporterPass();
+    polly::createScopDetectionPass();
+    polly::createScopInfoPass();
+#ifdef PLUTO_FOUND
+    polly::createPlutoOptimizerPass();
+#endif
+    polly::createPollyCanonicalizePass();
+    polly::createIslAstInfoPass();
+    polly::createIslCodeGenerationPass();
+    polly::createIslScheduleOptimizerPass();
+    polly::createTempScopInfoPass();
+
+#ifdef SCOPLIB_FOUND
+    polly::createPoccPass();
+    polly::createScopLibExporterPass();
+    polly::createScopLibImporterPass();
+#endif
+  }
+} PollyForcePassLinking; // Force link by creating a global definition.
+}
+
+namespace llvm {
+class PassRegistry;
+#ifdef CLOOG_FOUND
+void initializeCodeGenerationPass(llvm::PassRegistry &);
+#endif
+void initializeCodePreparationPass(llvm::PassRegistry &);
+void initializeDeadCodeElimPass(llvm::PassRegistry &);
+void initializeIndependentBlocksPass(llvm::PassRegistry &);
+void initializeJSONExporterPass(llvm::PassRegistry &);
+void initializeJSONImporterPass(llvm::PassRegistry &);
+void initializeIslAstInfoPass(llvm::PassRegistry &);
+void initializeIslCodeGenerationPass(llvm::PassRegistry &);
+void initializeIslScheduleOptimizerPass(llvm::PassRegistry &);
+#ifdef PLUTO_FOUND
+void initializePlutoOptimizerPass(llvm::PassRegistry &);
+#endif
+void initializePollyCanonicalizePass(llvm::PassRegistry &);
+#ifdef SCOPLIB_FOUND
+void initializePoccPass(llvm::PassRegistry &);
+#endif
+void initializePollyIndVarSimplifyPass(llvm::PassRegistry &);
+}
+
+#endif
diff --git a/rc1/include/polly/Options.h b/rc1/include/polly/Options.h
new file mode 100644
index 0000000..62e0960
--- /dev/null
+++ b/rc1/include/polly/Options.h
@@ -0,0 +1,20 @@
+//===--------------- polly/Options.h - The Polly option category *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Introduce an option category for Polly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_OPTIONS_H
+#define POLLY_OPTIONS_H
+
+#include "llvm/Support/CommandLine.h"
+
+extern llvm::cl::OptionCategory PollyCategory;
+#endif
diff --git a/rc1/include/polly/RegisterPasses.h b/rc1/include/polly/RegisterPasses.h
new file mode 100644
index 0000000..e53b45f
--- /dev/null
+++ b/rc1/include/polly/RegisterPasses.h
@@ -0,0 +1,28 @@
+//===------ polly/RegisterPasses.h - Register the Polly passes *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Functions to register the Polly passes in a LLVM pass manager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_REGISTER_PASSES_H
+#define POLLY_REGISTER_PASSES_H
+
+#include "llvm/PassManager.h"
+
+namespace llvm {
+namespace legacy {
+class PassManagerBase;
+}
+}
+
+namespace polly {
+void initializePollyPasses(llvm::PassRegistry &Registry);
+}
+#endif
diff --git a/rc1/include/polly/ScheduleOptimizer.h b/rc1/include/polly/ScheduleOptimizer.h
new file mode 100644
index 0000000..80272d2
--- /dev/null
+++ b/rc1/include/polly/ScheduleOptimizer.h
@@ -0,0 +1,19 @@
+//===------ polly/ScheduleOptimizer.h - The Schedule Optimizer *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCHEDULE_OPTIMIZER_H
+#define POLLY_SCHEDULE_OPTIMIZER_H
+
+namespace polly {
+extern bool DisablePollyTiling;
+}
+
+#endif
diff --git a/rc1/include/polly/ScopDetection.h b/rc1/include/polly/ScopDetection.h
new file mode 100644
index 0000000..96eeaef
--- /dev/null
+++ b/rc1/include/polly/ScopDetection.h
@@ -0,0 +1,373 @@
+//===--- 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 "polly/ScopDetectionDiagnostic.h"
+
+#include <set>
+#include <map>
+
+using namespace llvm;
+
+namespace llvm {
+class RegionInfo;
+class Region;
+class LoopInfo;
+class Loop;
+class ScalarEvolution;
+class SCEV;
+class SCEVAddRecExpr;
+class SCEVUnknown;
+class CallInst;
+class Instruction;
+class AliasAnalysis;
+class Value;
+}
+
+namespace polly {
+typedef std::set<const SCEV *> ParamSetType;
+
+// Description of the shape of an array.
+struct ArrayShape {
+  // Base pointer identifying all accesses to this array.
+  const SCEVUnknown *BasePointer;
+
+  // Sizes of each delinearized dimension.
+  SmallVector<const SCEV *, 4> DelinearizedSizes;
+
+  ArrayShape(const SCEVUnknown *B) : BasePointer(B), DelinearizedSizes() {}
+};
+
+struct MemAcc {
+  const Instruction *Insn;
+
+  // A pointer to the shape description of the array.
+  ArrayShape *Shape;
+
+  // Subscripts computed by delinearization.
+  SmallVector<const SCEV *, 4> DelinearizedSubscripts;
+
+  MemAcc(const Instruction *I, ArrayShape *S)
+      : Insn(I), Shape(S), DelinearizedSubscripts() {}
+};
+
+typedef std::map<const Instruction *, MemAcc *> MapInsnToMemAcc;
+typedef std::pair<const Instruction *, const SCEVAddRecExpr *> PairInsnAddRec;
+typedef std::vector<PairInsnAddRec> AFs;
+typedef std::map<const SCEVUnknown *, AFs> BaseToAFs;
+typedef std::map<const SCEVUnknown *, const SCEV *> BaseToElSize;
+
+extern bool PollyTrackFailures;
+extern bool PollyDelinearize;
+
+/// @brief A function attribute which will cause Polly to skip the function
+extern llvm::StringRef PollySkipFnAttr;
+
+//===----------------------------------------------------------------------===//
+/// @brief Pass to detect the maximal static control parts (Scops) of a
+/// function.
+class ScopDetection : public FunctionPass {
+  //===--------------------------------------------------------------------===//
+  ScopDetection(const ScopDetection &) LLVM_DELETED_FUNCTION;
+  const ScopDetection &operator=(const ScopDetection &) LLVM_DELETED_FUNCTION;
+
+  /// @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?
+    RejectLog Log;
+
+    // Map a base pointer to all access functions accessing it.
+    BaseToAFs NonAffineAccesses, AffineAccesses;
+    BaseToElSize ElementSize;
+
+    DetectionContext(Region &R, AliasAnalysis &AA, bool Verify)
+        : CurRegion(R), AST(AA), Verifying(Verify), Log(&R) {}
+  };
+
+  // Remember the valid regions
+  typedef std::set<const Region *> RegionSet;
+  RegionSet ValidRegions;
+
+  // Remember a list of errors for every region.
+  mutable RejectLogsContainer RejectLogs;
+
+  // Delinearize all non affine memory accesses and return false when there
+  // exists a non affine memory access that cannot be delinearized. Return true
+  // when all array accesses are affine after delinearization.
+  bool hasAffineMemoryAccesses(DetectionContext &Context) const;
+
+  // 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.
+  ///
+  /// @param The region tree to scan for scops.
+  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 region is a Scop.
+  ///
+  /// @param Context The context of scop detection.
+  ///
+  /// @return True if R is a Scop, false otherwise.
+  bool isValidRegion(Region &R) 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 value is invariant in the region Reg.
+  ///
+  /// @param Val Value to check for invariance.
+  /// @param Reg The region to consider for the invariance of Val.
+  ///
+  /// @return True if the value represented by Val is invariant in the region
+  ///         identified by Reg.
+  bool isInvariant(const Value &Val, const Region &Reg) const;
+
+  /// @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 &Inst, DetectionContext &Context) const;
+
+  /// @brief Check if the control flow in a basic block is valid.
+  ///
+  /// @param BB The BB to check the control flow.
+  /// @param Context The context of scop detection.
+  ///
+  /// @return True if the BB contains only valid control flow.
+  bool isValidCFG(BasicBlock &BB, DetectionContext &Context) const;
+
+  /// @brief Is a loop valid with respect to a given region.
+  ///
+  /// @param L The loop to check.
+  /// @param Context The context of scop detection.
+  ///
+  /// @return True if the loop is valid in the region.
+  bool isValidLoop(Loop *L, DetectionContext &Context) const;
+
+  /// @brief Check if the function @p F is marked as invalid.
+  ///
+  /// @note An OpenMP subfunction will be marked as invalid.
+  bool isValidFunction(llvm::Function &F);
+
+  /// @brief Print the locations of all detected scops.
+  void printLocations(llvm::Function &F);
+
+  /// @brief Track diagnostics for invalid scops.
+  ///
+  /// @param Context The context of scop detection.
+  /// @param Assert Throw an assert in verify mode or not.
+  /// @param Args Argument list that gets passed to the constructor of RR.
+  template <class RR, typename... Args>
+  inline bool invalid(DetectionContext &Context, bool Assert,
+                      Args &&... Arguments) const;
+
+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.
+  /// @param Verify Rerun the scop detection to verify SCoP was not invalidated
+  ///               meanwhile.
+  ///
+  /// @return Return true if R is the maximum Region in a Scop, false otherwise.
+  bool isMaxRegionInScop(const Region &R, bool Verify = true) const;
+
+  /// @brief Get a message why a region is invalid
+  ///
+  /// @param R The region for which we get the error message
+  ///
+  /// @return The error or "" if no error appeared.
+  std::string regionIsInvalidBecause(const Region *R) const;
+
+  /// @name Maximum Region In Scops Iterators
+  ///
+  /// These iterators iterator over all maximum region in Scops of this
+  /// function.
+  //@{
+  typedef RegionSet::iterator iterator;
+  typedef RegionSet::const_iterator const_iterator;
+
+  iterator begin() { return ValidRegions.begin(); }
+  iterator end() { return ValidRegions.end(); }
+
+  const_iterator begin() const { return ValidRegions.begin(); }
+  const_iterator end() const { return ValidRegions.end(); }
+  //@}
+
+  /// @name Reject log iterators
+  ///
+  /// These iterators iterate over the logs of all rejected regions of this
+  //  function.
+  //@{
+  typedef std::map<const Region *, RejectLog>::iterator reject_iterator;
+  typedef std::map<const Region *, RejectLog>::const_iterator
+      const_reject_iterator;
+
+  reject_iterator reject_begin() { return RejectLogs.begin(); }
+  reject_iterator reject_end() { return RejectLogs.end(); }
+
+  const_reject_iterator reject_begin() const { return RejectLogs.begin(); }
+  const_reject_iterator reject_end() const { return RejectLogs.end(); }
+  //@}
+
+  /// @brief Emit rejection remarks for all smallest invalid regions.
+  ///
+  /// @param F The function to emit remarks for.
+  /// @param R The region to start the region tree traversal for.
+  void emitMissedRemarksForLeaves(const Function &F, const Region *R);
+
+  /// @brief Emit rejection remarks for the parent regions of all valid regions.
+  ///
+  /// Emitting rejection remarks for the parent regions of all valid regions
+  /// may give the end-user clues about how to increase the size of the
+  /// detected Scops.
+  ///
+  /// @param F The function to emit remarks for.
+  /// @param ValidRegions The set of valid regions to emit remarks for.
+  void emitMissedRemarksForValidRegions(const Function &F,
+                                        const RegionSet &ValidRegions);
+
+  /// @brief Mark the function as invalid so we will not extract any scop from
+  ///        the function.
+  ///
+  /// @param F The function to mark as invalid.
+  void markFunctionAsInvalid(Function *F) const;
+
+  /// @brief Verify if all valid Regions in this Function are still valid
+  /// after some transformations.
+  void verifyAnalysis() const;
+
+  /// @brief Verify if R is still a valid part of Scop after some
+  /// transformations.
+  ///
+  /// @param R The Region to verify.
+  void verifyRegion(const Region &R) const;
+
+  /// @name FunctionPass interface
+  //@{
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void releaseMemory();
+  virtual bool runOnFunction(Function &F);
+  virtual void print(raw_ostream &OS, const Module *) const;
+  //@}
+};
+
+} // end namespace polly
+
+namespace llvm {
+class PassRegistry;
+void initializeScopDetectionPass(llvm::PassRegistry &);
+}
+
+#endif
diff --git a/rc1/include/polly/ScopDetectionDiagnostic.h b/rc1/include/polly/ScopDetectionDiagnostic.h
new file mode 100644
index 0000000..4d2dfad
--- /dev/null
+++ b/rc1/include/polly/ScopDetectionDiagnostic.h
@@ -0,0 +1,831 @@
+//=== ScopDetectionDiagnostic.h -- Diagnostic for ScopDetection -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Small set of diagnostic helper classes to encapsulate any errors occurred
+// during the detection of Scops.
+//
+// The ScopDetection defines a set of error classes (via Statistic variables)
+// that groups a number of individual errors into a group, e.g. non-affinity
+// related errors.
+// On error we generate an object that carries enough additional information
+// to diagnose the error and generate a helpful error message.
+//
+//===----------------------------------------------------------------------===//
+#ifndef POLLY_SCOP_DETECTION_DIAGNOSTIC_H
+#define POLLY_SCOP_DETECTION_DIAGNOSTIC_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Value.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Support/Casting.h"
+
+#include <string>
+#include <memory>
+
+using namespace llvm;
+
+namespace llvm {
+class SCEV;
+class BasicBlock;
+class Value;
+class Region;
+}
+
+namespace polly {
+
+/// @brief Get the location of a region from the debug info.
+///
+/// @param R The region to get debug info for.
+/// @param LineBegin The first line in the region.
+/// @param LineEnd The last line in the region.
+/// @param FileName The filename where the region was defined.
+void getDebugLocation(const Region *R, unsigned &LineBegin, unsigned &LineEnd,
+                      std::string &FileName);
+
+class RejectLog;
+/// @brief Emit optimization remarks about the rejected regions to the user.
+///
+/// This emits the content of the reject log as optimization remarks.
+/// Remember to at least track failures (-polly-detect-track-failures).
+/// @param F The function we emit remarks for.
+/// @param Log The error log containing all messages being emitted as remark.
+void emitRejectionRemarks(const llvm::Function &F, const RejectLog &Log);
+
+/// @brief Emit diagnostic remarks for a valid Scop
+///
+/// @param F The function we emit remarks for
+/// @param R The region that marks a valid Scop
+void emitValidRemarks(const llvm::Function &F, const Region *R);
+
+// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
+enum RejectReasonKind {
+  // CFG Category
+  rrkCFG,
+  rrkNonBranchTerminator,
+  rrkCondition,
+  rrkLastCFG,
+
+  // Non-Affinity
+  rrkAffFunc,
+  rrkUndefCond,
+  rrkInvalidCond,
+  rrkUndefOperand,
+  rrkNonAffBranch,
+  rrkNoBasePtr,
+  rrkUndefBasePtr,
+  rrkVariantBasePtr,
+  rrkNonAffineAccess,
+  rrkLastAffFunc,
+
+  // IndVar
+  rrkIndVar,
+  rrkPhiNodeRefInRegion,
+  rrkNonCanonicalPhiNode,
+  rrkLoopHeader,
+  rrkLastIndVar,
+
+  rrkIndEdge,
+
+  rrkLoopBound,
+
+  rrkFuncCall,
+
+  rrkAlias,
+
+  rrkSimpleLoop,
+
+  // Other
+  rrkOther,
+  rrkIntToPtr,
+  rrkAlloca,
+  rrkUnknownInst,
+  rrkPHIinExit,
+  rrkEntry,
+  rrkLastOther
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Base class of all reject reasons found during Scop detection.
+///
+/// Subclasses of RejectReason should provide means to capture enough
+/// diagnostic information to help clients figure out what and where something
+/// went wrong in the Scop detection.
+class RejectReason {
+  //===--------------------------------------------------------------------===//
+private:
+  const RejectReasonKind Kind;
+
+protected:
+  static const DebugLoc Unknown;
+
+public:
+  RejectReasonKind getKind() const { return Kind; }
+
+  RejectReason(RejectReasonKind K) : Kind(K) {}
+
+  virtual ~RejectReason() {}
+
+  /// @brief Generate a reasonable diagnostic message describing this error.
+  ///
+  /// @return A debug message representing this error.
+  virtual std::string getMessage() const = 0;
+
+  /// @brief Generate a message for the end-user describing this error.
+  ///
+  /// The message provided has to be suitable for the end-user. So it should
+  /// not reference any LLVM internal data structures or terminology.
+  /// Ideally, the message helps the end-user to increase the size of the
+  /// regions amenable to Polly.
+  ///
+  /// @return A short message representing this error.
+  virtual std::string getEndUserMessage() const {
+    return "Unspecified error.";
+  };
+
+  /// @brief Get the source location of this error.
+  ///
+  /// @return The debug location for this error.
+  virtual const llvm::DebugLoc &getDebugLoc() const;
+};
+
+typedef std::shared_ptr<RejectReason> RejectReasonPtr;
+
+/// @brief Stores all errors that ocurred during the detection.
+class RejectLog {
+  Region *R;
+  llvm::SmallVector<RejectReasonPtr, 1> ErrorReports;
+
+public:
+  explicit RejectLog(Region *R) : R(R) {}
+
+  typedef llvm::SmallVector<RejectReasonPtr, 1>::const_iterator iterator;
+
+  iterator begin() const { return ErrorReports.begin(); }
+  iterator end() const { return ErrorReports.end(); }
+  size_t size() const { return ErrorReports.size(); }
+  bool hasErrors() const { return size() > 0; }
+
+  const Region *region() const { return R; }
+  void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); }
+};
+
+/// @brief Store reject logs
+class RejectLogsContainer {
+  std::map<const Region *, RejectLog> Logs;
+
+public:
+  typedef std::map<const Region *, RejectLog>::iterator iterator;
+  typedef std::map<const Region *, RejectLog>::const_iterator const_iterator;
+
+  iterator begin() { return Logs.begin(); }
+  iterator end() { return Logs.end(); }
+
+  const_iterator begin() const { return Logs.begin(); }
+  const_iterator end() const { return Logs.end(); }
+
+  void insert(std::pair<const Region *, RejectLog> New) {
+    auto Result = Logs.insert(New);
+    assert(Result.second && "Tried to replace an element in the log!");
+  }
+
+  std::map<const Region *, RejectLog>::mapped_type at(const Region *R) {
+    return Logs.at(R);
+  }
+
+  void clear() { Logs.clear(); }
+
+  size_t count(const Region *R) const { return Logs.count(R); }
+
+  size_t size(const Region *R) const {
+    if (!Logs.count(R))
+      return 0;
+    return Logs.at(R).size();
+  }
+
+  bool hasErrors(const Region *R) const {
+    return (Logs.count(R) && Logs.at(R).size() > 0);
+  }
+
+  bool hasErrors(Region *R) const { return hasErrors((const Region *)R); }
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Base class for CFG related reject reasons.
+///
+/// Scop candidates that violate structural restrictions can be grouped under
+/// this reject reason class.
+class ReportCFG : public RejectReason {
+  //===--------------------------------------------------------------------===//
+public:
+  ReportCFG(const RejectReasonKind K);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a non-branch terminator within a Scop candidate.
+class ReportNonBranchTerminator : public ReportCFG {
+  BasicBlock *BB;
+
+public:
+  ReportNonBranchTerminator(BasicBlock *BB)
+      : ReportCFG(rrkNonBranchTerminator), BB(BB) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a not well-structured condition within the CFG.
+class ReportCondition : public ReportCFG {
+  //===--------------------------------------------------------------------===//
+
+  // The BasicBlock we found the broken condition in.
+  BasicBlock *BB;
+
+public:
+  ReportCondition(BasicBlock *BB) : ReportCFG(rrkCondition), BB(BB) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Base class for non-affine reject reasons.
+///
+/// Scop candidates that violate restrictions to affinity are reported under
+/// this class.
+class ReportAffFunc : public RejectReason {
+  //===--------------------------------------------------------------------===//
+
+  // The instruction that caused non-affinity to occur.
+  const Instruction *Inst;
+
+public:
+  ReportAffFunc(const RejectReasonKind K, const Instruction *Inst);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual const DebugLoc &getDebugLoc() const override {
+    return Inst->getDebugLoc();
+  };
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a condition that is based on an 'undef' value.
+class ReportUndefCond : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+
+  // The BasicBlock we found the broken condition in.
+  BasicBlock *BB;
+
+public:
+  ReportUndefCond(const Instruction *Inst, BasicBlock *BB)
+      : ReportAffFunc(rrkUndefCond, Inst), BB(BB) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures an invalid condition
+///
+/// Conditions have to be either constants or icmp instructions.
+class ReportInvalidCond : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+
+  // The BasicBlock we found the broken condition in.
+  BasicBlock *BB;
+
+public:
+  ReportInvalidCond(const Instruction *Inst, BasicBlock *BB)
+      : ReportAffFunc(rrkInvalidCond, Inst), BB(BB) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures an undefined operand.
+class ReportUndefOperand : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+
+  // The BasicBlock we found the undefined operand in.
+  BasicBlock *BB;
+
+public:
+  ReportUndefOperand(BasicBlock *BB, const Instruction *Inst)
+      : ReportAffFunc(rrkUndefOperand, Inst), BB(BB) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a non-affine branch.
+class ReportNonAffBranch : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+
+  // The BasicBlock we found the non-affine branch in.
+  BasicBlock *BB;
+
+  /// @brief LHS & RHS of the failed condition.
+  //@{
+  const SCEV *LHS;
+  const SCEV *RHS;
+  //@}
+
+public:
+  ReportNonAffBranch(BasicBlock *BB, const SCEV *LHS, const SCEV *RHS,
+                     const Instruction *Inst)
+      : ReportAffFunc(rrkNonAffBranch, Inst), BB(BB), LHS(LHS), RHS(RHS) {}
+
+  const SCEV *lhs() { return LHS; }
+  const SCEV *rhs() { return RHS; }
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a missing base pointer.
+class ReportNoBasePtr : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+public:
+  ReportNoBasePtr(const Instruction *Inst)
+      : ReportAffFunc(rrkNoBasePtr, Inst) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures an undefined base pointer.
+class ReportUndefBasePtr : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+public:
+  ReportUndefBasePtr(const Instruction *Inst)
+      : ReportAffFunc(rrkUndefBasePtr, Inst) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a base pointer that is not invariant in the region.
+class ReportVariantBasePtr : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+
+  // The variant base pointer.
+  Value *BaseValue;
+
+public:
+  ReportVariantBasePtr(Value *BaseValue, const Instruction *Inst)
+      : ReportAffFunc(rrkVariantBasePtr, Inst), BaseValue(BaseValue) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual std::string getEndUserMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a non-affine access function.
+class ReportNonAffineAccess : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+
+  // The non-affine access function.
+  const SCEV *AccessFunction;
+
+public:
+  ReportNonAffineAccess(const SCEV *AccessFunction, const Instruction *Inst)
+      : ReportAffFunc(rrkNonAffineAccess, Inst),
+        AccessFunction(AccessFunction) {}
+
+  const SCEV *get() { return AccessFunction; }
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Base class for reject reasons related to induction variables.
+///
+//  ReportIndVar reject reasons are generated when the ScopDetection finds
+/// errors in the induction variable(s) of the Scop candidate.
+class ReportIndVar : public RejectReason {
+  //===--------------------------------------------------------------------===//
+public:
+  ReportIndVar(const RejectReasonKind K);
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a phi node that refers to SSA names in the current region.
+class ReportPhiNodeRefInRegion : public ReportIndVar {
+  //===--------------------------------------------------------------------===//
+
+  // The offending instruction.
+  Instruction *Inst;
+
+public:
+  ReportPhiNodeRefInRegion(Instruction *Inst);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a non canonical phi node.
+class ReportNonCanonicalPhiNode : public ReportIndVar {
+  //===--------------------------------------------------------------------===//
+
+  // The offending instruction.
+  Instruction *Inst;
+
+public:
+  ReportNonCanonicalPhiNode(Instruction *Inst);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a non canonical induction variable in the loop header.
+class ReportLoopHeader : public ReportIndVar {
+  //===--------------------------------------------------------------------===//
+
+  // The offending loop.
+  Loop *L;
+
+public:
+  ReportLoopHeader(Loop *L);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures a region with invalid entering edges.
+class ReportIndEdge : public RejectReason {
+  //===--------------------------------------------------------------------===//
+
+  BasicBlock *BB;
+
+public:
+  ReportIndEdge(BasicBlock *BB);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with non affine loop bounds.
+class ReportLoopBound : public RejectReason {
+  //===--------------------------------------------------------------------===//
+
+  // The offending loop.
+  Loop *L;
+
+  // The non-affine loop bound.
+  const SCEV *LoopCount;
+
+public:
+  ReportLoopBound(Loop *L, const SCEV *LoopCount);
+
+  const SCEV *loopCount() { return LoopCount; }
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with non-side-effect-known function calls.
+class ReportFuncCall : public RejectReason {
+  //===--------------------------------------------------------------------===//
+
+  // The offending call instruction.
+  Instruction *Inst;
+
+public:
+  ReportFuncCall(Instruction *Inst);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  virtual std::string getEndUserMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with aliasing.
+class ReportAlias : public RejectReason {
+  //===--------------------------------------------------------------------===//
+
+  /// @brief Format an invalid alias set.
+  ///
+  /// @param AS The invalid alias set to format.
+  std::string formatInvalidAlias(AliasSet &AS) const;
+
+  Instruction *Inst;
+  AliasSet &AS;
+
+public:
+  ReportAlias(Instruction *Inst, AliasSet &AS);
+
+  AliasSet &getAliasSet() { return AS; }
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with non simplified loops.
+class ReportSimpleLoop : public RejectReason {
+  //===--------------------------------------------------------------------===//
+public:
+  ReportSimpleLoop();
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Base class for otherwise ungrouped reject reasons.
+class ReportOther : public RejectReason {
+  //===--------------------------------------------------------------------===//
+public:
+  ReportOther(const RejectReasonKind K);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with bad IntToPtr instructions.
+class ReportIntToPtr : public ReportOther {
+  //===--------------------------------------------------------------------===//
+
+  // The offending base value.
+  Instruction *BaseValue;
+
+public:
+  ReportIntToPtr(Instruction *BaseValue);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with alloca instructions.
+class ReportAlloca : public ReportOther {
+  //===--------------------------------------------------------------------===//
+  Instruction *Inst;
+
+public:
+  ReportAlloca(Instruction *Inst);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with unknown instructions.
+class ReportUnknownInst : public ReportOther {
+  //===--------------------------------------------------------------------===//
+  Instruction *Inst;
+
+public:
+  ReportUnknownInst(Instruction *Inst);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with phi nodes in exit BBs.
+class ReportPHIinExit : public ReportOther {
+  //===--------------------------------------------------------------------===//
+  Instruction *Inst;
+
+public:
+  ReportPHIinExit(Instruction *Inst);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
+/// @brief Captures errors with regions containing the function entry block.
+class ReportEntry : public ReportOther {
+  //===--------------------------------------------------------------------===//
+  BasicBlock *BB;
+
+public:
+  ReportEntry(BasicBlock *BB);
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual const DebugLoc &getDebugLoc() const override;
+  //@}
+};
+
+} // namespace polly
+
+#endif // POLLY_SCOP_DETECTION_DIAGNOSTIC_H
diff --git a/rc1/include/polly/ScopInfo.h b/rc1/include/polly/ScopInfo.h
new file mode 100644
index 0000000..6ce4a0f
--- /dev/null
+++ b/rc1/include/polly/ScopInfo.h
@@ -0,0 +1,786 @@
+//===------ 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 representation is shared among several tools in the polyhedral
+// community, which are e.g. CLooG, Pluto, Loopo, Graphite.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCOP_INFO_H
+#define POLLY_SCOP_INFO_H
+
+#include "polly/ScopDetection.h"
+
+#include "llvm/Analysis/RegionPass.h"
+
+#include "isl/ctx.h"
+
+using namespace llvm;
+
+namespace llvm {
+class Loop;
+class LoopInfo;
+class PHINode;
+class ScalarEvolution;
+class SCEV;
+class SCEVAddRecExpr;
+class Type;
+}
+
+struct isl_ctx;
+struct isl_map;
+struct isl_basic_map;
+struct isl_id;
+struct isl_set;
+struct isl_union_set;
+struct isl_union_map;
+struct isl_space;
+struct isl_constraint;
+
+namespace polly {
+
+class IRAccess;
+class Scop;
+class ScopStmt;
+class ScopInfo;
+class TempScop;
+class SCEVAffFunc;
+class Comparison;
+
+//===----------------------------------------------------------------------===//
+/// @brief Represent memory accesses in statements.
+class MemoryAccess {
+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 must-write access
+  ///
+  /// A certain set of memory locations 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 locations 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, MUST_WRITE, MAY_WRITE };
+
+  /// @brief Reduction access type
+  ///
+  /// Commutative and associative binary operations suitable for reductions
+  enum ReductionType {
+    RT_NONE, ///< Indicate no reduction at all
+    RT_ADD,  ///< Addition
+    RT_MUL,  ///< Multiplication
+    RT_BOR,  ///< Bitwise Or
+    RT_BXOR, ///< Bitwise XOr
+    RT_BAND, ///< Bitwise And
+  };
+
+private:
+  MemoryAccess(const MemoryAccess &) LLVM_DELETED_FUNCTION;
+  const MemoryAccess &operator=(const MemoryAccess &) LLVM_DELETED_FUNCTION;
+
+  isl_map *AccessRelation;
+  enum AccessType Type;
+
+  const Value *BaseAddr;
+  std::string BaseName;
+  isl_basic_map *createBasicAccessMap(ScopStmt *Statement);
+  void setBaseName();
+  ScopStmt *Statement;
+
+  /// @brief Reduction type for reduction like accesses, RT_NONE otherwise
+  ///
+  /// An access is reduction like if it is part of a load-store chain in which
+  /// both access the same memory location (use the same LLVM-IR value
+  /// as pointer reference). Furthermore, between the load and the store there
+  /// is exactly one binary operator which is known to be associative and
+  /// commutative.
+  ///
+  /// TODO:
+  ///
+  /// We can later lift the constraint that the same LLVM-IR value defines the
+  /// memory location to handle scops such as the following:
+  ///
+  ///    for i
+  ///      for j
+  ///        sum[i+j] = sum[i] + 3;
+  ///
+  /// Here not all iterations access the same memory location, but iterations
+  /// for which j = 0 holds do. After lifing the equality check in ScopInfo,
+  /// subsequent transformations do not only need check if a statement is
+  /// reduction like, but they also need to verify that that the reduction
+  /// property is only exploited for statement instances that load from and
+  /// store to the same data location. Doing so at dependence analysis time
+  /// could allow us to handle the above example.
+  ReductionType RedType = RT_NONE;
+
+  const Instruction *Inst;
+
+  /// Updated access relation read from JSCOP file.
+  isl_map *newAccessRelation;
+
+  void assumeNoOutOfBound(const IRAccess &Access);
+
+public:
+  // @brief Create a memory access from an access in LLVM-IR.
+  //
+  // @param Access     The memory access.
+  // @param Statement  The statement that contains the access.
+  // @param SE         The ScalarEvolution analysis.
+  MemoryAccess(const IRAccess &Access, const Instruction *AccInst,
+               ScopStmt *Statement);
+
+  // @brief Create a memory access that reads a complete memory object.
+  //
+  // @param BaseAddress The base address of the memory object.
+  // @param Statement   The statement that contains this access.
+  MemoryAccess(const Value *BaseAddress, ScopStmt *Statement);
+
+  ~MemoryAccess();
+
+  /// @brief Get the type of a memory access.
+  enum AccessType getType() { return Type; }
+
+  /// @brief Is this a reduction like access?
+  bool isReductionLike() const { return RedType != RT_NONE; }
+
+  /// @brief Is this a read memory access?
+  bool isRead() const { return Type == MemoryAccess::READ; }
+
+  /// @brief Is this a must-write memory access?
+  bool isMustWrite() const { return Type == MemoryAccess::MUST_WRITE; }
+
+  /// @brief Is this a may-write memory access?
+  bool isMayWrite() const { return Type == MemoryAccess::MAY_WRITE; }
+
+  /// @brief Is this a write memory access?
+  bool isWrite() const { return isMustWrite() || isMayWrite(); }
+
+  isl_map *getAccessRelation() const;
+
+  /// @brief Return the space in which the access relation lives in.
+  __isl_give isl_space *getAccessRelationSpace() const;
+
+  /// @brief Get an isl string representing this access function.
+  std::string getAccessRelationStr() const;
+
+  const Value *getBaseAddr() const { return BaseAddr; }
+
+  const std::string &getBaseName() const { return BaseName; }
+
+  const Instruction *getAccessInstruction() const { return Inst; }
+
+  /// @brief Get the new access function imported from JSCOP file
+  isl_map *getNewAccessRelation() const;
+
+  /// Get the stride of this memory access in the specified Schedule. Schedule
+  /// is a map from the statement to a schedule where the innermost dimension is
+  /// the dimension of the innermost loop containing the statement.
+  isl_set *getStride(__isl_take const isl_map *Schedule) const;
+
+  /// Is the stride of the access equal to a certain width? Schedule is a map
+  /// from the statement to a schedule where the innermost dimension is the
+  /// dimension of the innermost loop containing the statement.
+  bool isStrideX(__isl_take const isl_map *Schedule, int StrideWidth) const;
+
+  /// Is consecutive memory accessed for a given statement instance set?
+  /// Schedule is a map from the statement to a schedule where the innermost
+  /// dimension is the dimension of the innermost loop containing the
+  /// statement.
+  bool isStrideOne(__isl_take const isl_map *Schedule) const;
+
+  /// Is always the same memory accessed for a given statement instance set?
+  /// Schedule is a map from the statement to a schedule where the innermost
+  /// dimension is the dimension of the innermost loop containing the
+  /// statement.
+  bool isStrideZero(__isl_take const isl_map *Schedule) const;
+
+  /// @brief Check if this is a scalar memory access.
+  bool isScalar() const;
+
+  /// @brief Get the statement that contains this memory access.
+  ScopStmt *getStatement() const { return Statement; }
+
+  /// @brief Get the reduction type of this access
+  ReductionType getReductionType() const { return RedType; }
+
+  /// @brief Set the updated access relation read from JSCOP file.
+  void setNewAccessRelation(isl_map *newAccessRelation);
+
+  /// @brief Mark this a reduction like access
+  void markAsReductionLike(ReductionType RT) { RedType = RT; }
+
+  /// @brief Align the parameters in the access relation to the scop context
+  void realignParams();
+
+  /// @brief Print the MemoryAccess.
+  ///
+  /// @param OS The output stream the MemoryAccess is printed to.
+  void print(raw_ostream &OS) const;
+
+  /// @brief Print the MemoryAccess to stderr.
+  void dump() const;
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              MemoryAccess::ReductionType RT);
+
+//===----------------------------------------------------------------------===//
+/// @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 {
+  //===-------------------------------------------------------------------===//
+  ScopStmt(const ScopStmt &) LLVM_DELETED_FUNCTION;
+  const ScopStmt &operator=(const ScopStmt &) LLVM_DELETED_FUNCTION;
+
+  /// 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 statement and iteration vector (S, (5,3)) is called statement
+  /// 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 The loop induction variables surrounding the statement.
+  ///
+  /// This information is only needed for final code generation.
+  std::vector<PHINode *> IVS;
+  std::vector<Loop *> NestLoops;
+
+  std::string BaseName;
+
+  /// Build the statement.
+  //@{
+  __isl_give isl_set *buildConditionSet(const Comparison &Cmp);
+  __isl_give isl_set *addConditionsToDomain(__isl_take isl_set *Domain,
+                                            TempScop &tempScop,
+                                            const Region &CurRegion);
+  __isl_give isl_set *addLoopBoundsToDomain(__isl_take isl_set *Domain,
+                                            TempScop &tempScop);
+  __isl_give isl_set *buildDomain(TempScop &tempScop, const Region &CurRegion);
+  void buildScattering(SmallVectorImpl<unsigned> &Scatter);
+  void buildAccesses(TempScop &tempScop, const Region &CurRegion);
+
+  /// @brief Detect and mark reductions in the ScopStmt
+  void checkForReductions();
+
+  /// @brief Collect loads which might form a reduction chain with @p StoreMA
+  void
+  collectCandiateReductionLoads(MemoryAccess *StoreMA,
+                                llvm::SmallVectorImpl<MemoryAccess *> &Loads);
+  //@}
+
+  /// Create the ScopStmt from a BasicBlock.
+  ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
+           BasicBlock &bb, SmallVectorImpl<Loop *> &NestLoops,
+           SmallVectorImpl<unsigned> &Scatter);
+
+  friend class Scop;
+
+public:
+  ~ScopStmt();
+
+  /// @brief Get an isl_ctx pointer.
+  isl_ctx *getIslCtx() const;
+
+  /// @brief Get the iteration domain of this ScopStmt.
+  ///
+  /// @return The iteration domain of this ScopStmt.
+  __isl_give isl_set *getDomain() const;
+
+  /// @brief Get the space of the iteration domain
+  ///
+  /// @return The space of the iteration domain
+  __isl_give isl_space *getDomainSpace() const;
+
+  /// @brief Get the id of the iteration domain space
+  ///
+  /// @return The id of the iteration domain space
+  isl_id *getDomainId() const;
+
+  /// @brief Get an isl string representing this domain.
+  std::string getDomainStr() const;
+
+  /// @brief Get the scattering function of this ScopStmt.
+  ///
+  /// @return The scattering function of this ScopStmt.
+  __isl_give isl_map *getScattering() const;
+  void setScattering(isl_map *scattering);
+
+  /// @brief Get an isl string representing this scattering.
+  std::string getScatteringStr() const;
+
+  /// @brief Get the BasicBlock represented by this ScopStmt.
+  ///
+  /// @return The BasicBlock represented by this ScopStmt.
+  BasicBlock *getBasicBlock() const { return BB; }
+
+  const MemoryAccess &getAccessFor(const Instruction *Inst) const {
+    MemoryAccess *A = lookupAccessFor(Inst);
+    assert(A && "Cannot get memory access because it does not exist!");
+    return *A;
+  }
+
+  MemoryAccess *lookupAccessFor(const Instruction *Inst) const {
+    std::map<const Instruction *, MemoryAccess *>::const_iterator at =
+        InstructionToAccess.find(Inst);
+    return at == InstructionToAccess.end() ? NULL : at->second;
+  }
+
+  void setBasicBlock(BasicBlock *Block) { BB = Block; }
+
+  typedef MemoryAccessVec::iterator iterator;
+  typedef MemoryAccessVec::const_iterator const_iterator;
+
+  iterator begin() { return MemAccs.begin(); }
+  iterator end() { return MemAccs.end(); }
+  const_iterator begin() const { return MemAccs.begin(); }
+  const_iterator end() const { 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 Restrict the domain of the statement.
+  ///
+  /// @param NewDomain The new statement domain.
+  void restrictDomain(__isl_take isl_set *NewDomain);
+
+  /// @brief Get the loop for a dimension.
+  ///
+  /// @param Dimension The dimension of the induction variable
+  /// @return The loop at a certain dimension.
+  const Loop *getLoopForDimension(unsigned Dimension) const;
+
+  /// @brief Align the parameters in the statement to the scop context
+  void realignParams();
+
+  /// @brief Print the ScopStmt.
+  ///
+  /// @param OS The output stream the ScopStmt is printed to.
+  void print(raw_ostream &OS) const;
+
+  /// @brief Print the ScopStmt to stderr.
+  void dump() const;
+};
+
+/// @brief Print ScopStmt S to raw_ostream O.
+static inline raw_ostream &operator<<(raw_ostream &O, const ScopStmt &S) {
+  S.print(O);
+  return O;
+}
+
+//===----------------------------------------------------------------------===//
+/// @brief Static Control Part
+///
+/// A Scop is the polyhedral representation of a control flow region detected
+/// by the Scop detection. It is generated by translating the LLVM-IR and
+/// abstracting its effects.
+///
+/// A Scop consists of a set of:
+///
+///   * A set of statements executed in the Scop.
+///
+///   * A set of global parameters
+///   Those parameters are scalar integer values, which are constant during
+///   execution.
+///
+///   * A context
+///   This context contains information about the values the parameters
+///   can take and relations between different parameters.
+class Scop {
+  //===-------------------------------------------------------------------===//
+  Scop(const Scop &) LLVM_DELETED_FUNCTION;
+  const Scop &operator=(const Scop &) LLVM_DELETED_FUNCTION;
+
+  ScalarEvolution *SE;
+
+  /// The underlying Region.
+  Region &R;
+
+  /// Max loop depth.
+  unsigned MaxLoopDepth;
+
+  typedef std::vector<ScopStmt *> StmtSet;
+  /// The statements in this Scop.
+  StmtSet Stmts;
+
+  /// Parameters of this Scop
+  typedef SmallVector<const SCEV *, 8> ParamVecType;
+  ParamVecType Parameters;
+
+  /// The isl_ids that are used to represent the parameters
+  typedef std::map<const SCEV *, int> ParamIdType;
+  ParamIdType ParameterIds;
+
+  /// Isl context.
+  isl_ctx *IslCtx;
+
+  /// Constraints on parameters.
+  isl_set *Context;
+
+  /// @brief The assumptions under which this scop was built.
+  ///
+  /// When constructing a scop sometimes the exact representation of a statement
+  /// or condition would be very complex, but there is a common case which is a
+  /// lot simpler, but which is only valid under certain assumptions. The
+  /// assumed context records the assumptions taken during the construction of
+  /// this scop and that need to be code generated as a run-time test.
+  isl_set *AssumedContext;
+
+  /// Create the static control part with a region, max loop depth of this
+  /// region and parameters used in this region.
+  Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, isl_ctx *ctx);
+
+  /// @brief Check if a basic block is trivial.
+  ///
+  /// A trivial basic block does not contain any useful calculation. Therefore,
+  /// it does not need to be represented as a polyhedral statement.
+  ///
+  /// @param BB The basic block to check
+  /// @param tempScop TempScop returning further information regarding the Scop.
+  ///
+  /// @return True if the basic block is trivial, otherwise false.
+  static bool isTrivialBB(BasicBlock *BB, TempScop &tempScop);
+
+  /// @brief Build the Context of the Scop.
+  void buildContext();
+
+  /// @brief Add the bounds of the parameters to the context.
+  void addParameterBounds();
+
+  /// @brief Simplify the assumed context.
+  void simplifyAssumedContext();
+
+  /// Build the Scop and Statement with precalculated 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; }
+
+  /// @brief Take a list of parameters and add the new ones to the scop.
+  void addParams(std::vector<const SCEV *> NewParameters);
+
+  /// @brief Return the isl_id that represents a certain parameter.
+  ///
+  /// @param Parameter A SCEV that was recognized as a Parameter.
+  ///
+  /// @return The corresponding isl_id or NULL otherwise.
+  isl_id *getIdForParam(const SCEV *Parameter) const;
+
+  /// @name Parameter Iterators
+  ///
+  /// These iterators iterate over all parameters of this Scop.
+  //@{
+  typedef ParamVecType::iterator param_iterator;
+  typedef ParamVecType::const_iterator const_param_iterator;
+
+  param_iterator param_begin() { return Parameters.begin(); }
+  param_iterator param_end() { return Parameters.end(); }
+  const_param_iterator param_begin() const { return Parameters.begin(); }
+  const_param_iterator param_end() const { return Parameters.end(); }
+  //@}
+
+  /// @brief Get the maximum region of this static control part.
+  ///
+  /// @return The maximum region of this static control part.
+  inline const Region &getRegion() const { return R; }
+  inline Region &getRegion() { return R; }
+
+  /// @brief Get the maximum depth of the loop.
+  ///
+  /// @return The maximum depth of the loop.
+  inline unsigned getMaxLoopDepth() const { return MaxLoopDepth; }
+
+  /// @brief Get the scattering dimension number of this Scop.
+  ///
+  /// @return The scattering dimension number of this Scop.
+  inline unsigned getScatterDim() const {
+    unsigned maxScatterDim = 0;
+
+    for (const_iterator SI = begin(), SE = end(); SI != SE; ++SI)
+      maxScatterDim = std::max(maxScatterDim, (*SI)->getNumScattering());
+
+    return maxScatterDim;
+  }
+
+  /// @brief Get the name of this Scop.
+  std::string getNameStr() const;
+
+  /// @brief Get the constraint on parameter of this Scop.
+  ///
+  /// @return The constraint on parameter of this Scop.
+  __isl_give isl_set *getContext() const;
+  __isl_give isl_space *getParamSpace() const;
+
+  /// @brief Get the assumed context for this Scop.
+  ///
+  /// @return The assumed context of this Scop.
+  __isl_give isl_set *getAssumedContext() const;
+
+  /// @brief Add assumptions to assumed context.
+  ///
+  /// The assumptions added will be assumed to hold during the execution of the
+  /// scop. However, as they are generally not statically provable, at code
+  /// generation time run-time checks will be generated that ensure the
+  /// assumptions hold.
+  ///
+  /// WARNING: We currently exploit in simplifyAssumedContext the knowledge
+  ///          that assumptions do not change the set of statement instances
+  ///          executed.
+  ///
+  /// @param Set A set describing relations between parameters that are assumed
+  ///            to hold.
+  void addAssumption(__isl_take isl_set *Set);
+
+  /// @brief Get an isl string representing the context.
+  std::string getContextStr() const;
+
+  /// @brief Get an isl string representing the assumed context.
+  std::string getAssumedContextStr() const;
+
+  /// @name Statements Iterators
+  ///
+  /// These iterators iterate over all statements of this Scop.
+  //@{
+  typedef StmtSet::iterator iterator;
+  typedef StmtSet::const_iterator const_iterator;
+
+  iterator begin() { return Stmts.begin(); }
+  iterator end() { return Stmts.end(); }
+  const_iterator begin() const { return Stmts.begin(); }
+  const_iterator end() const { return Stmts.end(); }
+
+  typedef StmtSet::reverse_iterator reverse_iterator;
+  typedef StmtSet::const_reverse_iterator const_reverse_iterator;
+
+  reverse_iterator rbegin() { return Stmts.rbegin(); }
+  reverse_iterator rend() { return Stmts.rend(); }
+  const_reverse_iterator rbegin() const { return Stmts.rbegin(); }
+  const_reverse_iterator rend() const { return Stmts.rend(); }
+  //@}
+
+  void setContext(isl_set *NewContext);
+
+  /// @brief Align the parameters in the statement to the scop context
+  void realignParams();
+
+  /// @brief Print the static control part.
+  ///
+  /// @param OS The output stream the static control part is printed to.
+  void print(raw_ostream &OS) const;
+
+  /// @brief Print the ScopStmt to stderr.
+  void dump() const;
+
+  /// @brief Get the isl context of this static control part.
+  ///
+  /// @return The isl context of this static control part.
+  isl_ctx *getIslCtx() const;
+
+  /// @brief Get a union set containing the iteration domains of all statements.
+  __isl_give isl_union_set *getDomains();
+
+  /// @brief Get a union map of all may-writes performed in the SCoP.
+  __isl_give isl_union_map *getMayWrites();
+
+  /// @brief Get a union map of all must-writes performed in the SCoP.
+  __isl_give isl_union_map *getMustWrites();
+
+  /// @brief Get a union map of all writes performed in the SCoP.
+  __isl_give isl_union_map *getWrites();
+
+  /// @brief Get a union map of all reads performed in the SCoP.
+  __isl_give isl_union_map *getReads();
+
+  /// @brief Get the schedule of all the statements in the SCoP.
+  __isl_give isl_union_map *getSchedule();
+
+  /// @brief Intersects the domains of all statements in the SCoP.
+  ///
+  /// @return true if a change was made
+  bool restrictDomains(__isl_take isl_union_set *Domain);
+};
+
+/// @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 {
+  //===-------------------------------------------------------------------===//
+  ScopInfo(const ScopInfo &) LLVM_DELETED_FUNCTION;
+  const ScopInfo &operator=(const ScopInfo &) LLVM_DELETED_FUNCTION;
+
+  // The Scop
+  Scop *scop;
+  isl_ctx *ctx;
+
+  void clear() {
+    if (scop) {
+      delete scop;
+      scop = 0;
+    }
+  }
+
+public:
+  static char ID;
+  explicit ScopInfo();
+  ~ScopInfo();
+
+  /// @brief Try to build the Polly IR of static control part on the current
+  ///        SESE-Region.
+  ///
+  /// @return If the current region is a valid for a static control part,
+  ///         return the Polly IR representing this static control part,
+  ///         return null otherwise.
+  Scop *getScop() { return scop; }
+  const Scop *getScop() const { return scop; }
+
+  /// @name RegionPass interface
+  //@{
+  virtual bool runOnRegion(Region *R, RGPassManager &RGM);
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void releaseMemory() { clear(); }
+  virtual void print(raw_ostream &OS, const Module *) const {
+    if (scop)
+      scop->print(OS);
+    else
+      OS << "Invalid Scop!\n";
+  }
+  //@}
+};
+
+} // end namespace polly
+
+namespace llvm {
+class PassRegistry;
+void initializeScopInfoPass(llvm::PassRegistry &);
+}
+
+#endif
diff --git a/rc1/include/polly/ScopLib.h b/rc1/include/polly/ScopLib.h
new file mode 100644
index 0000000..6a3fd6f
--- /dev/null
+++ b/rc1/include/polly/ScopLib.h
@@ -0,0 +1,70 @@
+//===- 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
+
+#include "isl/ctx.h"
+
+#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_take isl_set *set);
+  static int scatteringToMatrix_constraint(isl_constraint *c, void *user);
+  static int scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user);
+  scoplib_matrix_p scatteringToMatrix(__isl_take isl_map *map);
+
+public:
+  ScopLib(Scop *S);
+  ScopLib(Scop *S, FILE *F, Dependences *D);
+  ~ScopLib();
+  void print(FILE *F);
+  bool updateScattering();
+};
+}
+
+#endif /* POLLY_SCOPLIB_H */
diff --git a/rc1/include/polly/ScopPass.h b/rc1/include/polly/ScopPass.h
new file mode 100755
index 0000000..3d5373a
--- /dev/null
+++ b/rc1/include/polly/ScopPass.h
@@ -0,0 +1,63 @@
+//===--------- 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:
+  Scop &getCurScop() const {
+    assert(S && "Not on a Scop!");
+    return *S;
+  }
+
+private:
+  virtual bool runOnRegion(Region *R, RGPassManager &RGM);
+  void print(raw_ostream &OS, const Module *) const;
+  virtual void printScop(raw_ostream &OS) const {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/rc1/include/polly/Support/GICHelper.h b/rc1/include/polly/Support/GICHelper.h
new file mode 100755
index 0000000..4c4d5e2
--- /dev/null
+++ b/rc1/include/polly/Support/GICHelper.h
@@ -0,0 +1,63 @@
+//===- Support/GICHelper.h -- Helper functions for ISL --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Helper functions for isl objects.
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef POLLY_SUPPORT_GIC_HELPER_H
+#define POLLY_SUPPORT_GIC_HELPER_H
+
+#include "llvm/ADT/APInt.h"
+#include "isl/ctx.h"
+#include "llvm/Support/raw_ostream.h"
+
+struct isl_map;
+struct isl_union_map;
+struct isl_set;
+struct isl_union_set;
+struct isl_schedule;
+struct isl_multi_aff;
+struct isl_pw_multi_aff;
+struct isl_aff;
+struct isl_pw_aff;
+struct isl_val;
+
+namespace polly {
+__isl_give isl_val *isl_valFromAPInt(isl_ctx *Ctx, const llvm::APInt Int,
+                                     bool IsSigned);
+llvm::APInt APIntFromVal(__isl_take isl_val *Val);
+
+/// @brief Get c++ string from Isl objects.
+//@{
+std::string stringFromIslObj(__isl_keep isl_map *map);
+std::string stringFromIslObj(__isl_keep isl_union_map *umap);
+std::string stringFromIslObj(__isl_keep isl_set *set);
+std::string stringFromIslObj(__isl_keep isl_union_set *uset);
+std::string stringFromIslObj(__isl_keep isl_schedule *schedule);
+std::string stringFromIslObj(__isl_keep isl_multi_aff *maff);
+std::string stringFromIslObj(__isl_keep isl_pw_multi_aff *pma);
+std::string stringFromIslObj(__isl_keep isl_aff *aff);
+std::string stringFromIslObj(__isl_keep isl_pw_aff *pwaff);
+//@}
+
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     __isl_keep isl_union_map *Map) {
+  OS << polly::stringFromIslObj(Map);
+  return OS;
+}
+
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                                     __isl_keep isl_map *Map) {
+  OS << polly::stringFromIslObj(Map);
+  return OS;
+}
+} // end namespace polly
+
+#endif
diff --git a/rc1/include/polly/Support/SCEVValidator.h b/rc1/include/polly/Support/SCEVValidator.h
new file mode 100755
index 0000000..e787d35
--- /dev/null
+++ b/rc1/include/polly/Support/SCEVValidator.h
@@ -0,0 +1,40 @@
+//===--- SCEVValidator.h - Detect Scops -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Checks if a SCEV expression represents a valid affine expression.
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCEV_VALIDATOR_H
+#define POLLY_SCEV_VALIDATOR_H
+
+#include <vector>
+
+namespace llvm {
+class Region;
+class SCEV;
+class ScalarEvolution;
+class Value;
+}
+
+namespace polly {
+/// Returns true when the SCEV contains references to instructions within the
+/// region.
+///
+/// @param S The SCEV to analyze.
+/// @param R The region in which we look for dependences.
+bool hasScalarDepsInsideRegion(const llvm::SCEV *S, const llvm::Region *R);
+bool isAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
+                  llvm::ScalarEvolution &SE,
+                  const llvm::Value *BaseAddress = 0);
+std::vector<const llvm::SCEV *>
+getParamsInAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
+                      llvm::ScalarEvolution &SE,
+                      const llvm::Value *BaseAddress = 0);
+}
+
+#endif
diff --git a/rc1/include/polly/Support/ScopHelper.h b/rc1/include/polly/Support/ScopHelper.h
new file mode 100755
index 0000000..4f275b2
--- /dev/null
+++ b/rc1/include/polly/Support/ScopHelper.h
@@ -0,0 +1,71 @@
+//===------ 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 {
+class 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);
+
+/// @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);
+llvm::BasicBlock *createSingleExitEdge(llvm::Region *R, llvm::Pass *P);
+
+/// @brief Simplify the region in a scop to have a single entry edge
+///        and a single exit edge.
+///
+/// @param S  The scop that is simplified.
+/// @param P  The pass that is currently running.
+///
+void simplifyRegion(polly::Scop *S, llvm::Pass *P);
+
+/// @brief Split the entry block of a function to store the newly inserted
+///        allocations outside of all Scops.
+///
+/// @param EntryBlock The entry block of the current function.
+/// @param P          The pass that currently running.
+///
+void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P);
+}
+#endif
diff --git a/rc1/include/polly/TempScopInfo.h b/rc1/include/polly/TempScopInfo.h
new file mode 100644
index 0000000..17fa751
--- /dev/null
+++ b/rc1/include/polly/TempScopInfo.h
@@ -0,0 +1,326 @@
+//===-------- 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/ScopDetection.h"
+
+#include "llvm/Analysis/RegionPass.h"
+#include "llvm/IR/Instructions.h"
+
+namespace llvm {
+class DataLayout;
+}
+
+using namespace llvm;
+
+namespace polly {
+
+extern bool PollyDelinearize;
+
+//===---------------------------------------------------------------------===//
+/// @brief A memory access described by a SCEV expression and the access type.
+class IRAccess {
+public:
+  const Value *BaseAddress;
+
+  const SCEV *Offset;
+
+  // The type of the scev affine function
+  enum TypeKind {
+    READ = 0x1,
+    WRITE = 0x2,
+  };
+
+private:
+  unsigned ElemBytes;
+  TypeKind Type;
+  bool IsAffine;
+
+public:
+  SmallVector<const SCEV *, 4> Subscripts, Sizes;
+
+  explicit IRAccess(TypeKind Type, const Value *BaseAddress, const SCEV *Offset,
+                    unsigned elemBytes, bool Affine,
+                    SmallVector<const SCEV *, 4> Subscripts,
+                    SmallVector<const SCEV *, 4> Sizes)
+      : BaseAddress(BaseAddress), Offset(Offset), ElemBytes(elemBytes),
+        Type(Type), IsAffine(Affine), Subscripts(Subscripts), Sizes(Sizes) {}
+
+  enum TypeKind getType() const { return Type; }
+
+  const Value *getBase() const { return BaseAddress; }
+
+  const SCEV *getOffset() const { return Offset; }
+
+  unsigned getElemSizeInBytes() const { return ElemBytes; }
+
+  bool isAffine() const { return IsAffine; }
+
+  bool isRead() const { return Type == READ; }
+
+  bool isWrite() const { return Type == WRITE; }
+
+  bool isScalar() const { return Subscripts.size() == 0; }
+
+  void print(raw_ostream &OS) const;
+};
+
+class Comparison {
+  const SCEV *LHS;
+  const SCEV *RHS;
+
+  ICmpInst::Predicate Pred;
+
+public:
+  Comparison(const SCEV *LHS, const SCEV *RHS, ICmpInst::Predicate Pred)
+      : LHS(LHS), RHS(RHS), Pred(Pred) {}
+
+  const SCEV *getLHS() const { return LHS; }
+  const SCEV *getRHS() const { return RHS; }
+
+  ICmpInst::Predicate getPred() const { return Pred; }
+  void print(raw_ostream &OS) const;
+};
+
+//===---------------------------------------------------------------------===//
+/// Types
+// The condition of a Basicblock, combine brcond with "And" operator.
+typedef SmallVector<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 *, const SCEV *> LoopBoundMapType;
+
+/// Mapping BBs to its condition constrains
+typedef std::map<const BasicBlock *, BBCond> BBCondMapType;
+
+typedef std::vector<std::pair<IRAccess, 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;
+
+  // 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;
+
+  friend class TempScopInfo;
+
+  explicit TempScop(Region &r, LoopBoundMapType &loopBounds,
+                    BBCondMapType &BBCmps, AccFuncMapType &accFuncMap)
+      : R(r), MaxLoopDepth(0), LoopBounds(loopBounds), BBConds(BBCmps),
+        AccFuncMap(accFuncMap) {}
+
+public:
+  ~TempScop();
+
+  /// @brief Get the maximum Region contained by this Scop.
+  ///
+  /// @return The maximum Region contained by this Scop.
+  Region &getMaxRegion() const { return R; }
+
+  /// @brief Get the maximum loop depth of Region R.
+  ///
+  /// @return The maximum loop depth of Region R.
+  unsigned getMaxLoopDepth() const { return MaxLoopDepth; }
+
+  /// @brief Get the loop bounds of the given loop.
+  ///
+  /// @param L The loop to get the bounds.
+  ///
+  /// @return The bounds of the loop L in { Lower bound, Upper bound } form.
+  ///
+  const SCEV *getLoopBound(const Loop *L) const {
+    LoopBoundMapType::const_iterator at = LoopBounds.find(L);
+    assert(at != LoopBounds.end() && "Bound for loop not available!");
+    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 {
+  //===-------------------------------------------------------------------===//
+  TempScopInfo(const TempScopInfo &) LLVM_DELETED_FUNCTION;
+  const TempScopInfo &operator=(const TempScopInfo &) LLVM_DELETED_FUNCTION;
+
+  // 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.
+  const DataLayout *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 statements (currently BasicBlocks) .
+  AccFuncMapType AccFuncMap;
+
+  // Pre-created zero for the scalar accesses, with it we do not need create a
+  // zero scev every time when we need it.
+  const SCEV *ZeroOffset;
+
+  // Mapping regions to the corresponding Scop in current function.
+  TempScopMapType TempScops;
+
+  // Clear the context.
+  void clear();
+
+  /// @brief Build condition constrains to BBs in a valid Scop.
+  ///
+  /// @param BB           The BasicBlock to build condition constrains
+  /// @param RegionEntry  The entry block of the Smallest Region that containing
+  ///                     BB
+  void buildCondition(BasicBlock *BB, BasicBlock *RegionEntry);
+
+  // Build the affine function of the given condition
+  void buildAffineCondition(Value &V, bool inverted, Comparison **Comp) 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);
+
+  /// @brief Build an instance of IRAccess from the Load/Store instruction.
+  ///
+  /// @param Inst The Load/Store instruction that access the memory
+  /// @param L    The parent loop of the instruction
+  /// @param R    The region on which we are going to build a TempScop
+  ///
+  /// @return     The IRAccess to describe the access function of the
+  ///             instruction.
+  IRAccess buildIRAccess(Instruction *Inst, Loop *L, Region *R);
+
+  /// @brief Analyze and extract the cross-BB scalar dependences (or,
+  ///        dataflow dependencies) of an instruction.
+  ///
+  /// @param Inst The instruction to be analyzed
+  /// @param R    The SCoP region
+  ///
+  /// @return     True if the Instruction is used in other BB and a scalar write
+  ///             Access is required.
+  bool buildScalarDependences(Instruction *Inst, Region *R);
+
+  void buildAccessFunctions(Region &RefRegion, BasicBlock &BB);
+
+  void buildLoopBounds(TempScop &Scop);
+
+public:
+  static char ID;
+  explicit TempScopInfo() : FunctionPass(ID) {}
+  ~TempScopInfo();
+
+  /// @brief Get the temporay Scop information in LLVM IR represent
+  ///        for Region R.
+  ///
+  /// @return The Scop information in LLVM IR represent.
+  TempScop *getTempScop(const Region *R) const;
+
+  /// @name FunctionPass interface
+  //@{
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void releaseMemory() { clear(); }
+  virtual bool runOnFunction(Function &F);
+  virtual void print(raw_ostream &OS, const Module *) const;
+  //@}
+};
+
+} // end namespace polly
+
+namespace llvm {
+class PassRegistry;
+void initializeTempScopInfoPass(llvm::PassRegistry &);
+}
+
+#endif
diff --git a/rc1/lib/Analysis/Dependences.cpp b/rc1/lib/Analysis/Dependences.cpp
new file mode 100644
index 0000000..2a6b16d
--- /dev/null
+++ b/rc1/lib/Analysis/Dependences.cpp
@@ -0,0 +1,585 @@
+//===- 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/Options.h"
+#include "polly/ScopInfo.h"
+#include "polly/Support/GICHelper.h"
+#include "llvm/Support/Debug.h"
+
+#include <isl/aff.h>
+#include <isl/ctx.h>
+#include <isl/flow.h>
+#include <isl/map.h>
+#include <isl/options.h>
+#include <isl/set.h>
+
+using namespace polly;
+using namespace llvm;
+
+#define DEBUG_TYPE "polly-dependence"
+
+static cl::opt<int> OptComputeOut(
+    "polly-dependences-computeout",
+    cl::desc("Bound the dependence analysis by a maximal amount of "
+             "computational steps"),
+    cl::Hidden, cl::init(250000), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> LegalityCheckDisabled(
+    "disable-polly-legality", cl::desc("Disable polly legality check"),
+    cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+enum AnalysisType { VALUE_BASED_ANALYSIS, MEMORY_BASED_ANALYSIS };
+
+static cl::opt<enum AnalysisType> OptAnalysisType(
+    "polly-dependences-analysis-type",
+    cl::desc("The kind of dependence analysis to use"),
+    cl::values(clEnumValN(VALUE_BASED_ANALYSIS, "value-based",
+                          "Exact dependences without transitive dependences"),
+               clEnumValN(MEMORY_BASED_ANALYSIS, "memory-based",
+                          "Overapproximation of dependences"),
+               clEnumValEnd),
+    cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::ZeroOrMore,
+    cl::cat(PollyCategory));
+
+//===----------------------------------------------------------------------===//
+Dependences::Dependences() : ScopPass(ID) { RAW = WAR = WAW = nullptr; }
+
+void Dependences::collectInfo(Scop &S, isl_union_map **Read,
+                              isl_union_map **Write, isl_union_map **MayWrite,
+                              isl_union_map **AccessSchedule,
+                              isl_union_map **StmtSchedule) {
+  isl_space *Space = S.getParamSpace();
+  *Read = isl_union_map_empty(isl_space_copy(Space));
+  *Write = isl_union_map_empty(isl_space_copy(Space));
+  *MayWrite = isl_union_map_empty(isl_space_copy(Space));
+  *AccessSchedule = isl_union_map_empty(isl_space_copy(Space));
+  *StmtSchedule = isl_union_map_empty(Space);
+
+  SmallPtrSet<const Value *, 8> ReductionBaseValues;
+  for (ScopStmt *Stmt : S)
+    for (MemoryAccess *MA : *Stmt)
+      if (MA->isReductionLike())
+        ReductionBaseValues.insert(MA->getBaseAddr());
+
+  for (ScopStmt *Stmt : S) {
+    for (MemoryAccess *MA : *Stmt) {
+      isl_set *domcp = Stmt->getDomain();
+      isl_map *accdom = MA->getAccessRelation();
+
+      accdom = isl_map_intersect_domain(accdom, domcp);
+
+      if (ReductionBaseValues.count(MA->getBaseAddr())) {
+        // Wrap the access domain and adjust the scattering accordingly.
+        //
+        // An access domain like
+        //   Stmt[i0, i1] -> MemAcc_A[i0 + i1]
+        // will be transformed into
+        //   [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> MemAcc_A[i0 + i1]
+        //
+        // The original scattering looks like
+        //   Stmt[i0, i1] -> [0, i0, 2, i1, 0]
+        // but as we transformed the access domain we need the scattering
+        // to match the new access domains, thus we need
+        //   [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> [0, i0, 2, i1, 0]
+        accdom = isl_map_range_map(accdom);
+
+        isl_map *stmt_scatter = Stmt->getScattering();
+        isl_set *scatter_dom = isl_map_domain(isl_map_copy(accdom));
+        isl_set *scatter_ran = isl_map_range(stmt_scatter);
+        isl_map *scatter =
+            isl_map_from_domain_and_range(scatter_dom, scatter_ran);
+        for (unsigned u = 0, e = Stmt->getNumIterators(); u != e; u++)
+          scatter =
+              isl_map_equate(scatter, isl_dim_out, 2 * u + 1, isl_dim_in, u);
+        *AccessSchedule = isl_union_map_add_map(*AccessSchedule, scatter);
+      }
+
+      if (MA->isRead())
+        *Read = isl_union_map_add_map(*Read, accdom);
+      else
+        *Write = isl_union_map_add_map(*Write, accdom);
+    }
+    *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt->getScattering());
+  }
+}
+
+/// @brief Fix all dimension of @p Zero to 0 and add it to @p user
+static int fixSetToZero(__isl_take isl_set *Zero, void *user) {
+  isl_union_set **User = (isl_union_set **)user;
+  for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
+    Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
+  *User = isl_union_set_add_set(*User, Zero);
+  return 0;
+}
+
+/// @brief Compute the privatization dependences for a given dependency @p Map
+///
+/// Privatization dependences are widened original dependences which originate
+/// or end in a reduction access. To compute them we apply the transitive close
+/// of the reduction dependences (which maps each iteration of a reduction
+/// statement to all following ones) on the RAW/WAR/WAW dependences. The
+/// dependences which start or end at a reduction statement will be extended to
+/// depend on all following reduction statement iterations as well.
+/// Note: "Following" here means according to the reduction dependences.
+///
+/// For the input:
+///
+///  S0:   *sum = 0;
+///        for (int i = 0; i < 1024; i++)
+///  S1:     *sum += i;
+///  S2:   *sum = *sum * 3;
+///
+/// we have the following dependences before we add privatization dependences:
+///
+///   RAW:
+///     { S0[] -> S1[0]; S1[1023] -> S2[] }
+///   WAR:
+///     {  }
+///   WAW:
+///     { S0[] -> S1[0]; S1[1024] -> S2[] }
+///   RED:
+///     { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
+///
+/// and afterwards:
+///
+///   RAW:
+///     { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
+///       S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
+///   WAR:
+///     {  }
+///   WAW:
+///     { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
+///       S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
+///   RED:
+///     { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
+///
+/// Note: This function also computes the (reverse) transitive closure of the
+///       reduction dependences.
+void Dependences::addPrivatizationDependences() {
+  isl_union_map *PrivRAW, *PrivWAW, *PrivWAR;
+
+  // The transitive closure might be over approximated, thus could lead to
+  // dependency cycles in the privatization dependences. To make sure this
+  // will not happen we remove all negative dependences after we computed
+  // the transitive closure.
+  TC_RED = isl_union_map_transitive_closure(isl_union_map_copy(RED), 0);
+
+  // FIXME: Apply the current schedule instead of assuming the identity schedule
+  //        here. The current approach is only valid as long as we compute the
+  //        dependences only with the initial (identity schedule). Any other
+  //        schedule could change "the direction of the backward depenendes" we
+  //        want to eliminate here.
+  isl_union_set *UDeltas = isl_union_map_deltas(isl_union_map_copy(TC_RED));
+  isl_union_set *Universe = isl_union_set_universe(isl_union_set_copy(UDeltas));
+  isl_union_set *Zero = isl_union_set_empty(isl_union_set_get_space(Universe));
+  isl_union_set_foreach_set(Universe, fixSetToZero, &Zero);
+  isl_union_map *NonPositive = isl_union_set_lex_le_union_set(UDeltas, Zero);
+
+  TC_RED = isl_union_map_subtract(TC_RED, NonPositive);
+
+  TC_RED = isl_union_map_union(
+      TC_RED, isl_union_map_reverse(isl_union_map_copy(TC_RED)));
+  TC_RED = isl_union_map_coalesce(TC_RED);
+
+  isl_union_map **Maps[] = {&RAW, &WAW, &WAR};
+  isl_union_map **PrivMaps[] = {&PrivRAW, &PrivWAW, &PrivWAR};
+  for (unsigned u = 0; u < 3; u++) {
+    isl_union_map **Map = Maps[u], **PrivMap = PrivMaps[u];
+
+    *PrivMap = isl_union_map_apply_range(isl_union_map_copy(*Map),
+                                         isl_union_map_copy(TC_RED));
+    *PrivMap = isl_union_map_union(
+        *PrivMap, isl_union_map_apply_range(isl_union_map_copy(TC_RED),
+                                            isl_union_map_copy(*Map)));
+
+    *Map = isl_union_map_union(*Map, *PrivMap);
+  }
+
+  isl_union_set_free(Universe);
+}
+
+void Dependences::calculateDependences(Scop &S) {
+  isl_union_map *Read, *Write, *MayWrite, *AccessSchedule, *StmtSchedule,
+      *Schedule;
+
+  DEBUG(dbgs() << "Scop: \n" << S << "\n");
+
+  collectInfo(S, &Read, &Write, &MayWrite, &AccessSchedule, &StmtSchedule);
+
+  Schedule =
+      isl_union_map_union(AccessSchedule, isl_union_map_copy(StmtSchedule));
+
+  Read = isl_union_map_coalesce(Read);
+  Write = isl_union_map_coalesce(Write);
+  MayWrite = isl_union_map_coalesce(MayWrite);
+
+  long MaxOpsOld = isl_ctx_get_max_operations(S.getIslCtx());
+  isl_ctx_set_max_operations(S.getIslCtx(), OptComputeOut);
+  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE);
+
+  DEBUG(dbgs() << "Read: " << Read << "\n";
+        dbgs() << "Write: " << Write << "\n";
+        dbgs() << "MayWrite: " << MayWrite << "\n";
+        dbgs() << "Schedule: " << Schedule << "\n");
+
+  // The pointers below will be set by the subsequent calls to
+  // isl_union_map_compute_flow.
+  RAW = WAW = WAR = RED = nullptr;
+
+  if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
+    isl_union_map_compute_flow(
+        isl_union_map_copy(Read), isl_union_map_copy(Write),
+        isl_union_map_copy(MayWrite), isl_union_map_copy(Schedule), &RAW,
+        nullptr, nullptr, nullptr);
+
+    isl_union_map_compute_flow(
+        isl_union_map_copy(Write), isl_union_map_copy(Write),
+        isl_union_map_copy(Read), isl_union_map_copy(Schedule), &WAW, &WAR,
+        nullptr, nullptr);
+  } else {
+    isl_union_map *Empty;
+
+    Empty = isl_union_map_empty(isl_union_map_get_space(Write));
+    Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
+
+    isl_union_map_compute_flow(
+        isl_union_map_copy(Read), isl_union_map_copy(Empty),
+        isl_union_map_copy(Write), isl_union_map_copy(Schedule), nullptr, &RAW,
+        nullptr, nullptr);
+
+    isl_union_map_compute_flow(
+        isl_union_map_copy(Write), isl_union_map_copy(Empty),
+        isl_union_map_copy(Read), isl_union_map_copy(Schedule), nullptr, &WAR,
+        nullptr, nullptr);
+
+    isl_union_map_compute_flow(
+        isl_union_map_copy(Write), isl_union_map_copy(Empty),
+        isl_union_map_copy(Write), isl_union_map_copy(Schedule), nullptr, &WAW,
+        nullptr, nullptr);
+    isl_union_map_free(Empty);
+  }
+
+  isl_union_map_free(MayWrite);
+  isl_union_map_free(Write);
+  isl_union_map_free(Read);
+  isl_union_map_free(Schedule);
+
+  RAW = isl_union_map_coalesce(RAW);
+  WAW = isl_union_map_coalesce(WAW);
+  WAR = isl_union_map_coalesce(WAR);
+
+  if (isl_ctx_last_error(S.getIslCtx()) == isl_error_quota) {
+    isl_union_map_free(RAW);
+    isl_union_map_free(WAW);
+    isl_union_map_free(WAR);
+    RAW = WAW = WAR = nullptr;
+    isl_ctx_reset_error(S.getIslCtx());
+  }
+  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT);
+  isl_ctx_reset_operations(S.getIslCtx());
+  isl_ctx_set_max_operations(S.getIslCtx(), MaxOpsOld);
+
+  isl_union_map *STMT_RAW, *STMT_WAW, *STMT_WAR;
+  STMT_RAW = isl_union_map_intersect_domain(
+      isl_union_map_copy(RAW),
+      isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
+  STMT_WAW = isl_union_map_intersect_domain(
+      isl_union_map_copy(WAW),
+      isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
+  STMT_WAR = isl_union_map_intersect_domain(isl_union_map_copy(WAR),
+                                            isl_union_map_domain(StmtSchedule));
+  DEBUG(dbgs() << "Wrapped Dependences:\n"; printScop(dbgs()); dbgs() << "\n");
+
+  // To handle reduction dependences we proceed as follows:
+  // 1) Aggregate all possible reduction dependences, namely all self
+  //    dependences on reduction like statements.
+  // 2) Intersect them with the actual RAW & WAW dependences to the get the
+  //    actual reduction dependences. This will ensure the load/store memory
+  //    addresses were __identical__ in the two iterations of the statement.
+  // 3) Relax the original RAW and WAW dependences by substracting the actual
+  //    reduction dependences. Binary reductions (sum += A[i]) cause both, and
+  //    the same, RAW and WAW dependences.
+  // 4) Add the privatization dependences which are widened versions of
+  //    already present dependences. They model the effect of manual
+  //    privatization at the outermost possible place (namely after the last
+  //    write and before the first access to a reduction location).
+
+  // Step 1)
+  RED = isl_union_map_empty(isl_union_map_get_space(RAW));
+  for (ScopStmt *Stmt : S) {
+    for (MemoryAccess *MA : *Stmt) {
+      if (!MA->isReductionLike())
+        continue;
+      isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
+      isl_map *Identity =
+          isl_map_from_domain_and_range(isl_set_copy(AccDomW), AccDomW);
+      RED = isl_union_map_add_map(RED, Identity);
+    }
+  }
+
+  // Step 2)
+  RED = isl_union_map_intersect(RED, isl_union_map_copy(RAW));
+  RED = isl_union_map_intersect(RED, isl_union_map_copy(WAW));
+
+  if (!isl_union_map_is_empty(RED)) {
+
+    // Step 3)
+    RAW = isl_union_map_subtract(RAW, isl_union_map_copy(RED));
+    WAW = isl_union_map_subtract(WAW, isl_union_map_copy(RED));
+
+    // Step 4)
+    addPrivatizationDependences();
+  }
+
+  DEBUG(dbgs() << "Final Wrapped Dependences:\n"; printScop(dbgs());
+        dbgs() << "\n");
+
+  RAW = isl_union_map_zip(RAW);
+  WAW = isl_union_map_zip(WAW);
+  WAR = isl_union_map_zip(WAR);
+  RED = isl_union_map_zip(RED);
+  TC_RED = isl_union_map_zip(TC_RED);
+
+  DEBUG(dbgs() << "Zipped Dependences:\n"; printScop(dbgs()); dbgs() << "\n");
+
+  RAW = isl_union_set_unwrap(isl_union_map_domain(RAW));
+  WAW = isl_union_set_unwrap(isl_union_map_domain(WAW));
+  WAR = isl_union_set_unwrap(isl_union_map_domain(WAR));
+  RED = isl_union_set_unwrap(isl_union_map_domain(RED));
+  TC_RED = isl_union_set_unwrap(isl_union_map_domain(TC_RED));
+
+  DEBUG(dbgs() << "Unwrapped Dependences:\n"; printScop(dbgs());
+        dbgs() << "\n");
+
+  RAW = isl_union_map_union(RAW, STMT_RAW);
+  WAW = isl_union_map_union(WAW, STMT_WAW);
+  WAR = isl_union_map_union(WAR, STMT_WAR);
+
+  RAW = isl_union_map_coalesce(RAW);
+  WAW = isl_union_map_coalesce(WAW);
+  WAR = isl_union_map_coalesce(WAR);
+  RED = isl_union_map_coalesce(RED);
+  TC_RED = isl_union_map_coalesce(TC_RED);
+
+  DEBUG(printScop(dbgs()));
+}
+
+bool Dependences::runOnScop(Scop &S) {
+  releaseMemory();
+  calculateDependences(S);
+
+  return false;
+}
+
+bool Dependences::isValidScattering(StatementToIslMapTy *NewScattering) {
+  Scop &S = getCurScop();
+
+  if (LegalityCheckDisabled)
+    return true;
+
+  isl_union_map *Dependences = getDependences(TYPE_RAW | TYPE_WAW | TYPE_WAR);
+  isl_space *Space = S.getParamSpace();
+  isl_union_map *Scattering = isl_union_map_empty(Space);
+
+  isl_space *ScatteringSpace = 0;
+
+  for (ScopStmt *Stmt : S) {
+    isl_map *StmtScat;
+
+    if (NewScattering->find(Stmt) == NewScattering->end())
+      StmtScat = Stmt->getScattering();
+    else
+      StmtScat = isl_map_copy((*NewScattering)[Stmt]);
+
+    if (!ScatteringSpace)
+      ScatteringSpace = isl_space_range(isl_map_get_space(StmtScat));
+
+    Scattering = isl_union_map_add_map(Scattering, StmtScat);
+  }
+
+  Dependences =
+      isl_union_map_apply_domain(Dependences, isl_union_map_copy(Scattering));
+  Dependences = isl_union_map_apply_range(Dependences, Scattering);
+
+  isl_set *Zero = isl_set_universe(isl_space_copy(ScatteringSpace));
+  for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
+    Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
+
+  isl_union_set *UDeltas = isl_union_map_deltas(Dependences);
+  isl_set *Deltas = isl_union_set_extract_set(UDeltas, ScatteringSpace);
+  isl_union_set_free(UDeltas);
+
+  isl_map *NonPositive = isl_set_lex_le_set(Deltas, Zero);
+  bool IsValid = isl_map_is_empty(NonPositive);
+  isl_map_free(NonPositive);
+
+  return IsValid;
+}
+
+isl_union_map *getCombinedScheduleForSpace(Scop *scop, unsigned dimLevel) {
+  isl_space *Space = scop->getParamSpace();
+  isl_union_map *schedule = isl_union_map_empty(Space);
+
+  for (ScopStmt *Stmt : *scop) {
+    unsigned remainingDimensions = Stmt->getNumScattering() - dimLevel;
+    isl_map *Scattering = isl_map_project_out(
+        Stmt->getScattering(), isl_dim_out, dimLevel, remainingDimensions);
+    schedule = isl_union_map_add_map(schedule, Scattering);
+  }
+
+  return schedule;
+}
+
+bool Dependences::isParallelDimension(__isl_take isl_set *ScheduleSubset,
+                                      unsigned ParallelDim) {
+  // To check if a loop is parallel, we perform the following steps:
+  //
+  // o Move dependences from 'Domain -> Domain' to 'Schedule -> Schedule' space.
+  // o Limit dependences to the schedule space enumerated by the loop.
+  // o Calculate distances of the dependences.
+  // o Check if one of the distances is invalid in presence of parallelism.
+
+  isl_union_map *Schedule, *Deps;
+  isl_map *ScheduleDeps;
+  Scop *S = &getCurScop();
+
+  if (!hasValidDependences()) {
+    isl_set_free(ScheduleSubset);
+    return false;
+  }
+
+  // FIXME: We can remove ignore reduction dependences in case we privatize the
+  //        memory locations the reduction statements reduce into.
+  Deps = getDependences(TYPE_RAW | TYPE_WAW | TYPE_WAR | TYPE_RED);
+
+  if (isl_union_map_is_empty(Deps)) {
+    isl_union_map_free(Deps);
+    isl_set_free(ScheduleSubset);
+    return true;
+  }
+
+  Schedule = getCombinedScheduleForSpace(S, ParallelDim);
+  Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(Schedule));
+  Deps = isl_union_map_apply_domain(Deps, Schedule);
+
+  if (isl_union_map_is_empty(Deps)) {
+    isl_union_map_free(Deps);
+    isl_set_free(ScheduleSubset);
+    return true;
+  }
+
+  ScheduleDeps = isl_map_from_union_map(Deps);
+  ScheduleDeps =
+      isl_map_intersect_domain(ScheduleDeps, isl_set_copy(ScheduleSubset));
+  ScheduleDeps = isl_map_intersect_range(ScheduleDeps, ScheduleSubset);
+
+  isl_set *Distances = isl_map_deltas(ScheduleDeps);
+  isl_space *Space = isl_set_get_space(Distances);
+  isl_set *Invalid = isl_set_universe(Space);
+
+  // [0, ..., 0, +] - All zeros and last dimension larger than zero
+  for (unsigned i = 0; i < ParallelDim - 1; i++)
+    Invalid = isl_set_fix_si(Invalid, isl_dim_set, i, 0);
+
+  Invalid = isl_set_lower_bound_si(Invalid, isl_dim_set, ParallelDim - 1, 1);
+  Invalid = isl_set_intersect(Invalid, Distances);
+
+  bool IsParallel = isl_set_is_empty(Invalid);
+  isl_set_free(Invalid);
+
+  return IsParallel;
+}
+
+static void printDependencyMap(raw_ostream &OS, __isl_keep isl_union_map *DM) {
+  if (DM)
+    OS << DM << "\n";
+  else
+    OS << "n/a\n";
+}
+
+void Dependences::printScop(raw_ostream &OS) const {
+  OS << "\tRAW dependences:\n\t\t";
+  printDependencyMap(OS, RAW);
+  OS << "\tWAR dependences:\n\t\t";
+  printDependencyMap(OS, WAR);
+  OS << "\tWAW dependences:\n\t\t";
+  printDependencyMap(OS, WAW);
+  OS << "\tReduction dependences:\n\t\t";
+  printDependencyMap(OS, RED);
+  OS << "\tTransitive closure of reduction dependences:\n\t\t";
+  printDependencyMap(OS, TC_RED);
+}
+
+void Dependences::releaseMemory() {
+  isl_union_map_free(RAW);
+  isl_union_map_free(WAR);
+  isl_union_map_free(WAW);
+  isl_union_map_free(RED);
+  isl_union_map_free(TC_RED);
+
+  RED = RAW = WAR = WAW = TC_RED = nullptr;
+}
+
+isl_union_map *Dependences::getDependences(int Kinds) {
+  assert(hasValidDependences() && "No valid dependences available");
+  isl_space *Space = isl_union_map_get_space(RAW);
+  isl_union_map *Deps = isl_union_map_empty(Space);
+
+  if (Kinds & TYPE_RAW)
+    Deps = isl_union_map_union(Deps, isl_union_map_copy(RAW));
+
+  if (Kinds & TYPE_WAR)
+    Deps = isl_union_map_union(Deps, isl_union_map_copy(WAR));
+
+  if (Kinds & TYPE_WAW)
+    Deps = isl_union_map_union(Deps, isl_union_map_copy(WAW));
+
+  if (Kinds & TYPE_RED)
+    Deps = isl_union_map_union(Deps, isl_union_map_copy(RED));
+
+  if (Kinds & TYPE_TC_RED)
+    Deps = isl_union_map_union(Deps, isl_union_map_copy(TC_RED));
+
+  Deps = isl_union_map_coalesce(Deps);
+  Deps = isl_union_map_detect_equalities(Deps);
+  return Deps;
+}
+
+bool Dependences::hasValidDependences() {
+  return (RAW != nullptr) && (WAR != nullptr) && (WAW != nullptr);
+}
+
+void Dependences::getAnalysisUsage(AnalysisUsage &AU) const {
+  ScopPass::getAnalysisUsage(AU);
+}
+
+char Dependences::ID = 0;
+
+Pass *polly::createDependencesPass() { return new Dependences(); }
+
+INITIALIZE_PASS_BEGIN(Dependences, "polly-dependences",
+                      "Polly - Calculate dependences", false, false);
+INITIALIZE_PASS_DEPENDENCY(ScopInfo);
+INITIALIZE_PASS_END(Dependences, "polly-dependences",
+                    "Polly - Calculate dependences", false, false)
diff --git a/rc1/lib/Analysis/ScopDetection.cpp b/rc1/lib/Analysis/ScopDetection.cpp
new file mode 100644
index 0000000..75d6731
--- /dev/null
+++ b/rc1/lib/Analysis/ScopDetection.cpp
@@ -0,0 +1,909 @@
+//===----- 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/CodeGen/BlockGenerators.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
+#include "polly/ScopDetectionDiagnostic.h"
+#include "polly/ScopDetection.h"
+#include "polly/Support/SCEVValidator.h"
+#include "polly/Support/ScopHelper.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/Debug.h"
+#include <set>
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-detect"
+
+static cl::opt<bool>
+    DetectScopsWithoutLoops("polly-detect-scops-in-functions-without-loops",
+                            cl::desc("Detect scops in functions without loops"),
+                            cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                            cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    DetectRegionsWithoutLoops("polly-detect-scops-in-regions-without-loops",
+                              cl::desc("Detect scops in regions without loops"),
+                              cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                              cl::cat(PollyCategory));
+
+static cl::opt<std::string> OnlyFunction(
+    "polly-only-func",
+    cl::desc("Only run on functions that contain a certain string"),
+    cl::value_desc("string"), cl::ValueRequired, cl::init(""),
+    cl::cat(PollyCategory));
+
+static cl::opt<std::string> OnlyRegion(
+    "polly-only-region",
+    cl::desc("Only run on certain regions (The provided identifier must "
+             "appear in the name of the region's entry block"),
+    cl::value_desc("identifier"), cl::ValueRequired, cl::init(""),
+    cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    IgnoreAliasing("polly-ignore-aliasing",
+                   cl::desc("Ignore possible aliasing of the array bases"),
+                   cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                   cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    ReportLevel("polly-report",
+                cl::desc("Print information about the activities of Polly"),
+                cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    AllowNonAffine("polly-allow-nonaffine",
+                   cl::desc("Allow non affine access functions in arrays"),
+                   cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                   cl::cat(PollyCategory));
+
+static cl::opt<bool, true>
+    TrackFailures("polly-detect-track-failures",
+                  cl::desc("Track failure strings in detecting scop regions"),
+                  cl::location(PollyTrackFailures), cl::Hidden, cl::ZeroOrMore,
+                  cl::init(false), cl::cat(PollyCategory));
+
+static cl::opt<bool> KeepGoing("polly-detect-keep-going",
+                               cl::desc("Do not fail on the first error."),
+                               cl::Hidden, cl::ZeroOrMore, cl::init(false),
+                               cl::cat(PollyCategory));
+
+static cl::opt<bool, true>
+    PollyDelinearizeX("polly-delinearize",
+                      cl::desc("Delinearize array access functions"),
+                      cl::location(PollyDelinearize), cl::Hidden,
+                      cl::ZeroOrMore, cl::init(false), cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    VerifyScops("polly-detect-verify",
+                cl::desc("Verify the detected SCoPs after each transformation"),
+                cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                cl::cat(PollyCategory));
+
+bool polly::PollyTrackFailures = false;
+bool polly::PollyDelinearize = false;
+StringRef polly::PollySkipFnAttr = "polly.skip.fn";
+
+//===----------------------------------------------------------------------===//
+// Statistics.
+
+STATISTIC(ValidRegion, "Number of regions that a valid part of Scop");
+
+class DiagnosticScopFound : public DiagnosticInfo {
+private:
+  static int PluginDiagnosticKind;
+
+  Function &F;
+  std::string FileName;
+  unsigned EntryLine, ExitLine;
+
+public:
+  DiagnosticScopFound(Function &F, std::string FileName, unsigned EntryLine,
+                      unsigned ExitLine)
+      : DiagnosticInfo(PluginDiagnosticKind, DS_Note), F(F), FileName(FileName),
+        EntryLine(EntryLine), ExitLine(ExitLine) {}
+
+  virtual void print(DiagnosticPrinter &DP) const;
+
+  static bool classof(const DiagnosticInfo *DI) {
+    return DI->getKind() == PluginDiagnosticKind;
+  }
+};
+
+int DiagnosticScopFound::PluginDiagnosticKind = 10;
+
+void DiagnosticScopFound::print(DiagnosticPrinter &DP) const {
+  DP << "Polly detected an optimizable loop region (scop) in function '" << F
+     << "'\n";
+
+  if (FileName.empty()) {
+    DP << "Scop location is unknown. Compile with debug info "
+          "(-g) to get more precise information. ";
+    return;
+  }
+
+  DP << FileName << ":" << EntryLine << ": Start of scop\n";
+  DP << FileName << ":" << ExitLine << ": End of scop";
+}
+
+//===----------------------------------------------------------------------===//
+// ScopDetection.
+
+template <class RR, typename... Args>
+inline bool ScopDetection::invalid(DetectionContext &Context, bool Assert,
+                                   Args &&... Arguments) const {
+
+  if (!Context.Verifying) {
+    RejectLog &Log = Context.Log;
+    std::shared_ptr<RR> RejectReason = std::make_shared<RR>(Arguments...);
+
+    if (PollyTrackFailures)
+      Log.report(RejectReason);
+
+    DEBUG(dbgs() << RejectReason->getMessage());
+    DEBUG(dbgs() << "\n");
+  } else {
+    assert(!Assert && "Verification of detected scop failed");
+  }
+
+  return false;
+}
+
+bool ScopDetection::isMaxRegionInScop(const Region &R, bool Verify) const {
+  if (!ValidRegions.count(&R))
+    return false;
+
+  if (Verify)
+    return isValidRegion(const_cast<Region &>(R));
+
+  return true;
+}
+
+std::string ScopDetection::regionIsInvalidBecause(const Region *R) const {
+  if (!RejectLogs.count(R))
+    return "";
+
+  // Get the first error we found. Even in keep-going mode, this is the first
+  // reason that caused the candidate to be rejected.
+  RejectLog Errors = RejectLogs.at(R);
+
+  // This can happen when we marked a region invalid, but didn't track
+  // an error for it.
+  if (Errors.size() == 0)
+    return "";
+
+  RejectReasonPtr RR = *Errors.begin();
+  return RR->getMessage();
+}
+
+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)
+    return invalid<ReportNonBranchTerminator>(Context, /*Assert=*/true, &BB);
+
+  if (Br->isUnconditional())
+    return true;
+
+  Value *Condition = Br->getCondition();
+
+  // UndefValue is not allowed as condition.
+  if (isa<UndefValue>(Condition))
+    return invalid<ReportUndefCond>(Context, /*Assert=*/true, Br, &BB);
+
+  // Only Constant and ICmpInst are allowed as condition.
+  if (!(isa<Constant>(Condition) || isa<ICmpInst>(Condition)))
+    return invalid<ReportInvalidCond>(Context, /*Assert=*/true, Br, &BB);
+
+  // 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)))
+      return invalid<ReportUndefOperand>(Context, /*Assert=*/true, &BB, ICmp);
+
+    Loop *L = LI->getLoopFor(ICmp->getParent());
+    const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
+    const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
+
+    if (!isAffineExpr(&Context.CurRegion, LHS, *SE) ||
+        !isAffineExpr(&Context.CurRegion, RHS, *SE))
+      return invalid<ReportNonAffBranch>(Context, /*Assert=*/true, &BB, LHS,
+                                         RHS, ICmp);
+  }
+
+  // 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)
+    return invalid<ReportCondition>(Context, /*Assert=*/true, &BB);
+
+  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::isInvariant(const Value &Val, const Region &Reg) const {
+  // A reference to function argument or constant value is invariant.
+  if (isa<Argument>(Val) || isa<Constant>(Val))
+    return true;
+
+  const Instruction *I = dyn_cast<Instruction>(&Val);
+  if (!I)
+    return false;
+
+  if (!Reg.contains(I))
+    return true;
+
+  if (I->mayHaveSideEffects())
+    return false;
+
+  // When Val is a Phi node, it is likely not invariant. We do not check whether
+  // Phi nodes are actually invariant, we assume that Phi nodes are usually not
+  // invariant. Recursively checking the operators of Phi nodes would lead to
+  // infinite recursion.
+  if (isa<PHINode>(*I))
+    return false;
+
+  for (const Use &Operand : I->operands())
+    if (!isInvariant(*Operand, Reg))
+      return false;
+
+  // When the instruction is a load instruction, check that no write to memory
+  // in the region aliases with the load.
+  if (const LoadInst *LI = dyn_cast<LoadInst>(I)) {
+    AliasAnalysis::Location Loc = AA->getLocation(LI);
+    const Region::const_block_iterator BE = Reg.block_end();
+    // Check if any basic block in the region can modify the location pointed to
+    // by 'Loc'.  If so, 'Val' is (likely) not invariant in the region.
+    for (const BasicBlock *BB : Reg.blocks())
+      if (AA->canBasicBlockModify(*BB, Loc))
+        return false;
+  }
+
+  return true;
+}
+
+MapInsnToMemAcc InsnToMemAcc;
+
+bool ScopDetection::hasAffineMemoryAccesses(DetectionContext &Context) const {
+  for (auto P : Context.NonAffineAccesses) {
+    const SCEVUnknown *BasePointer = P.first;
+    Value *BaseValue = BasePointer->getValue();
+    ArrayShape *Shape = new ArrayShape(BasePointer);
+
+    // First step: collect parametric terms in all array references.
+    SmallVector<const SCEV *, 4> Terms;
+    for (PairInsnAddRec PIAF : Context.NonAffineAccesses[BasePointer])
+      PIAF.second->collectParametricTerms(*SE, Terms);
+
+    // Also collect terms from the affine memory accesses.
+    for (PairInsnAddRec PIAF : Context.AffineAccesses[BasePointer])
+      PIAF.second->collectParametricTerms(*SE, Terms);
+
+    // Second step: find array shape.
+    SE->findArrayDimensions(Terms, Shape->DelinearizedSizes,
+                            Context.ElementSize[BasePointer]);
+
+    // Third step: compute the access functions for each subscript.
+    for (PairInsnAddRec PIAF : Context.NonAffineAccesses[BasePointer]) {
+      const SCEVAddRecExpr *AF = PIAF.second;
+      const Instruction *Insn = PIAF.first;
+      if (Shape->DelinearizedSizes.empty())
+        return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF,
+                                              Insn);
+
+      MemAcc *Acc = new MemAcc(Insn, Shape);
+      InsnToMemAcc.insert({Insn, Acc});
+      AF->computeAccessFunctions(*SE, Acc->DelinearizedSubscripts,
+                                 Shape->DelinearizedSizes);
+      if (Shape->DelinearizedSizes.empty() ||
+          Acc->DelinearizedSubscripts.empty())
+        return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF,
+                                              Insn);
+
+      // Check that the delinearized subscripts are affine.
+      for (const SCEV *S : Acc->DelinearizedSubscripts)
+        if (!isAffineExpr(&Context.CurRegion, S, *SE, BaseValue))
+          return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true, AF,
+                                                Insn);
+    }
+  }
+  return true;
+}
+
+bool ScopDetection::isValidMemoryAccess(Instruction &Inst,
+                                        DetectionContext &Context) const {
+  Value *Ptr = getPointerOperand(Inst);
+  Loop *L = LI->getLoopFor(Inst.getParent());
+  const SCEV *AccessFunction = SE->getSCEVAtScope(Ptr, L);
+  const SCEVUnknown *BasePointer;
+  Value *BaseValue;
+
+  BasePointer = dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));
+
+  if (!BasePointer)
+    return invalid<ReportNoBasePtr>(Context, /*Assert=*/true, &Inst);
+
+  BaseValue = BasePointer->getValue();
+
+  if (isa<UndefValue>(BaseValue))
+    return invalid<ReportUndefBasePtr>(Context, /*Assert=*/true, &Inst);
+
+  // Check that the base address of the access is invariant in the current
+  // region.
+  if (!isInvariant(*BaseValue, Context.CurRegion))
+    // Verification of this property is difficult as the independent blocks
+    // pass may introduce aliasing that we did not have when running the
+    // scop detection.
+    return invalid<ReportVariantBasePtr>(Context, /*Assert=*/false, BaseValue,
+                                         &Inst);
+
+  AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
+
+  if (AllowNonAffine) {
+    // Do not check whether AccessFunction is affine.
+  } else if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE,
+                           BaseValue)) {
+    const SCEVAddRecExpr *AF = dyn_cast<SCEVAddRecExpr>(AccessFunction);
+
+    if (!PollyDelinearize || !AF)
+      return invalid<ReportNonAffineAccess>(Context, /*Assert=*/true,
+                                            AccessFunction, &Inst);
+
+    const SCEV *ElementSize = SE->getElementSize(&Inst);
+    Context.ElementSize[BasePointer] = ElementSize;
+
+    // Collect all non affine memory accesses, and check whether they are linear
+    // at the end of scop detection. That way we can delinearize all the memory
+    // accesses to the same array in a unique step.
+    if (Context.NonAffineAccesses[BasePointer].size() == 0)
+      Context.NonAffineAccesses[BasePointer] = AFs();
+    Context.NonAffineAccesses[BasePointer].push_back({&Inst, AF});
+  } else if (const SCEVAddRecExpr *AF =
+                 dyn_cast<SCEVAddRecExpr>(AccessFunction)) {
+    if (Context.AffineAccesses[BasePointer].size() == 0)
+      Context.AffineAccesses[BasePointer] = AFs();
+    Context.AffineAccesses[BasePointer].push_back({&Inst, AF});
+  }
+
+  // FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions
+  // created by IndependentBlocks Pass.
+  if (IntToPtrInst *Inst = dyn_cast<IntToPtrInst>(BaseValue))
+    return invalid<ReportIntToPtr>(Context, /*Assert=*/true, Inst);
+
+  if (IgnoreAliasing)
+    return true;
+
+  // Check if the base pointer of the memory access does alias with
+  // any other pointer. This cannot be handled at the moment.
+  AliasSet &AS =
+      Context.AST.getAliasSetForPointer(BaseValue, AliasAnalysis::UnknownSize,
+                                        Inst.getMetadata(LLVMContext::MD_tbaa));
+
+  // INVALID triggers an assertion in verifying mode, if it detects that a
+  // SCoP was detected by SCoP detection and that this SCoP was invalidated by
+  // a pass that stated it would preserve the SCoPs. We disable this check as
+  // the independent blocks pass may create memory references which seem to
+  // alias, if -basicaa is not available. They actually do not, but as we can
+  // not proof this without -basicaa we would fail. We disable this check to
+  // not cause irrelevant verification failures.
+  if (!AS.isMustAlias())
+    return invalid<ReportAlias>(Context, /*Assert=*/false, &Inst, AS);
+
+  return true;
+}
+
+bool ScopDetection::isValidInstruction(Instruction &Inst,
+                                       DetectionContext &Context) const {
+  if (PHINode *PN = dyn_cast<PHINode>(&Inst))
+    if (!canSynthesize(PN, LI, SE, &Context.CurRegion)) {
+      if (SCEVCodegen)
+        return invalid<ReportPhiNodeRefInRegion>(Context, /*Assert=*/true,
+                                                 &Inst);
+      else
+        return invalid<ReportNonCanonicalPhiNode>(Context, /*Assert=*/true,
+                                                  &Inst);
+    }
+
+  // We only check the call instruction but not invoke instruction.
+  if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
+    if (isValidCallInst(*CI))
+      return true;
+
+    return invalid<ReportFuncCall>(Context, /*Assert=*/true, &Inst);
+  }
+
+  if (!Inst.mayWriteToMemory() && !Inst.mayReadFromMemory()) {
+    if (!isa<AllocaInst>(Inst))
+      return true;
+
+    return invalid<ReportAlloca>(Context, /*Assert=*/true, &Inst);
+  }
+
+  // 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.
+  return invalid<ReportUnknownInst>(Context, /*Assert=*/true, &Inst);
+}
+
+bool ScopDetection::isValidLoop(Loop *L, DetectionContext &Context) const {
+  if (!SCEVCodegen) {
+    // If code generation is not in scev based mode, we need to ensure that
+    // each loop has a canonical induction variable.
+    PHINode *IndVar = L->getCanonicalInductionVariable();
+    if (!IndVar)
+      return invalid<ReportLoopHeader>(Context, /*Assert=*/true, L);
+  }
+
+  // Is the loop count affine?
+  const SCEV *LoopCount = SE->getBackedgeTakenCount(L);
+  if (!isAffineExpr(&Context.CurRegion, LoopCount, *SE))
+    return invalid<ReportLoopBound>(Context, /*Assert=*/true, L, LoopCount);
+
+  return true;
+}
+
+Region *ScopDetection::expandRegion(Region &R) {
+  // Initial no valid region was found (greater than R)
+  Region *LastValidRegion = nullptr;
+  Region *ExpandedRegion = R.getExpandedRegion();
+
+  DEBUG(dbgs() << "\tExpanding " << R.getNameStr() << "\n");
+
+  while (ExpandedRegion) {
+    DetectionContext Context(*ExpandedRegion, *AA, false /* verifying */);
+    DEBUG(dbgs() << "\t\tTrying " << ExpandedRegion->getNameStr() << "\n");
+    // Only expand when we did not collect errors.
+
+    // Check the exit first (cheap)
+    if (isValidExit(Context) && !Context.Log.hasErrors()) {
+      // If the exit is valid check all blocks
+      //  - if true, a valid region was found => store it + keep expanding
+      //  - if false, .tbd. => stop  (should this really end the loop?)
+      if (!allBlocksValid(Context) || Context.Log.hasErrors())
+        break;
+
+      if (Context.Log.hasErrors())
+        break;
+
+      // Delete unnecessary regions (allocated by getExpandedRegion)
+      if (LastValidRegion)
+        delete LastValidRegion;
+
+      // Store this region, because it is the greatest valid (encountered so
+      // far).
+      LastValidRegion = ExpandedRegion;
+
+      // Create and test the next greater region (if any)
+      ExpandedRegion = ExpandedRegion->getExpandedRegion();
+
+    } else {
+      // Create and test the next greater region (if any)
+      Region *TmpRegion = ExpandedRegion->getExpandedRegion();
+
+      // Delete unnecessary regions (allocated by getExpandedRegion)
+      delete ExpandedRegion;
+
+      ExpandedRegion = TmpRegion;
+    }
+  }
+
+  DEBUG({
+    if (LastValidRegion)
+      dbgs() << "\tto " << LastValidRegion->getNameStr() << "\n";
+    else
+      dbgs() << "\tExpanding " << R.getNameStr() << " failed\n";
+  });
+
+  return LastValidRegion;
+}
+static bool regionWithoutLoops(Region &R, LoopInfo *LI) {
+  for (const BasicBlock *BB : R.blocks())
+    if (R.contains(LI->getLoopFor(BB)))
+      return false;
+
+  return true;
+}
+
+// Remove all direct and indirect children of region R from the region set Regs,
+// but do not recurse further if the first child has been found.
+//
+// Return the number of regions erased from Regs.
+static unsigned eraseAllChildren(std::set<const Region *> &Regs,
+                                 const Region &R) {
+  unsigned Count = 0;
+  for (auto &SubRegion : R) {
+    if (Regs.find(SubRegion.get()) != Regs.end()) {
+      ++Count;
+      Regs.erase(SubRegion.get());
+    } else {
+      Count += eraseAllChildren(Regs, *SubRegion);
+    }
+  }
+  return Count;
+}
+
+void ScopDetection::findScops(Region &R) {
+  if (!DetectRegionsWithoutLoops && regionWithoutLoops(R, LI))
+    return;
+
+  bool IsValidRegion = isValidRegion(R);
+  bool HasErrors = RejectLogs.count(&R) > 0;
+
+  if (IsValidRegion && !HasErrors) {
+    ++ValidRegion;
+    ValidRegions.insert(&R);
+    return;
+  }
+
+  for (auto &SubRegion : R)
+    findScops(*SubRegion);
+
+  // 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 (auto &SubRegion : R)
+    ToExpand.push_back(SubRegion.get());
+
+  for (Region *CurrentRegion : ToExpand) {
+    // Skip regions that had errors.
+    bool HadErrors = RejectLogs.hasErrors(CurrentRegion);
+    if (HadErrors)
+      continue;
+
+    // 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);
+
+    // Erase all (direct and indirect) children of ExpandedR from the valid
+    // regions and update the number of valid regions.
+    ValidRegion -= eraseAllChildren(ValidRegions, *ExpandedR);
+  }
+}
+
+bool ScopDetection::allBlocksValid(DetectionContext &Context) const {
+  Region &R = Context.CurRegion;
+
+  for (const BasicBlock *BB : R.blocks()) {
+    Loop *L = LI->getLoopFor(BB);
+    if (L && L->getHeader() == BB && (!isValidLoop(L, Context) && !KeepGoing))
+      return false;
+  }
+
+  for (BasicBlock *BB : R.blocks())
+    if (!isValidCFG(*BB, Context) && !KeepGoing)
+      return false;
+
+  for (BasicBlock *BB : R.blocks())
+    for (BasicBlock::iterator I = BB->begin(), E = --BB->end(); I != E; ++I)
+      if (!isValidInstruction(*I, Context) && !KeepGoing)
+        return false;
+
+  if (!hasAffineMemoryAccesses(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))
+      return invalid<ReportPHIinExit>(Context, /*Assert=*/true, I);
+  }
+
+  return true;
+}
+
+bool ScopDetection::isValidRegion(Region &R) const {
+  DetectionContext Context(R, *AA, false /*verifying*/);
+
+  bool RegionIsValid = isValidRegion(Context);
+  bool HasErrors = !RegionIsValid || Context.Log.size() > 0;
+
+  if (PollyTrackFailures && HasErrors)
+    RejectLogs.insert(std::make_pair(&R, Context.Log));
+
+  return RegionIsValid;
+}
+
+bool ScopDetection::isValidRegion(DetectionContext &Context) const {
+  Region &R = Context.CurRegion;
+
+  DEBUG(dbgs() << "Checking region: " << R.getNameStr() << "\n\t");
+
+  if (R.isTopLevelRegion()) {
+    DEBUG(dbgs() << "Top level region is invalid"; dbgs() << "\n");
+    return false;
+  }
+
+  if (!R.getEntry()->getName().count(OnlyRegion)) {
+    DEBUG({
+      dbgs() << "Region entry does not match -polly-region-only";
+      dbgs() << "\n";
+    });
+    return false;
+  }
+
+  if (!R.getEnteringBlock()) {
+    BasicBlock *entry = R.getEntry();
+    Loop *L = LI->getLoopFor(entry);
+
+    if (L) {
+      if (!L->isLoopSimplifyForm())
+        return invalid<ReportSimpleLoop>(Context, /*Assert=*/true);
+
+      for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE;
+           ++PI) {
+        // Region entering edges come from the same loop but outside the region
+        // are not allowed.
+        if (L->contains(*PI) && !R.contains(*PI))
+          return invalid<ReportIndEdge>(Context, /*Assert=*/true, *PI);
+      }
+    }
+  }
+
+  // SCoP cannot contain 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()))
+    return invalid<ReportEntry>(Context, /*Assert=*/true, R.getEntry());
+
+  if (!isValidExit(Context))
+    return false;
+
+  if (!allBlocksValid(Context))
+    return false;
+
+  DEBUG(dbgs() << "OK\n");
+  return true;
+}
+
+void ScopDetection::markFunctionAsInvalid(Function *F) const {
+  F->addFnAttr(PollySkipFnAttr);
+}
+
+bool ScopDetection::isValidFunction(llvm::Function &F) {
+  return !F.hasFnAttribute(PollySkipFnAttr);
+}
+
+void ScopDetection::printLocations(llvm::Function &F) {
+  for (const Region *R : *this) {
+    unsigned LineEntry, LineExit;
+    std::string FileName;
+
+    getDebugLocation(R, LineEntry, LineExit, FileName);
+    DiagnosticScopFound Diagnostic(F, FileName, LineEntry, LineExit);
+    F.getContext().diagnose(Diagnostic);
+  }
+}
+
+void
+ScopDetection::emitMissedRemarksForValidRegions(const Function &F,
+                                                const RegionSet &ValidRegions) {
+  for (const Region *R : ValidRegions) {
+    const Region *Parent = R->getParent();
+    if (Parent && !Parent->isTopLevelRegion() && RejectLogs.count(Parent))
+      emitRejectionRemarks(F, RejectLogs.at(Parent));
+  }
+}
+
+void ScopDetection::emitMissedRemarksForLeaves(const Function &F,
+                                               const Region *R) {
+  for (const std::unique_ptr<Region> &Child : *R) {
+    bool IsValid = ValidRegions.count(Child.get());
+    if (IsValid)
+      continue;
+
+    bool IsLeaf = Child->begin() == Child->end();
+    if (!IsLeaf)
+      emitMissedRemarksForLeaves(F, Child.get());
+    else {
+      if (RejectLogs.count(Child.get())) {
+        emitRejectionRemarks(F, RejectLogs.at(Child.get()));
+      }
+    }
+  }
+}
+
+bool ScopDetection::runOnFunction(llvm::Function &F) {
+  LI = &getAnalysis<LoopInfo>();
+  RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
+  if (!DetectScopsWithoutLoops && LI->empty())
+    return false;
+
+  AA = &getAnalysis<AliasAnalysis>();
+  SE = &getAnalysis<ScalarEvolution>();
+  Region *TopRegion = RI->getTopLevelRegion();
+
+  releaseMemory();
+
+  if (OnlyFunction != "" && !F.getName().count(OnlyFunction))
+    return false;
+
+  if (!isValidFunction(F))
+    return false;
+
+  findScops(*TopRegion);
+
+  // Only makes sense when we tracked errors.
+  if (PollyTrackFailures) {
+    emitMissedRemarksForValidRegions(F, ValidRegions);
+    emitMissedRemarksForLeaves(F, TopRegion);
+  }
+
+  for (const Region *R : ValidRegions)
+    emitValidRemarks(F, R);
+
+  if (ReportLevel >= 1)
+    printLocations(F);
+
+  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 {
+  if (!VerifyScops)
+    return;
+
+  for (const Region *R : ValidRegions)
+    verifyRegion(*R);
+}
+
+void ScopDetection::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<DominatorTreeWrapperPass>();
+  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<RegionInfoPass>();
+  AU.setPreservesAll();
+}
+
+void ScopDetection::print(raw_ostream &OS, const Module *) const {
+  for (const Region *R : ValidRegions)
+    OS << "Valid Region for Scop: " << R->getNameStr() << '\n';
+
+  OS << "\n";
+}
+
+void ScopDetection::releaseMemory() {
+  ValidRegions.clear();
+  RejectLogs.clear();
+
+  // Do not clear the invalid function set.
+}
+
+char ScopDetection::ID = 0;
+
+Pass *polly::createScopDetectionPass() { return new ScopDetection(); }
+
+INITIALIZE_PASS_BEGIN(ScopDetection, "polly-detect",
+                      "Polly - Detect static control parts (SCoPs)", false,
+                      false);
+INITIALIZE_AG_DEPENDENCY(AliasAnalysis);
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
+INITIALIZE_PASS_DEPENDENCY(LoopInfo);
+INITIALIZE_PASS_DEPENDENCY(PostDominatorTree);
+INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
+INITIALIZE_PASS_END(ScopDetection, "polly-detect",
+                    "Polly - Detect static control parts (SCoPs)", false, false)
diff --git a/rc1/lib/Analysis/ScopDetectionDiagnostic.cpp b/rc1/lib/Analysis/ScopDetectionDiagnostic.cpp
new file mode 100644
index 0000000..4b89333
--- /dev/null
+++ b/rc1/lib/Analysis/ScopDetectionDiagnostic.cpp
@@ -0,0 +1,566 @@
+//=== ScopDetectionDiagnostic.cpp - Error diagnostics --------- -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Small set of diagnostic helper classes to encapsulate any errors occurred
+// during the detection of Scops.
+//
+// The ScopDetection defines a set of error classes (via Statistic variables)
+// that groups a number of individual errors into a group, e.g. non-affinity
+// related errors.
+// On error we generate an object that carries enough additional information
+// to diagnose the error and generate a helpful error message.
+//
+//===----------------------------------------------------------------------===//
+#include "polly/ScopDetectionDiagnostic.h"
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Value.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+
+#include "llvm/Analysis/RegionInfo.h"
+
+#define DEBUG_TYPE "polly-detect"
+#include "llvm/Support/Debug.h"
+
+#include <string>
+
+#define BADSCOP_STAT(NAME, DESC)                                               \
+  STATISTIC(Bad##NAME##ForScop, "Number of bad regions for Scop: " DESC)
+
+BADSCOP_STAT(CFG, "CFG too complex");
+BADSCOP_STAT(IndVar, "Non canonical induction variable in loop");
+BADSCOP_STAT(IndEdge, "Found invalid region entering edges");
+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(Alias, "Found base address alias");
+BADSCOP_STAT(SimpleLoop, "Loop not in -loop-simplify form");
+BADSCOP_STAT(Other, "Others");
+
+namespace polly {
+/// @brief Small string conversion via raw_string_stream.
+template <typename T> std::string operator+(Twine LHS, const T &RHS) {
+  std::string Buf;
+  raw_string_ostream fmt(Buf);
+  fmt << RHS;
+  fmt.flush();
+
+  return LHS.concat(Buf).str();
+}
+
+void getDebugLocation(const Region *R, unsigned &LineBegin, unsigned &LineEnd,
+                      std::string &FileName) {
+  LineBegin = -1;
+  LineEnd = 0;
+
+  for (const BasicBlock *BB : R->blocks())
+    for (const Instruction &Inst : *BB) {
+      DebugLoc DL = Inst.getDebugLoc();
+      if (DL.isUnknown())
+        continue;
+
+      DIScope Scope(DL.getScope(Inst.getContext()));
+
+      if (FileName.empty())
+        FileName = Scope.getFilename();
+
+      unsigned NewLine = DL.getLine();
+
+      LineBegin = std::min(LineBegin, NewLine);
+      LineEnd = std::max(LineEnd, NewLine);
+    }
+}
+
+void emitRejectionRemarks(const llvm::Function &F, const RejectLog &Log) {
+  LLVMContext &Ctx = F.getContext();
+
+  const Region *R = Log.region();
+  const BasicBlock *Entry = R->getEntry();
+  DebugLoc DL = Entry->getTerminator()->getDebugLoc();
+
+  emitOptimizationRemarkMissed(
+      Ctx, DEBUG_TYPE, F, DL,
+      "The following errors keep this region from being a Scop.");
+  for (RejectReasonPtr RR : Log) {
+    const DebugLoc &Loc = RR->getDebugLoc();
+    if (!Loc.isUnknown())
+      emitOptimizationRemarkMissed(Ctx, DEBUG_TYPE, F, Loc,
+                                   RR->getEndUserMessage());
+  }
+}
+
+void emitValidRemarks(const llvm::Function &F, const Region *R) {
+  LLVMContext &Ctx = F.getContext();
+
+  const BasicBlock *Entry = R->getEntry();
+  const BasicBlock *Exit = R->getExit();
+
+  const DebugLoc &Begin = Entry->getFirstNonPHIOrDbg()->getDebugLoc();
+  const DebugLoc &End = Exit->getFirstNonPHIOrDbg()->getDebugLoc();
+
+  emitOptimizationRemark(Ctx, DEBUG_TYPE, F, Begin,
+                         "A valid Scop begins here.");
+  emitOptimizationRemark(Ctx, DEBUG_TYPE, F, End, "A valid Scop ends here.");
+}
+
+//===----------------------------------------------------------------------===//
+// RejectReason.
+const DebugLoc RejectReason::Unknown = DebugLoc();
+
+const llvm::DebugLoc &RejectReason::getDebugLoc() const {
+  // Allocate an empty DebugLoc and return it a reference to it.
+  return Unknown;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportCFG.
+
+ReportCFG::ReportCFG(const RejectReasonKind K) : RejectReason(K) {
+  ++BadCFGForScop;
+}
+
+bool ReportCFG::classof(const RejectReason *RR) {
+  return RR->getKind() >= rrkCFG && RR->getKind() <= rrkLastCFG;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportNonBranchTerminator.
+
+std::string ReportNonBranchTerminator::getMessage() const {
+  return ("Non branch instruction terminates BB: " + BB->getName()).str();
+}
+
+const DebugLoc &ReportNonBranchTerminator::getDebugLoc() const {
+  return BB->getTerminator()->getDebugLoc();
+}
+
+bool ReportNonBranchTerminator::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkNonBranchTerminator;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportCondition.
+
+std::string ReportCondition::getMessage() const {
+  return ("Not well structured condition at BB: " + BB->getName()).str();
+}
+
+const DebugLoc &ReportCondition::getDebugLoc() const {
+  return BB->getTerminator()->getDebugLoc();
+}
+
+bool ReportCondition::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkCondition;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportAffFunc.
+
+ReportAffFunc::ReportAffFunc(const RejectReasonKind K, const Instruction *Inst)
+    : RejectReason(K), Inst(Inst) {
+  ++BadAffFuncForScop;
+}
+
+bool ReportAffFunc::classof(const RejectReason *RR) {
+  return RR->getKind() >= rrkAffFunc && RR->getKind() <= rrkLastAffFunc;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportUndefCond.
+
+std::string ReportUndefCond::getMessage() const {
+  return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
+}
+
+bool ReportUndefCond::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkUndefCond;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportInvalidCond.
+
+std::string ReportInvalidCond::getMessage() const {
+  return ("Condition in BB '" + BB->getName()).str() +
+         "' neither constant nor an icmp instruction";
+}
+
+bool ReportInvalidCond::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkInvalidCond;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportUndefOperand.
+
+std::string ReportUndefOperand::getMessage() const {
+  return ("undef operand in branch at BB: " + BB->getName()).str();
+}
+
+bool ReportUndefOperand::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkUndefOperand;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportNonAffBranch.
+
+std::string ReportNonAffBranch::getMessage() const {
+  return ("Non affine branch in BB '" + BB->getName()).str() + "' with LHS: " +
+         *LHS + " and RHS: " + *RHS;
+}
+
+bool ReportNonAffBranch::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkNonAffBranch;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportNoBasePtr.
+
+std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
+
+bool ReportNoBasePtr::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkNoBasePtr;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportUndefBasePtr.
+
+std::string ReportUndefBasePtr::getMessage() const {
+  return "Undefined base pointer";
+}
+
+bool ReportUndefBasePtr::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkUndefBasePtr;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportVariantBasePtr.
+
+std::string ReportVariantBasePtr::getMessage() const {
+  return "Base address not invariant in current region:" + *BaseValue;
+}
+
+std::string ReportVariantBasePtr::getEndUserMessage() const {
+  return "The base address of this array is not invariant inside the loop";
+}
+
+bool ReportVariantBasePtr::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkVariantBasePtr;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportNonAffineAccess.
+
+std::string ReportNonAffineAccess::getMessage() const {
+  return "Non affine access function: " + *AccessFunction;
+}
+
+bool ReportNonAffineAccess::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkNonAffineAccess;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportIndVar.
+
+ReportIndVar::ReportIndVar(const RejectReasonKind K) : RejectReason(K) {
+  ++BadIndVarForScop;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportPhiNodeRefInRegion.
+
+ReportPhiNodeRefInRegion::ReportPhiNodeRefInRegion(Instruction *Inst)
+    : ReportIndVar(rrkPhiNodeRefInRegion), Inst(Inst) {}
+
+std::string ReportPhiNodeRefInRegion::getMessage() const {
+  return "SCEV of PHI node refers to SSA names in region: " + *Inst;
+}
+
+const DebugLoc &ReportPhiNodeRefInRegion::getDebugLoc() const {
+  return Inst->getDebugLoc();
+}
+
+bool ReportPhiNodeRefInRegion::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkPhiNodeRefInRegion;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportNonCanonicalPhiNode.
+
+ReportNonCanonicalPhiNode::ReportNonCanonicalPhiNode(Instruction *Inst)
+    : ReportIndVar(rrkNonCanonicalPhiNode), Inst(Inst) {}
+
+std::string ReportNonCanonicalPhiNode::getMessage() const {
+  return "Non canonical PHI node: " + *Inst;
+}
+
+const DebugLoc &ReportNonCanonicalPhiNode::getDebugLoc() const {
+  return Inst->getDebugLoc();
+}
+
+bool ReportNonCanonicalPhiNode::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkNonCanonicalPhiNode;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportLoopHeader.
+
+ReportLoopHeader::ReportLoopHeader(Loop *L)
+    : ReportIndVar(rrkLoopHeader), L(L) {}
+
+std::string ReportLoopHeader::getMessage() const {
+  return ("No canonical IV at loop header: " + L->getHeader()->getName()).str();
+}
+
+const DebugLoc &ReportLoopHeader::getDebugLoc() const {
+  BasicBlock *BB = L->getHeader();
+  return BB->getTerminator()->getDebugLoc();
+}
+
+bool ReportLoopHeader::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkLoopHeader;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportIndEdge.
+
+ReportIndEdge::ReportIndEdge(BasicBlock *BB)
+    : RejectReason(rrkIndEdge), BB(BB) {
+  ++BadIndEdgeForScop;
+}
+
+std::string ReportIndEdge::getMessage() const {
+  return "Region has invalid entering edges!";
+}
+
+const DebugLoc &ReportIndEdge::getDebugLoc() const {
+  return BB->getTerminator()->getDebugLoc();
+}
+
+bool ReportIndEdge::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkIndEdge;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportLoopBound.
+
+ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
+    : RejectReason(rrkLoopBound), L(L), LoopCount(LoopCount) {
+  ++BadLoopBoundForScop;
+}
+
+std::string ReportLoopBound::getMessage() const {
+  return "Non affine loop bound '" + *LoopCount + "' in loop: " +
+         L->getHeader()->getName();
+}
+
+const DebugLoc &ReportLoopBound::getDebugLoc() const {
+  const BasicBlock *BB = L->getHeader();
+  return BB->getTerminator()->getDebugLoc();
+}
+
+bool ReportLoopBound::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkLoopBound;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportFuncCall.
+
+ReportFuncCall::ReportFuncCall(Instruction *Inst)
+    : RejectReason(rrkFuncCall), Inst(Inst) {
+  ++BadFuncCallForScop;
+}
+
+std::string ReportFuncCall::getMessage() const {
+  return "Call instruction: " + *Inst;
+}
+
+const DebugLoc &ReportFuncCall::getDebugLoc() const {
+  return Inst->getDebugLoc();
+}
+
+std::string ReportFuncCall::getEndUserMessage() const {
+  return "This function call cannot be handeled. "
+         "Try to inline it.";
+}
+
+bool ReportFuncCall::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkFuncCall;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportAlias.
+
+ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
+    : RejectReason(rrkAlias), Inst(Inst), AS(AS) {
+  ++BadAliasForScop;
+}
+
+std::string ReportAlias::formatInvalidAlias(AliasSet &AS) const {
+  std::string Message;
+  raw_string_ostream OS(Message);
+
+  OS << "Possible aliasing: ";
+
+  std::vector<Value *> Pointers;
+
+  for (const auto &I : AS)
+    Pointers.push_back(I.getValue());
+
+  std::sort(Pointers.begin(), Pointers.end());
+
+  for (std::vector<Value *>::iterator PI = Pointers.begin(),
+                                      PE = Pointers.end();
+       ;) {
+    Value *V = *PI;
+
+    if (V->getName().size() == 0)
+      OS << "\"" << *V << "\"";
+    else
+      OS << "\"" << V->getName() << "\"";
+
+    ++PI;
+
+    if (PI != PE)
+      OS << ", ";
+    else
+      break;
+  }
+
+  return OS.str();
+}
+
+std::string ReportAlias::getMessage() const { return formatInvalidAlias(AS); }
+
+const DebugLoc &ReportAlias::getDebugLoc() const { return Inst->getDebugLoc(); }
+
+bool ReportAlias::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkAlias;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportSimpleLoop.
+
+ReportSimpleLoop::ReportSimpleLoop() : RejectReason(rrkSimpleLoop) {
+  ++BadSimpleLoopForScop;
+}
+
+std::string ReportSimpleLoop::getMessage() const {
+  return "Loop not in simplify form is invalid!";
+}
+
+bool ReportSimpleLoop::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkSimpleLoop;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportOther.
+
+std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
+
+ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {
+  ++BadOtherForScop;
+}
+
+bool ReportOther::classof(const RejectReason *RR) {
+  return RR->getKind() >= rrkOther && RR->getKind() <= rrkLastOther;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportIntToPtr.
+ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
+    : ReportOther(rrkIntToPtr), BaseValue(BaseValue) {}
+
+std::string ReportIntToPtr::getMessage() const {
+  return "Find bad intToptr prt: " + *BaseValue;
+}
+
+const DebugLoc &ReportIntToPtr::getDebugLoc() const {
+  return BaseValue->getDebugLoc();
+}
+
+bool ReportIntToPtr::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkIntToPtr;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportAlloca.
+
+ReportAlloca::ReportAlloca(Instruction *Inst)
+    : ReportOther(rrkAlloca), Inst(Inst) {}
+
+std::string ReportAlloca::getMessage() const {
+  return "Alloca instruction: " + *Inst;
+}
+
+const DebugLoc &ReportAlloca::getDebugLoc() const {
+  return Inst->getDebugLoc();
+}
+
+bool ReportAlloca::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkAlloca;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportUnknownInst.
+
+ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
+    : ReportOther(rrkUnknownInst), Inst(Inst) {}
+
+std::string ReportUnknownInst::getMessage() const {
+  return "Unknown instruction: " + *Inst;
+}
+
+const DebugLoc &ReportUnknownInst::getDebugLoc() const {
+  return Inst->getDebugLoc();
+}
+
+bool ReportUnknownInst::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkUnknownInst;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportPHIinExit.
+
+ReportPHIinExit::ReportPHIinExit(Instruction *Inst)
+    : ReportOther(rrkPHIinExit), Inst(Inst) {}
+
+std::string ReportPHIinExit::getMessage() const {
+  return "PHI node in exit BB";
+}
+
+const DebugLoc &ReportPHIinExit::getDebugLoc() const {
+  return Inst->getDebugLoc();
+}
+
+bool ReportPHIinExit::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkPHIinExit;
+}
+
+//===----------------------------------------------------------------------===//
+// ReportEntry.
+ReportEntry::ReportEntry(BasicBlock *BB) : ReportOther(rrkEntry), BB(BB) {}
+
+std::string ReportEntry::getMessage() const {
+  return "Region containing entry block of function is invalid!";
+}
+
+const DebugLoc &ReportEntry::getDebugLoc() const {
+  return BB->getTerminator()->getDebugLoc();
+}
+
+bool ReportEntry::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkEntry;
+}
+} // namespace polly
diff --git a/rc1/lib/Analysis/ScopGraphPrinter.cpp b/rc1/lib/Analysis/ScopGraphPrinter.cpp
new file mode 100644
index 0000000..740e122
--- /dev/null
+++ b/rc1/lib/Analysis/ScopGraphPrinter.cpp
@@ -0,0 +1,206 @@
+//===- 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, reinterpret_cast<RegionNode *>(SD->getRI()->getTopLevelRegion()));
+  }
+
+  static std::string escapeString(std::string String) {
+    std::string Escaped;
+
+    for (const auto &C : String) {
+      if (C == '"')
+        Escaped += '\\';
+
+      Escaped += C;
+    }
+    return Escaped;
+  }
+
+  // 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";
+    std::string ErrorMessage = SD->regionIsInvalidBecause(R);
+    ErrorMessage = escapeString(ErrorMessage);
+    O.indent(2 * (depth + 1)) << "label = \"" << ErrorMessage << "\";\n";
+
+    if (SD->isMaxRegionInScop(*R)) {
+      O.indent(2 * (depth + 1)) << "style = filled;\n";
+
+      // Set color to green.
+      O.indent(2 * (depth + 1)) << "color = 3";
+    } else {
+      O.indent(2 * (depth + 1)) << "style = solid;\n";
+
+      int color = (R->getDepth() * 2 % 12) + 1;
+
+      // We do not want green again.
+      if (color == 3)
+        color = 6;
+
+      O.indent(2 * (depth + 1)) << "color = " << color << "\n";
+    }
+
+    for (const auto &SubRegion : *R)
+      printRegionCluster(SD, SubRegion.get(), O, depth + 1);
+
+    RegionInfo *RI = R->getRegionInfo();
+
+    for (const auto &BB : R->blocks())
+      if (RI->getRegionFor(BB) == R)
+        O.indent(2 * (depth + 1))
+            << "Node"
+            << static_cast<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(); }
diff --git a/rc1/lib/Analysis/ScopInfo.cpp b/rc1/lib/Analysis/ScopInfo.cpp
new file mode 100644
index 0000000..e462c77
--- /dev/null
+++ b/rc1/lib/Analysis/ScopInfo.cpp
@@ -0,0 +1,1480 @@
+//===--------- 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/CodeGen/BlockGenerators.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopInfo.h"
+#include "polly/Options.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/SCEVValidator.h"
+#include "polly/Support/ScopHelper.h"
+#include "polly/TempScopInfo.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Support/Debug.h"
+
+#include "isl/constraint.h"
+#include "isl/set.h"
+#include "isl/map.h"
+#include "isl/union_map.h"
+#include "isl/aff.h"
+#include "isl/printer.h"
+#include "isl/local_space.h"
+#include "isl/options.h"
+#include "isl/val.h"
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-scops"
+
+STATISTIC(ScopFound, "Number of valid Scops");
+STATISTIC(RichScopFound, "Number of Scops containing a loop");
+
+// Multiplicative reductions can be disabled seperately as these kind of
+// operations can overflow easily. Additive reductions and bit operations
+// are in contrast pretty stable.
+static cl::opt<bool> DisableMultiplicativeReductions(
+    "polly-disable-multiplicative-reductions",
+    cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore,
+    cl::init(false), cl::cat(PollyCategory));
+
+/// Translate a 'const SCEV *' expression in an isl_pw_aff.
+struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
+public:
+  /// @brief Translate a 'const SCEV *' to an isl_pw_aff.
+  ///
+  /// @param Stmt The location at which the scalar evolution expression
+  ///             is evaluated.
+  /// @param Expr The expression that is translated.
+  static __isl_give isl_pw_aff *getPwAff(ScopStmt *Stmt, const SCEV *Expr);
+
+private:
+  isl_ctx *Ctx;
+  int NbLoopSpaces;
+  const Scop *S;
+
+  SCEVAffinator(const ScopStmt *Stmt);
+  int getLoopDepth(const Loop *L);
+
+  __isl_give isl_pw_aff *visit(const SCEV *Expr);
+  __isl_give isl_pw_aff *visitConstant(const SCEVConstant *Expr);
+  __isl_give isl_pw_aff *visitTruncateExpr(const SCEVTruncateExpr *Expr);
+  __isl_give isl_pw_aff *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr);
+  __isl_give isl_pw_aff *visitSignExtendExpr(const SCEVSignExtendExpr *Expr);
+  __isl_give isl_pw_aff *visitAddExpr(const SCEVAddExpr *Expr);
+  __isl_give isl_pw_aff *visitMulExpr(const SCEVMulExpr *Expr);
+  __isl_give isl_pw_aff *visitUDivExpr(const SCEVUDivExpr *Expr);
+  __isl_give isl_pw_aff *visitAddRecExpr(const SCEVAddRecExpr *Expr);
+  __isl_give isl_pw_aff *visitSMaxExpr(const SCEVSMaxExpr *Expr);
+  __isl_give isl_pw_aff *visitUMaxExpr(const SCEVUMaxExpr *Expr);
+  __isl_give isl_pw_aff *visitUnknown(const SCEVUnknown *Expr);
+
+  friend struct SCEVVisitor<SCEVAffinator, isl_pw_aff *>;
+};
+
+SCEVAffinator::SCEVAffinator(const ScopStmt *Stmt)
+    : Ctx(Stmt->getIslCtx()), NbLoopSpaces(Stmt->getNumIterators()),
+      S(Stmt->getParent()) {}
+
+__isl_give isl_pw_aff *SCEVAffinator::getPwAff(ScopStmt *Stmt,
+                                               const SCEV *Scev) {
+  Scop *S = Stmt->getParent();
+  const Region *Reg = &S->getRegion();
+
+  S->addParams(getParamsInAffineExpr(Reg, Scev, *S->getSE()));
+
+  SCEVAffinator Affinator(Stmt);
+  return Affinator.visit(Scev);
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visit(const SCEV *Expr) {
+  // In case the scev is a valid parameter, we do not further analyze this
+  // expression, but create a new parameter in the isl_pw_aff. This allows us
+  // to treat subexpressions that we cannot translate into an piecewise affine
+  // expression, as constant parameters of the piecewise affine expression.
+  if (isl_id *Id = S->getIdForParam(Expr)) {
+    isl_space *Space = isl_space_set_alloc(Ctx, 1, NbLoopSpaces);
+    Space = isl_space_set_dim_id(Space, isl_dim_param, 0, Id);
+
+    isl_set *Domain = isl_set_universe(isl_space_copy(Space));
+    isl_aff *Affine = isl_aff_zero_on_domain(isl_local_space_from_space(Space));
+    Affine = isl_aff_add_coefficient_si(Affine, isl_dim_param, 0, 1);
+
+    return isl_pw_aff_alloc(Domain, Affine);
+  }
+
+  return SCEVVisitor<SCEVAffinator, isl_pw_aff *>::visit(Expr);
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitConstant(const SCEVConstant *Expr) {
+  ConstantInt *Value = Expr->getValue();
+  isl_val *v;
+
+  // LLVM does not define if an integer value is interpreted as a signed or
+  // unsigned value. Hence, without further information, it is unknown how
+  // this value needs to be converted to GMP. At the moment, we only support
+  // signed operations. So we just interpret it as signed. Later, there are
+  // two options:
+  //
+  // 1. We always interpret any value as signed and convert the values on
+  //    demand.
+  // 2. We pass down the signedness of the calculation and use it to interpret
+  //    this constant correctly.
+  v = isl_valFromAPInt(Ctx, Value->getValue(), /* isSigned */ true);
+
+  isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
+  isl_local_space *ls = isl_local_space_from_space(isl_space_copy(Space));
+  isl_aff *Affine = isl_aff_zero_on_domain(ls);
+  isl_set *Domain = isl_set_universe(Space);
+
+  Affine = isl_aff_add_constant_val(Affine, v);
+
+  return isl_pw_aff_alloc(Domain, Affine);
+}
+
+__isl_give isl_pw_aff *
+SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+  llvm_unreachable("SCEVTruncateExpr not yet supported");
+}
+
+__isl_give isl_pw_aff *
+SCEVAffinator::visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+  llvm_unreachable("SCEVZeroExtendExpr not yet supported");
+}
+
+__isl_give isl_pw_aff *
+SCEVAffinator::visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+  // Assuming the value is signed, a sign extension is basically a noop.
+  // TODO: Reconsider this as soon as we support unsigned values.
+  return visit(Expr->getOperand());
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitAddExpr(const SCEVAddExpr *Expr) {
+  isl_pw_aff *Sum = visit(Expr->getOperand(0));
+
+  for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
+    isl_pw_aff *NextSummand = visit(Expr->getOperand(i));
+    Sum = isl_pw_aff_add(Sum, NextSummand);
+  }
+
+  // TODO: Check for NSW and NUW.
+
+  return Sum;
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitMulExpr(const SCEVMulExpr *Expr) {
+  isl_pw_aff *Product = visit(Expr->getOperand(0));
+
+  for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
+    isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
+
+    if (!isl_pw_aff_is_cst(Product) && !isl_pw_aff_is_cst(NextOperand)) {
+      isl_pw_aff_free(Product);
+      isl_pw_aff_free(NextOperand);
+      return nullptr;
+    }
+
+    Product = isl_pw_aff_mul(Product, NextOperand);
+  }
+
+  // TODO: Check for NSW and NUW.
+  return Product;
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitUDivExpr(const SCEVUDivExpr *Expr) {
+  llvm_unreachable("SCEVUDivExpr not yet supported");
+}
+
+__isl_give isl_pw_aff *
+SCEVAffinator::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+  assert(Expr->isAffine() && "Only affine AddRecurrences allowed");
+
+  // Directly generate isl_pw_aff for Expr if 'start' is zero.
+  if (Expr->getStart()->isZero()) {
+    assert(S->getRegion().contains(Expr->getLoop()) &&
+           "Scop does not contain the loop referenced in this AddRec");
+
+    isl_pw_aff *Start = visit(Expr->getStart());
+    isl_pw_aff *Step = visit(Expr->getOperand(1));
+    isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
+    isl_local_space *LocalSpace = isl_local_space_from_space(Space);
+
+    int loopDimension = getLoopDepth(Expr->getLoop());
+
+    isl_aff *LAff = isl_aff_set_coefficient_si(
+        isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);
+    isl_pw_aff *LPwAff = isl_pw_aff_from_aff(LAff);
+
+    // TODO: Do we need to check for NSW and NUW?
+    return isl_pw_aff_add(Start, isl_pw_aff_mul(Step, LPwAff));
+  }
+
+  // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
+  // if 'start' is not zero.
+  ScalarEvolution &SE = *S->getSE();
+  const SCEV *ZeroStartExpr = SE.getAddRecExpr(
+      SE.getConstant(Expr->getStart()->getType(), 0),
+      Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
+
+  isl_pw_aff *ZeroStartResult = visit(ZeroStartExpr);
+  isl_pw_aff *Start = visit(Expr->getStart());
+
+  return isl_pw_aff_add(ZeroStartResult, Start);
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+  isl_pw_aff *Max = visit(Expr->getOperand(0));
+
+  for (int i = 1, e = Expr->getNumOperands(); i < e; ++i) {
+    isl_pw_aff *NextOperand = visit(Expr->getOperand(i));
+    Max = isl_pw_aff_max(Max, NextOperand);
+  }
+
+  return Max;
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+  llvm_unreachable("SCEVUMaxExpr not yet supported");
+}
+
+__isl_give isl_pw_aff *SCEVAffinator::visitUnknown(const SCEVUnknown *Expr) {
+  llvm_unreachable("Unknowns are always parameters");
+}
+
+int SCEVAffinator::getLoopDepth(const Loop *L) {
+  Loop *outerLoop = S->getRegion().outermostLoopInRegion(const_cast<Loop *>(L));
+  assert(outerLoop && "Scop does not contain this loop");
+  return L->getLoopDepth() - outerLoop->getLoopDepth();
+}
+
+/// @brief Return the reduction type for a given binary operator
+static MemoryAccess::ReductionType getReductionType(const BinaryOperator *BinOp,
+                                                    const Instruction *Load) {
+  if (!BinOp)
+    return MemoryAccess::RT_NONE;
+  switch (BinOp->getOpcode()) {
+  case Instruction::FAdd:
+    if (!BinOp->hasUnsafeAlgebra())
+      return MemoryAccess::RT_NONE;
+  // Fall through
+  case Instruction::Add:
+    return MemoryAccess::RT_ADD;
+  case Instruction::Or:
+    return MemoryAccess::RT_BOR;
+  case Instruction::Xor:
+    return MemoryAccess::RT_BXOR;
+  case Instruction::And:
+    return MemoryAccess::RT_BAND;
+  case Instruction::FMul:
+    if (!BinOp->hasUnsafeAlgebra())
+      return MemoryAccess::RT_NONE;
+  // Fall through
+  case Instruction::Mul:
+    if (DisableMultiplicativeReductions)
+      return MemoryAccess::RT_NONE;
+    return MemoryAccess::RT_MUL;
+  default:
+    return MemoryAccess::RT_NONE;
+  }
+}
+//===----------------------------------------------------------------------===//
+
+MemoryAccess::~MemoryAccess() {
+  isl_map_free(AccessRelation);
+  isl_map_free(newAccessRelation);
+}
+
+static void replace(std::string &str, const std::string &find,
+                    const std::string &replace) {
+  size_t pos = 0;
+  while ((pos = str.find(find, pos)) != std::string::npos) {
+    str.replace(pos, find.length(), replace);
+    pos += replace.length();
+  }
+}
+
+static void makeIslCompatible(std::string &str) {
+  str.erase(0, 1);
+  replace(str, ".", "_");
+  replace(str, "\"", "_");
+}
+
+void MemoryAccess::setBaseName() {
+  raw_string_ostream OS(BaseName);
+  getBaseAddr()->printAsOperand(OS, false);
+  BaseName = OS.str();
+
+  makeIslCompatible(BaseName);
+  BaseName = "MemRef_" + BaseName;
+}
+
+isl_map *MemoryAccess::getAccessRelation() const {
+  return isl_map_copy(AccessRelation);
+}
+
+std::string MemoryAccess::getAccessRelationStr() const {
+  return stringFromIslObj(AccessRelation);
+}
+
+__isl_give isl_space *MemoryAccess::getAccessRelationSpace() const {
+  return isl_map_get_space(AccessRelation);
+}
+
+isl_map *MemoryAccess::getNewAccessRelation() const {
+  return isl_map_copy(newAccessRelation);
+}
+
+isl_basic_map *MemoryAccess::createBasicAccessMap(ScopStmt *Statement) {
+  isl_space *Space = isl_space_set_alloc(Statement->getIslCtx(), 0, 1);
+  Space = isl_space_set_tuple_name(Space, isl_dim_set, getBaseName().c_str());
+  Space = isl_space_align_params(Space, Statement->getDomainSpace());
+
+  return isl_basic_map_from_domain_and_range(
+      isl_basic_set_universe(Statement->getDomainSpace()),
+      isl_basic_set_universe(Space));
+}
+
+// Formalize no out-of-bound access assumption
+//
+// When delinearizing array accesses we optimistically assume that the
+// delinearized accesses do not access out of bound locations (the subscript
+// expression of each array evaluates for each statement instance that is
+// executed to a value that is larger than zero and strictly smaller than the
+// size of the corresponding dimension). The only exception is the outermost
+// dimension for which we do not assume any upper bound.  At this point we
+// formalize this assumption to ensure that at code generation time the relevant
+// run-time checks can be generated.
+//
+// To find the set of constraints necessary to avoid out of bound accesses, we
+// first build the set of data locations that are not within array bounds. We
+// then apply the reverse access relation to obtain the set of iterations that
+// may contain invalid accesses and reduce this set of iterations to the ones
+// that are actually executed by intersecting them with the domain of the
+// statement. If we now project out all loop dimensions, we obtain a set of
+// parameters that may cause statement instances to be executed that may
+// possibly yield out of bound memory accesses. The complement of these
+// constraints is the set of constraints that needs to be assumed to ensure such
+// statement instances are never executed.
+void MemoryAccess::assumeNoOutOfBound(const IRAccess &Access) {
+  isl_space *Space = isl_space_range(getAccessRelationSpace());
+  isl_set *Outside = isl_set_empty(isl_space_copy(Space));
+  for (int i = 0, Size = Access.Subscripts.size(); i < Size; ++i) {
+    isl_local_space *LS = isl_local_space_from_space(isl_space_copy(Space));
+    isl_pw_aff *Var =
+        isl_pw_aff_var_on_domain(isl_local_space_copy(LS), isl_dim_set, i);
+    isl_pw_aff *Zero = isl_pw_aff_zero_on_domain(LS);
+
+    isl_set *DimOutside;
+
+    if (i == 0) {
+      DimOutside = isl_pw_aff_lt_set(Var, Zero);
+    } else {
+      DimOutside = isl_pw_aff_lt_set(isl_pw_aff_copy(Var), Zero);
+      isl_pw_aff *SizeE =
+          SCEVAffinator::getPwAff(Statement, Access.Sizes[i - 1]);
+
+      SizeE = isl_pw_aff_drop_dims(SizeE, isl_dim_in, 0,
+                                   Statement->getNumIterators());
+      SizeE = isl_pw_aff_add_dims(SizeE, isl_dim_in,
+                                  isl_space_dim(Space, isl_dim_set));
+      SizeE = isl_pw_aff_set_tuple_id(
+          SizeE, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
+
+      DimOutside = isl_set_union(DimOutside, isl_pw_aff_le_set(SizeE, Var));
+    }
+
+    Outside = isl_set_union(Outside, DimOutside);
+  }
+
+  Outside = isl_set_apply(Outside, isl_map_reverse(getAccessRelation()));
+  Outside = isl_set_intersect(Outside, Statement->getDomain());
+  Outside = isl_set_params(Outside);
+  Outside = isl_set_complement(Outside);
+  Statement->getParent()->addAssumption(Outside);
+  isl_space_free(Space);
+}
+
+MemoryAccess::MemoryAccess(const IRAccess &Access, const Instruction *AccInst,
+                           ScopStmt *Statement)
+    : Statement(Statement), Inst(AccInst), newAccessRelation(nullptr) {
+
+  BaseAddr = Access.getBase();
+  setBaseName();
+
+  if (!Access.isAffine()) {
+    // We overapproximate non-affine accesses with a possible access to the
+    // whole array. For read accesses it does not make a difference, if an
+    // access must or may happen. However, for write accesses it is important to
+    // differentiate between writes that must happen and writes that may happen.
+    AccessRelation = isl_map_from_basic_map(createBasicAccessMap(Statement));
+    Type = Access.isRead() ? READ : MAY_WRITE;
+    return;
+  }
+
+  Type = Access.isRead() ? READ : MUST_WRITE;
+
+  isl_space *Space = isl_space_alloc(Statement->getIslCtx(), 0,
+                                     Statement->getNumIterators(), 0);
+  AccessRelation = isl_map_universe(Space);
+
+  for (int i = 0, Size = Access.Subscripts.size(); i < Size; ++i) {
+    isl_pw_aff *Affine =
+        SCEVAffinator::getPwAff(Statement, Access.Subscripts[i]);
+
+    if (Size == 1) {
+      // For the non delinearized arrays, divide the access function of the last
+      // subscript by the size of the elements in the array.
+      //
+      // A stride one array access in C expressed as A[i] is expressed in
+      // LLVM-IR as something like A[i * elementsize]. This hides the fact that
+      // two subsequent values of 'i' index two values that are stored next to
+      // each other in memory. By this division we make this characteristic
+      // obvious again.
+      isl_val *v;
+      v = isl_val_int_from_si(isl_pw_aff_get_ctx(Affine),
+                              Access.getElemSizeInBytes());
+      Affine = isl_pw_aff_scale_down_val(Affine, v);
+    }
+
+    isl_map *SubscriptMap = isl_map_from_pw_aff(Affine);
+
+    AccessRelation = isl_map_flat_range_product(AccessRelation, SubscriptMap);
+  }
+
+  Space = Statement->getDomainSpace();
+  AccessRelation = isl_map_set_tuple_id(
+      AccessRelation, isl_dim_in, isl_space_get_tuple_id(Space, isl_dim_set));
+  isl_space_free(Space);
+  AccessRelation = isl_map_set_tuple_name(AccessRelation, isl_dim_out,
+                                          getBaseName().c_str());
+  assumeNoOutOfBound(Access);
+}
+
+void MemoryAccess::realignParams() {
+  isl_space *ParamSpace = Statement->getParent()->getParamSpace();
+  AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
+}
+
+MemoryAccess::MemoryAccess(const Value *BaseAddress, ScopStmt *Statement)
+    : Type(READ), BaseAddr(BaseAddress), Statement(Statement),
+      newAccessRelation(nullptr) {
+
+  isl_basic_map *BasicAccessMap = createBasicAccessMap(Statement);
+  AccessRelation = isl_map_from_basic_map(BasicAccessMap);
+  isl_space *ParamSpace = Statement->getParent()->getParamSpace();
+  AccessRelation = isl_map_align_params(AccessRelation, ParamSpace);
+}
+
+raw_ostream &polly::operator<<(raw_ostream &OS,
+                               MemoryAccess::ReductionType RT) {
+  switch (RT) {
+  case MemoryAccess::RT_NONE:
+    OS << "NONE";
+    break;
+  case MemoryAccess::RT_ADD:
+    OS << "ADD";
+    break;
+  case MemoryAccess::RT_MUL:
+    OS << "MUL";
+    break;
+  case MemoryAccess::RT_BOR:
+    OS << "BOR";
+    break;
+  case MemoryAccess::RT_BXOR:
+    OS << "BXOR";
+    break;
+  case MemoryAccess::RT_BAND:
+    OS << "BAND";
+    break;
+  }
+  return OS;
+}
+
+void MemoryAccess::print(raw_ostream &OS) const {
+  switch (Type) {
+  case READ:
+    OS.indent(12) << "ReadAccess :=\t";
+    break;
+  case MUST_WRITE:
+    OS.indent(12) << "MustWriteAccess :=\t";
+    break;
+  case MAY_WRITE:
+    OS.indent(12) << "MayWriteAccess :=\t";
+    break;
+  }
+  OS << "[Reduction Type: " << getReductionType() << "]\n";
+  OS.indent(16) << getAccessRelationStr() << ";\n";
+}
+
+void MemoryAccess::dump() const { print(errs()); }
+
+// Create a map in the size of the provided set domain, that maps from the
+// one element of the provided set domain to another element of the provided
+// set domain.
+// The mapping is limited to all points that are equal in all but the last
+// dimension and for which the last dimension of the input is strict smaller
+// than the last dimension of the output.
+//
+//   getEqualAndLarger(set[i0, i1, ..., iX]):
+//
+//   set[i0, i1, ..., iX] -> set[o0, o1, ..., oX]
+//     : i0 = o0, i1 = o1, ..., i(X-1) = o(X-1), iX < oX
+//
+static isl_map *getEqualAndLarger(isl_space *setDomain) {
+  isl_space *Space = isl_space_map_from_set(setDomain);
+  isl_map *Map = isl_map_universe(isl_space_copy(Space));
+  isl_local_space *MapLocalSpace = isl_local_space_from_space(Space);
+  unsigned lastDimension = isl_map_dim(Map, isl_dim_in) - 1;
+
+  // 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 < lastDimension; ++i)
+    Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
+
+  // Set the last dimension of the input to be strict smaller than the
+  // last dimension of the output.
+  //
+  //   input[?,?,?,...,iX] -> output[?,?,?,...,oX] : iX < oX
+  //
+  isl_val *v;
+  isl_ctx *Ctx = isl_map_get_ctx(Map);
+  isl_constraint *c = isl_inequality_alloc(isl_local_space_copy(MapLocalSpace));
+  v = isl_val_int_from_si(Ctx, -1);
+  c = isl_constraint_set_coefficient_val(c, isl_dim_in, lastDimension, v);
+  v = isl_val_int_from_si(Ctx, 1);
+  c = isl_constraint_set_coefficient_val(c, isl_dim_out, lastDimension, v);
+  v = isl_val_int_from_si(Ctx, -1);
+  c = isl_constraint_set_constant_val(c, v);
+
+  Map = isl_map_add_constraint(Map, c);
+
+  isl_local_space_free(MapLocalSpace);
+  return Map;
+}
+
+isl_set *MemoryAccess::getStride(__isl_take const isl_map *Schedule) const {
+  isl_map *S = const_cast<isl_map *>(Schedule);
+  isl_map *AccessRelation = getAccessRelation();
+  isl_space *Space = isl_space_range(isl_map_get_space(S));
+  isl_map *NextScatt = getEqualAndLarger(Space);
+
+  S = isl_map_reverse(S);
+  NextScatt = isl_map_lexmin(NextScatt);
+
+  NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(S));
+  NextScatt = isl_map_apply_range(NextScatt, isl_map_copy(AccessRelation));
+  NextScatt = isl_map_apply_domain(NextScatt, S);
+  NextScatt = isl_map_apply_domain(NextScatt, AccessRelation);
+
+  isl_set *Deltas = isl_map_deltas(NextScatt);
+  return Deltas;
+}
+
+bool MemoryAccess::isStrideX(__isl_take const isl_map *Schedule,
+                             int StrideWidth) const {
+  isl_set *Stride, *StrideX;
+  bool IsStrideX;
+
+  Stride = getStride(Schedule);
+  StrideX = isl_set_universe(isl_set_get_space(Stride));
+  StrideX = isl_set_fix_si(StrideX, isl_dim_set, 0, StrideWidth);
+  IsStrideX = isl_set_is_equal(Stride, StrideX);
+
+  isl_set_free(StrideX);
+  isl_set_free(Stride);
+
+  return IsStrideX;
+}
+
+bool MemoryAccess::isStrideZero(const isl_map *Schedule) const {
+  return isStrideX(Schedule, 0);
+}
+
+bool MemoryAccess::isScalar() const {
+  return isl_map_n_out(AccessRelation) == 0;
+}
+
+bool MemoryAccess::isStrideOne(const isl_map *Schedule) const {
+  return isStrideX(Schedule, 1);
+}
+
+void MemoryAccess::setNewAccessRelation(isl_map *newAccess) {
+  isl_map_free(newAccessRelation);
+  newAccessRelation = newAccess;
+}
+
+//===----------------------------------------------------------------------===//
+
+isl_map *ScopStmt::getScattering() const { return isl_map_copy(Scattering); }
+
+void ScopStmt::restrictDomain(__isl_take isl_set *NewDomain) {
+  assert(isl_set_is_subset(NewDomain, Domain) &&
+         "New domain is not a subset of old domain!");
+  isl_set_free(Domain);
+  Domain = NewDomain;
+  Scattering = isl_map_intersect_domain(Scattering, isl_set_copy(Domain));
+}
+
+void ScopStmt::setScattering(isl_map *NewScattering) {
+  assert(NewScattering && "New scattering is nullptr");
+  isl_map_free(Scattering);
+  Scattering = NewScattering;
+}
+
+void ScopStmt::buildScattering(SmallVectorImpl<unsigned> &Scatter) {
+  unsigned NbIterators = getNumIterators();
+  unsigned NbScatteringDims = Parent.getMaxLoopDepth() * 2 + 1;
+
+  isl_space *Space = isl_space_set_alloc(getIslCtx(), 0, NbScatteringDims);
+  Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering");
+
+  Scattering = isl_map_from_domain_and_range(isl_set_universe(getDomainSpace()),
+                                             isl_set_universe(Space));
+
+  // Loop dimensions.
+  for (unsigned i = 0; i < NbIterators; ++i)
+    Scattering =
+        isl_map_equate(Scattering, isl_dim_out, 2 * i + 1, isl_dim_in, i);
+
+  // Constant dimensions
+  for (unsigned i = 0; i < NbIterators + 1; ++i)
+    Scattering = isl_map_fix_si(Scattering, isl_dim_out, 2 * i, Scatter[i]);
+
+  // Fill scattering dimensions.
+  for (unsigned i = 2 * NbIterators + 1; i < NbScatteringDims; ++i)
+    Scattering = isl_map_fix_si(Scattering, isl_dim_out, i, 0);
+
+  Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
+}
+
+void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) {
+  for (auto &&Access : *tempScop.getAccessFunctions(BB)) {
+    MemAccs.push_back(new MemoryAccess(Access.first, Access.second, this));
+
+    // We do not track locations for scalar memory accesses at the moment.
+    //
+    // We do not have a use for this information at the moment. If we need this
+    // at some point, the "instruction -> access" mapping needs to be enhanced
+    // as a single instruction could then possibly perform multiple accesses.
+    if (!Access.first.isScalar()) {
+      assert(!InstructionToAccess.count(Access.second) &&
+             "Unexpected 1-to-N mapping on instruction to access map!");
+      InstructionToAccess[Access.second] = MemAccs.back();
+    }
+  }
+}
+
+void ScopStmt::realignParams() {
+  for (MemoryAccess *MA : *this)
+    MA->realignParams();
+
+  Domain = isl_set_align_params(Domain, Parent.getParamSpace());
+  Scattering = isl_map_align_params(Scattering, Parent.getParamSpace());
+}
+
+__isl_give isl_set *ScopStmt::buildConditionSet(const Comparison &Comp) {
+  isl_pw_aff *L = SCEVAffinator::getPwAff(this, Comp.getLHS());
+  isl_pw_aff *R = SCEVAffinator::getPwAff(this, Comp.getRHS());
+
+  switch (Comp.getPred()) {
+  case ICmpInst::ICMP_EQ:
+    return isl_pw_aff_eq_set(L, R);
+  case ICmpInst::ICMP_NE:
+    return isl_pw_aff_ne_set(L, R);
+  case ICmpInst::ICMP_SLT:
+    return isl_pw_aff_lt_set(L, R);
+  case ICmpInst::ICMP_SLE:
+    return isl_pw_aff_le_set(L, R);
+  case ICmpInst::ICMP_SGT:
+    return isl_pw_aff_gt_set(L, R);
+  case ICmpInst::ICMP_SGE:
+    return isl_pw_aff_ge_set(L, R);
+  case ICmpInst::ICMP_ULT:
+  case ICmpInst::ICMP_UGT:
+  case ICmpInst::ICMP_ULE:
+  case ICmpInst::ICMP_UGE:
+    llvm_unreachable("Unsigned comparisons not yet supported");
+  default:
+    llvm_unreachable("Non integer predicate not supported");
+  }
+}
+
+__isl_give isl_set *ScopStmt::addLoopBoundsToDomain(__isl_take isl_set *Domain,
+                                                    TempScop &tempScop) {
+  isl_space *Space;
+  isl_local_space *LocalSpace;
+
+  Space = isl_set_get_space(Domain);
+  LocalSpace = isl_local_space_from_space(Space);
+
+  for (int i = 0, e = getNumIterators(); i != e; ++i) {
+    isl_aff *Zero = isl_aff_zero_on_domain(isl_local_space_copy(LocalSpace));
+    isl_pw_aff *IV =
+        isl_pw_aff_from_aff(isl_aff_set_coefficient_si(Zero, isl_dim_in, i, 1));
+
+    // 0 <= IV.
+    isl_set *LowerBound = isl_pw_aff_nonneg_set(isl_pw_aff_copy(IV));
+    Domain = isl_set_intersect(Domain, LowerBound);
+
+    // IV <= LatchExecutions.
+    const Loop *L = getLoopForDimension(i);
+    const SCEV *LatchExecutions = tempScop.getLoopBound(L);
+    isl_pw_aff *UpperBound = SCEVAffinator::getPwAff(this, LatchExecutions);
+    isl_set *UpperBoundSet = isl_pw_aff_le_set(IV, UpperBound);
+    Domain = isl_set_intersect(Domain, UpperBoundSet);
+  }
+
+  isl_local_space_free(LocalSpace);
+  return Domain;
+}
+
+__isl_give isl_set *ScopStmt::addConditionsToDomain(__isl_take isl_set *Domain,
+                                                    TempScop &tempScop,
+                                                    const Region &CurRegion) {
+  const Region *TopRegion = tempScop.getMaxRegion().getParent(),
+               *CurrentRegion = &CurRegion;
+  const BasicBlock *BranchingBB = BB;
+
+  do {
+    if (BranchingBB != CurrentRegion->getEntry()) {
+      if (const BBCond *Condition = tempScop.getBBCond(BranchingBB))
+        for (const auto &C : *Condition) {
+          isl_set *ConditionSet = buildConditionSet(C);
+          Domain = isl_set_intersect(Domain, ConditionSet);
+        }
+    }
+    BranchingBB = CurrentRegion->getEntry();
+    CurrentRegion = CurrentRegion->getParent();
+  } while (TopRegion != CurrentRegion);
+
+  return Domain;
+}
+
+__isl_give isl_set *ScopStmt::buildDomain(TempScop &tempScop,
+                                          const Region &CurRegion) {
+  isl_space *Space;
+  isl_set *Domain;
+  isl_id *Id;
+
+  Space = isl_space_set_alloc(getIslCtx(), 0, getNumIterators());
+
+  Id = isl_id_alloc(getIslCtx(), getBaseName(), this);
+
+  Domain = isl_set_universe(Space);
+  Domain = addLoopBoundsToDomain(Domain, tempScop);
+  Domain = addConditionsToDomain(Domain, tempScop, CurRegion);
+  Domain = isl_set_set_tuple_id(Domain, Id);
+
+  return Domain;
+}
+
+ScopStmt::ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
+                   BasicBlock &bb, SmallVectorImpl<Loop *> &Nest,
+                   SmallVectorImpl<unsigned> &Scatter)
+    : Parent(parent), BB(&bb), IVS(Nest.size()), NestLoops(Nest.size()) {
+  // Setup the induction variables.
+  for (unsigned i = 0, e = Nest.size(); i < e; ++i) {
+    if (!SCEVCodegen) {
+      PHINode *PN = Nest[i]->getCanonicalInductionVariable();
+      assert(PN && "Non canonical IV in Scop!");
+      IVS[i] = PN;
+    }
+    NestLoops[i] = Nest[i];
+  }
+
+  raw_string_ostream OS(BaseName);
+  bb.printAsOperand(OS, false);
+  BaseName = OS.str();
+
+  makeIslCompatible(BaseName);
+  BaseName = "Stmt_" + BaseName;
+
+  Domain = buildDomain(tempScop, CurRegion);
+  buildScattering(Scatter);
+  buildAccesses(tempScop, CurRegion);
+  checkForReductions();
+}
+
+/// @brief Collect loads which might form a reduction chain with @p StoreMA
+///
+/// Check if the stored value for @p StoreMA is a binary operator with one or
+/// two loads as operands. If the binary operand is commutative & associative,
+/// used only once (by @p StoreMA) and its load operands are also used only
+/// once, we have found a possible reduction chain. It starts at an operand
+/// load and includes the binary operator and @p StoreMA.
+///
+/// Note: We allow only one use to ensure the load and binary operator cannot
+///       escape this block or into any other store except @p StoreMA.
+void ScopStmt::collectCandiateReductionLoads(
+    MemoryAccess *StoreMA, SmallVectorImpl<MemoryAccess *> &Loads) {
+  auto *Store = dyn_cast<StoreInst>(StoreMA->getAccessInstruction());
+  if (!Store)
+    return;
+
+  // Skip if there is not one binary operator between the load and the store
+  auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand());
+  if (!BinOp)
+    return;
+
+  // Skip if the binary operators has multiple uses
+  if (BinOp->getNumUses() != 1)
+    return;
+
+  // Skip if the opcode of the binary operator is not commutative/associative
+  if (!BinOp->isCommutative() || !BinOp->isAssociative())
+    return;
+
+  // Skip if the binary operator is outside the current SCoP
+  if (BinOp->getParent() != Store->getParent())
+    return;
+
+  // Skip if it is a multiplicative reduction and we disabled them
+  if (DisableMultiplicativeReductions &&
+      (BinOp->getOpcode() == Instruction::Mul ||
+       BinOp->getOpcode() == Instruction::FMul))
+    return;
+
+  // Check the binary operator operands for a candidate load
+  auto *PossibleLoad0 = dyn_cast<LoadInst>(BinOp->getOperand(0));
+  auto *PossibleLoad1 = dyn_cast<LoadInst>(BinOp->getOperand(1));
+  if (!PossibleLoad0 && !PossibleLoad1)
+    return;
+
+  // A load is only a candidate if it cannot escape (thus has only this use)
+  if (PossibleLoad0 && PossibleLoad0->getNumUses() == 1)
+    if (PossibleLoad0->getParent() == Store->getParent())
+      Loads.push_back(lookupAccessFor(PossibleLoad0));
+  if (PossibleLoad1 && PossibleLoad1->getNumUses() == 1)
+    if (PossibleLoad1->getParent() == Store->getParent())
+      Loads.push_back(lookupAccessFor(PossibleLoad1));
+}
+
+/// @brief Check for reductions in this ScopStmt
+///
+/// Iterate over all store memory accesses and check for valid binary reduction
+/// like chains. For all candidates we check if they have the same base address
+/// and there are no other accesses which overlap with them. The base address
+/// check rules out impossible reductions candidates early. The overlap check,
+/// together with the "only one user" check in collectCandiateReductionLoads,
+/// guarantees that none of the intermediate results will escape during
+/// execution of the loop nest. We basically check here that no other memory
+/// access can access the same memory as the potential reduction.
+void ScopStmt::checkForReductions() {
+  SmallVector<MemoryAccess *, 2> Loads;
+  SmallVector<std::pair<MemoryAccess *, MemoryAccess *>, 4> Candidates;
+
+  // First collect candidate load-store reduction chains by iterating over all
+  // stores and collecting possible reduction loads.
+  for (MemoryAccess *StoreMA : MemAccs) {
+    if (StoreMA->isRead())
+      continue;
+
+    Loads.clear();
+    collectCandiateReductionLoads(StoreMA, Loads);
+    for (MemoryAccess *LoadMA : Loads)
+      Candidates.push_back(std::make_pair(LoadMA, StoreMA));
+  }
+
+  // Then check each possible candidate pair.
+  for (const auto &CandidatePair : Candidates) {
+    bool Valid = true;
+    isl_map *LoadAccs = CandidatePair.first->getAccessRelation();
+    isl_map *StoreAccs = CandidatePair.second->getAccessRelation();
+
+    // Skip those with obviously unequal base addresses.
+    if (!isl_map_has_equal_space(LoadAccs, StoreAccs)) {
+      isl_map_free(LoadAccs);
+      isl_map_free(StoreAccs);
+      continue;
+    }
+
+    // And check if the remaining for overlap with other memory accesses.
+    isl_map *AllAccsRel = isl_map_union(LoadAccs, StoreAccs);
+    AllAccsRel = isl_map_intersect_domain(AllAccsRel, getDomain());
+    isl_set *AllAccs = isl_map_range(AllAccsRel);
+
+    for (MemoryAccess *MA : MemAccs) {
+      if (MA == CandidatePair.first || MA == CandidatePair.second)
+        continue;
+
+      isl_map *AccRel =
+          isl_map_intersect_domain(MA->getAccessRelation(), getDomain());
+      isl_set *Accs = isl_map_range(AccRel);
+
+      if (isl_set_has_equal_space(AllAccs, Accs) || isl_set_free(Accs)) {
+        isl_set *OverlapAccs = isl_set_intersect(Accs, isl_set_copy(AllAccs));
+        Valid = Valid && isl_set_is_empty(OverlapAccs);
+        isl_set_free(OverlapAccs);
+      }
+    }
+
+    isl_set_free(AllAccs);
+    if (!Valid)
+      continue;
+
+    const LoadInst *Load =
+        dyn_cast<const LoadInst>(CandidatePair.first->getAccessInstruction());
+    MemoryAccess::ReductionType RT =
+        getReductionType(dyn_cast<BinaryOperator>(Load->user_back()), Load);
+
+    // If no overlapping access was found we mark the load and store as
+    // reduction like.
+    CandidatePair.first->markAsReductionLike(RT);
+    CandidatePair.second->markAsReductionLike(RT);
+  }
+}
+
+std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
+
+std::string ScopStmt::getScatteringStr() const {
+  return stringFromIslObj(Scattering);
+}
+
+unsigned ScopStmt::getNumParams() const { return Parent.getNumParams(); }
+
+unsigned ScopStmt::getNumIterators() const {
+  // The final read has one dimension with one element.
+  if (!BB)
+    return 1;
+
+  return NestLoops.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 Loop *ScopStmt::getLoopForDimension(unsigned Dimension) const {
+  return NestLoops[Dimension];
+}
+
+isl_ctx *ScopStmt::getIslCtx() const { return Parent.getIslCtx(); }
+
+isl_set *ScopStmt::getDomain() const { return isl_set_copy(Domain); }
+
+isl_space *ScopStmt::getDomainSpace() const {
+  return isl_set_get_space(Domain);
+}
+
+isl_id *ScopStmt::getDomainId() const { return isl_set_get_tuple_id(Domain); }
+
+ScopStmt::~ScopStmt() {
+  while (!MemAccs.empty()) {
+    delete MemAccs.back();
+    MemAccs.pop_back();
+  }
+
+  isl_set_free(Domain);
+  isl_map_free(Scattering);
+}
+
+void ScopStmt::print(raw_ostream &OS) const {
+  OS << "\t" << getBaseName() << "\n";
+  OS.indent(12) << "Domain :=\n";
+
+  if (Domain) {
+    OS.indent(16) << getDomainStr() << ";\n";
+  } else
+    OS.indent(16) << "n/a\n";
+
+  OS.indent(12) << "Scattering :=\n";
+
+  if (Domain) {
+    OS.indent(16) << getScatteringStr() << ";\n";
+  } else
+    OS.indent(16) << "n/a\n";
+
+  for (MemoryAccess *Access : MemAccs)
+    Access->print(OS);
+}
+
+void ScopStmt::dump() const { print(dbgs()); }
+
+//===----------------------------------------------------------------------===//
+/// Scop class implement
+
+void Scop::setContext(__isl_take isl_set *NewContext) {
+  NewContext = isl_set_align_params(NewContext, isl_set_get_space(Context));
+  isl_set_free(Context);
+  Context = NewContext;
+}
+
+void Scop::addParams(std::vector<const SCEV *> NewParameters) {
+  for (const SCEV *Parameter : NewParameters) {
+    if (ParameterIds.find(Parameter) != ParameterIds.end())
+      continue;
+
+    int dimension = Parameters.size();
+
+    Parameters.push_back(Parameter);
+    ParameterIds[Parameter] = dimension;
+  }
+}
+
+__isl_give isl_id *Scop::getIdForParam(const SCEV *Parameter) const {
+  ParamIdType::const_iterator IdIter = ParameterIds.find(Parameter);
+
+  if (IdIter == ParameterIds.end())
+    return nullptr;
+
+  std::string ParameterName;
+
+  if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
+    Value *Val = ValueParameter->getValue();
+    ParameterName = Val->getName();
+  }
+
+  if (ParameterName == "" || ParameterName.substr(0, 2) == "p_")
+    ParameterName = "p_" + utostr_32(IdIter->second);
+
+  return isl_id_alloc(getIslCtx(), ParameterName.c_str(),
+                      const_cast<void *>((const void *)Parameter));
+}
+
+void Scop::buildContext() {
+  isl_space *Space = isl_space_params_alloc(IslCtx, 0);
+  Context = isl_set_universe(isl_space_copy(Space));
+  AssumedContext = isl_set_universe(Space);
+}
+
+void Scop::addParameterBounds() {
+  for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
+    isl_val *V;
+    isl_id *Id;
+    const SCEV *Scev;
+    const IntegerType *T;
+
+    Id = isl_set_get_dim_id(Context, isl_dim_param, i);
+    Scev = (const SCEV *)isl_id_get_user(Id);
+    T = dyn_cast<IntegerType>(Scev->getType());
+    isl_id_free(Id);
+
+    assert(T && "Not an integer type");
+    int Width = T->getBitWidth();
+
+    V = isl_val_int_from_si(IslCtx, Width - 1);
+    V = isl_val_2exp(V);
+    V = isl_val_neg(V);
+    Context = isl_set_lower_bound_val(Context, isl_dim_param, i, V);
+
+    V = isl_val_int_from_si(IslCtx, Width - 1);
+    V = isl_val_2exp(V);
+    V = isl_val_sub_ui(V, 1);
+    Context = isl_set_upper_bound_val(Context, isl_dim_param, i, V);
+  }
+}
+
+void Scop::realignParams() {
+  // Add all parameters into a common model.
+  isl_space *Space = isl_space_params_alloc(IslCtx, ParameterIds.size());
+
+  for (const auto &ParamID : ParameterIds) {
+    const SCEV *Parameter = ParamID.first;
+    isl_id *id = getIdForParam(Parameter);
+    Space = isl_space_set_dim_id(Space, isl_dim_param, ParamID.second, id);
+  }
+
+  // Align the parameters of all data structures to the model.
+  Context = isl_set_align_params(Context, Space);
+
+  for (ScopStmt *Stmt : *this)
+    Stmt->realignParams();
+}
+
+void Scop::simplifyAssumedContext() {
+  // The parameter constraints of the iteration domains give us a set of
+  // constraints that need to hold for all cases where at least a single
+  // statement iteration is executed in the whole scop. We now simplify the
+  // assumed context under the assumption that such constraints hold and at
+  // least a single statement iteration is executed. For cases where no
+  // statement instances are executed, the assumptions we have taken about
+  // the executed code do not matter and can be changed.
+  //
+  // WARNING: This only holds if the assumptions we have taken do not reduce
+  //          the set of statement instances that are executed. Otherwise we
+  //          may run into a case where the iteration domains suggest that
+  //          for a certain set of parameter constraints no code is executed,
+  //          but in the original program some computation would have been
+  //          performed. In such a case, modifying the run-time conditions and
+  //          possibly influencing the run-time check may cause certain scops
+  //          to not be executed.
+  //
+  // Example:
+  //
+  //   When delinearizing the following code:
+  //
+  //     for (long i = 0; i < 100; i++)
+  //       for (long j = 0; j < m; j++)
+  //         A[i+p][j] = 1.0;
+  //
+  //   we assume that the condition m <= 0 or (m >= 1 and p >= 0) holds as
+  //   otherwise we would access out of bound data. Now, knowing that code is
+  //   only executed for the case m >= 0, it is sufficient to assume p >= 0.
+  AssumedContext =
+      isl_set_gist_params(AssumedContext, isl_union_set_params(getDomains()));
+}
+
+Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution,
+           isl_ctx *Context)
+    : SE(&ScalarEvolution), R(tempScop.getMaxRegion()),
+      MaxLoopDepth(tempScop.getMaxLoopDepth()) {
+  IslCtx = Context;
+  buildContext();
+
+  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);
+
+  realignParams();
+  addParameterBounds();
+  simplifyAssumedContext();
+
+  assert(NestLoops.empty() && "NestLoops not empty at top level!");
+}
+
+Scop::~Scop() {
+  isl_set_free(Context);
+  isl_set_free(AssumedContext);
+
+  // Free the statements;
+  for (ScopStmt *Stmt : *this)
+    delete Stmt;
+}
+
+std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
+std::string Scop::getAssumedContextStr() const {
+  return stringFromIslObj(AssumedContext);
+}
+
+std::string Scop::getNameStr() const {
+  std::string ExitName, EntryName;
+  raw_string_ostream ExitStr(ExitName);
+  raw_string_ostream EntryStr(EntryName);
+
+  R.getEntry()->printAsOperand(EntryStr, false);
+  EntryStr.str();
+
+  if (R.getExit()) {
+    R.getExit()->printAsOperand(ExitStr, false);
+    ExitStr.str();
+  } else
+    ExitName = "FunctionExit";
+
+  return EntryName + "---" + ExitName;
+}
+
+__isl_give isl_set *Scop::getContext() const { return isl_set_copy(Context); }
+__isl_give isl_space *Scop::getParamSpace() const {
+  return isl_set_get_space(this->Context);
+}
+
+__isl_give isl_set *Scop::getAssumedContext() const {
+  return isl_set_copy(AssumedContext);
+}
+
+void Scop::addAssumption(__isl_take isl_set *Set) {
+  AssumedContext = isl_set_intersect(AssumedContext, Set);
+}
+
+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";
+
+  OS.indent(4) << "Assumed Context:\n";
+  if (!AssumedContext) {
+    OS.indent(4) << "n/a\n\n";
+    return;
+  }
+
+  OS.indent(4) << getAssumedContextStr() << "\n";
+
+  for (const SCEV *Parameter : Parameters) {
+    int Dim = ParameterIds.find(Parameter)->second;
+    OS.indent(4) << "p" << Dim << ": " << *Parameter << "\n";
+  }
+}
+
+void Scop::printStatements(raw_ostream &OS) const {
+  OS << "Statements {\n";
+
+  for (ScopStmt *Stmt : *this)
+    OS.indent(4) << *Stmt;
+
+  OS.indent(4) << "}\n";
+}
+
+void Scop::print(raw_ostream &OS) const {
+  OS.indent(4) << "Function: " << getRegion().getEntry()->getParent()->getName()
+               << "\n";
+  OS.indent(4) << "Region: " << getNameStr() << "\n";
+  printContext(OS.indent(4));
+  printStatements(OS.indent(4));
+}
+
+void Scop::dump() const { print(dbgs()); }
+
+isl_ctx *Scop::getIslCtx() const { return IslCtx; }
+
+__isl_give isl_union_set *Scop::getDomains() {
+  isl_union_set *Domain = isl_union_set_empty(getParamSpace());
+
+  for (ScopStmt *Stmt : *this)
+    Domain = isl_union_set_add_set(Domain, Stmt->getDomain());
+
+  return Domain;
+}
+
+__isl_give isl_union_map *Scop::getMustWrites() {
+  isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
+
+  for (ScopStmt *Stmt : *this) {
+    for (MemoryAccess *MA : *Stmt) {
+      if (!MA->isMustWrite())
+        continue;
+
+      isl_set *Domain = Stmt->getDomain();
+      isl_map *AccessDomain = MA->getAccessRelation();
+      AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
+      Write = isl_union_map_add_map(Write, AccessDomain);
+    }
+  }
+  return isl_union_map_coalesce(Write);
+}
+
+__isl_give isl_union_map *Scop::getMayWrites() {
+  isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
+
+  for (ScopStmt *Stmt : *this) {
+    for (MemoryAccess *MA : *Stmt) {
+      if (!MA->isMayWrite())
+        continue;
+
+      isl_set *Domain = Stmt->getDomain();
+      isl_map *AccessDomain = MA->getAccessRelation();
+      AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
+      Write = isl_union_map_add_map(Write, AccessDomain);
+    }
+  }
+  return isl_union_map_coalesce(Write);
+}
+
+__isl_give isl_union_map *Scop::getWrites() {
+  isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
+
+  for (ScopStmt *Stmt : *this) {
+    for (MemoryAccess *MA : *Stmt) {
+      if (!MA->isWrite())
+        continue;
+
+      isl_set *Domain = Stmt->getDomain();
+      isl_map *AccessDomain = MA->getAccessRelation();
+      AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
+      Write = isl_union_map_add_map(Write, AccessDomain);
+    }
+  }
+  return isl_union_map_coalesce(Write);
+}
+
+__isl_give isl_union_map *Scop::getReads() {
+  isl_union_map *Read = isl_union_map_empty(getParamSpace());
+
+  for (ScopStmt *Stmt : *this) {
+    for (MemoryAccess *MA : *Stmt) {
+      if (!MA->isRead())
+        continue;
+
+      isl_set *Domain = Stmt->getDomain();
+      isl_map *AccessDomain = MA->getAccessRelation();
+
+      AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
+      Read = isl_union_map_add_map(Read, AccessDomain);
+    }
+  }
+  return isl_union_map_coalesce(Read);
+}
+
+__isl_give isl_union_map *Scop::getSchedule() {
+  isl_union_map *Schedule = isl_union_map_empty(getParamSpace());
+
+  for (ScopStmt *Stmt : *this)
+    Schedule = isl_union_map_add_map(Schedule, Stmt->getScattering());
+
+  return isl_union_map_coalesce(Schedule);
+}
+
+bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
+  bool Changed = false;
+  for (ScopStmt *Stmt : *this) {
+    isl_union_set *StmtDomain = isl_union_set_from_set(Stmt->getDomain());
+    isl_union_set *NewStmtDomain = isl_union_set_intersect(
+        isl_union_set_copy(StmtDomain), isl_union_set_copy(Domain));
+
+    if (isl_union_set_is_subset(StmtDomain, NewStmtDomain)) {
+      isl_union_set_free(StmtDomain);
+      isl_union_set_free(NewStmtDomain);
+      continue;
+    }
+
+    Changed = true;
+
+    isl_union_set_free(StmtDomain);
+    NewStmtDomain = isl_union_set_coalesce(NewStmtDomain);
+
+    if (isl_union_set_is_empty(NewStmtDomain)) {
+      Stmt->restrictDomain(isl_set_empty(Stmt->getDomainSpace()));
+      isl_union_set_free(NewStmtDomain);
+    } else
+      Stmt->restrictDomain(isl_set_from_union_set(NewStmtDomain));
+  }
+  isl_union_set_free(Domain);
+  return Changed;
+}
+
+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];
+}
+
+//===----------------------------------------------------------------------===//
+ScopInfo::ScopInfo() : RegionPass(ID), scop(0) {
+  ctx = isl_ctx_alloc();
+  isl_options_set_on_error(ctx, ISL_ON_ERROR_ABORT);
+}
+
+ScopInfo::~ScopInfo() {
+  clear();
+  isl_ctx_free(ctx);
+}
+
+void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<LoopInfo>();
+  AU.addRequired<RegionInfoPass>();
+  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, ctx);
+
+  return false;
+}
+
+char ScopInfo::ID = 0;
+
+Pass *polly::createScopInfoPass() { return new ScopInfo(); }
+
+INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops",
+                      "Polly - Create polyhedral description of Scops", false,
+                      false);
+INITIALIZE_PASS_DEPENDENCY(LoopInfo);
+INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
+INITIALIZE_PASS_DEPENDENCY(TempScopInfo);
+INITIALIZE_PASS_END(ScopInfo, "polly-scops",
+                    "Polly - Create polyhedral description of Scops", false,
+                    false)
diff --git a/rc1/lib/Analysis/ScopPass.cpp b/rc1/lib/Analysis/ScopPass.cpp
new file mode 100644
index 0000000..217feab
--- /dev/null
+++ b/rc1/lib/Analysis/ScopPass.cpp
@@ -0,0 +1,37 @@
+//===- 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;
+}
+
+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();
+}
diff --git a/rc1/lib/Analysis/TempScopInfo.cpp b/rc1/lib/Analysis/TempScopInfo.cpp
new file mode 100644
index 0000000..5dd3423
--- /dev/null
+++ b/rc1/lib/Analysis/TempScopInfo.cpp
@@ -0,0 +1,404 @@
+//===---------- 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/ScopDetection.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/CodeGen/BlockGenerators.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/SCEVValidator.h"
+#include "polly/Support/ScopHelper.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/RegionIterator.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-analyze-ir"
+
+//===----------------------------------------------------------------------===//
+/// Helper Classes
+
+void IRAccess::print(raw_ostream &OS) const {
+  if (isRead())
+    OS << "Read ";
+  else
+    OS << "Write ";
+
+  OS << BaseAddress->getName() << '[' << *Offset << "]\n";
+}
+
+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() {}
+
+void TempScop::print(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI) const {
+  OS << "Scop: " << R.getNameStr() << ", Max Loop Depth: " << MaxLoopDepth
+     << "\n";
+
+  printDetail(OS, SE, LI, &R, 0);
+}
+
+void TempScop::printDetail(raw_ostream &OS, ScalarEvolution *SE, LoopInfo *LI,
+                           const Region *CurR, unsigned ind) const {
+  // FIXME: Print other details rather than memory accesses.
+  for (const auto &CurBlock : CurR->blocks()) {
+    AccFuncMapType::const_iterator AccSetIt = AccFuncMap.find(CurBlock);
+
+    // Ignore trivial blocks that do not contain any memory access.
+    if (AccSetIt == AccFuncMap.end())
+      continue;
+
+    OS.indent(ind) << "BB: " << CurBlock->getName() << '\n';
+    typedef AccFuncSetType::const_iterator access_iterator;
+    const AccFuncSetType &AccFuncs = AccSetIt->second;
+
+    for (access_iterator AI = AccFuncs.begin(), AE = AccFuncs.end(); AI != AE;
+         ++AI)
+      AI->first.print(OS.indent(ind + 2));
+  }
+}
+
+bool TempScopInfo::buildScalarDependences(Instruction *Inst, Region *R) {
+  // No need to translate these scalar dependences into polyhedral form, because
+  // synthesizable scalars can be generated by the code generator.
+  if (canSynthesize(Inst, LI, SE, R))
+    return false;
+
+  bool AnyCrossStmtUse = false;
+  BasicBlock *ParentBB = Inst->getParent();
+
+  for (User *U : Inst->users()) {
+    Instruction *UI = dyn_cast<Instruction>(U);
+
+    // Ignore the strange user
+    if (UI == 0)
+      continue;
+
+    BasicBlock *UseParent = UI->getParent();
+
+    // Ignore the users in the same BB (statement)
+    if (UseParent == ParentBB)
+      continue;
+
+    // No need to translate these scalar dependences into polyhedral form,
+    // because synthesizable scalars can be generated by the code generator.
+    if (canSynthesize(UI, LI, SE, R))
+      continue;
+
+    // Now U is used in another statement.
+    AnyCrossStmtUse = true;
+
+    // Do not build a read access that is not in the current SCoP
+    if (!R->contains(UseParent))
+      continue;
+
+    assert(!isa<PHINode>(UI) && "Non synthesizable PHINode found in a SCoP!");
+
+    SmallVector<const SCEV *, 4> Subscripts, Sizes;
+
+    // Use the def instruction as base address of the IRAccess, so that it will
+    // become the name of the scalar access in the polyhedral form.
+    IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true, Subscripts,
+                          Sizes);
+    AccFuncMap[UseParent].push_back(std::make_pair(ScalarAccess, UI));
+  }
+
+  return AnyCrossStmtUse;
+}
+
+extern MapInsnToMemAcc InsnToMemAcc;
+
+IRAccess TempScopInfo::buildIRAccess(Instruction *Inst, Loop *L, Region *R) {
+  unsigned Size;
+  Type *SizeType;
+  enum IRAccess::TypeKind Type;
+
+  if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
+    SizeType = Load->getType();
+    Size = TD->getTypeStoreSize(SizeType);
+    Type = IRAccess::READ;
+  } else {
+    StoreInst *Store = cast<StoreInst>(Inst);
+    SizeType = Store->getValueOperand()->getType();
+    Size = TD->getTypeStoreSize(SizeType);
+    Type = IRAccess::WRITE;
+  }
+
+  const SCEV *AccessFunction = SE->getSCEVAtScope(getPointerOperand(*Inst), L);
+  const SCEVUnknown *BasePointer =
+      dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));
+
+  assert(BasePointer && "Could not find base pointer");
+  AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
+  SmallVector<const SCEV *, 4> Subscripts, Sizes;
+
+  MemAcc *Acc = InsnToMemAcc[Inst];
+  if (PollyDelinearize && Acc)
+    return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, true,
+                    Acc->DelinearizedSubscripts, Acc->Shape->DelinearizedSizes);
+
+  bool IsAffine = isAffineExpr(R, AccessFunction, *SE, BasePointer->getValue());
+  Subscripts.push_back(AccessFunction);
+  Sizes.push_back(SE->getConstant(ZeroOffset->getType(), Size));
+  return IRAccess(Type, BasePointer->getValue(), AccessFunction, Size, IsAffine,
+                  Subscripts, Sizes);
+}
+
+void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB) {
+  AccFuncSetType Functions;
+  Loop *L = LI->getLoopFor(&BB);
+
+  for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) {
+    Instruction *Inst = I;
+    if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
+      Functions.push_back(std::make_pair(buildIRAccess(Inst, L, &R), Inst));
+
+    if (!isa<StoreInst>(Inst) && buildScalarDependences(Inst, &R)) {
+      // If the Instruction is used outside the statement, we need to build the
+      // write access.
+      SmallVector<const SCEV *, 4> Subscripts, Sizes;
+      IRAccess ScalarAccess(IRAccess::WRITE, Inst, ZeroOffset, 1, true,
+                            Subscripts, Sizes);
+      Functions.push_back(std::make_pair(ScalarAccess, Inst));
+    }
+  }
+
+  if (Functions.empty())
+    return;
+
+  AccFuncSetType &Accs = AccFuncMap[&BB];
+  Accs.insert(Accs.end(), Functions.begin(), Functions.end());
+}
+
+void TempScopInfo::buildLoopBounds(TempScop &Scop) {
+  Region &R = Scop.getMaxRegion();
+  unsigned MaxLoopDepth = 0;
+
+  for (auto const &BB : R.blocks()) {
+    Loop *L = LI->getLoopFor(BB);
+
+    if (!L || !R.contains(L))
+      continue;
+
+    if (LoopBounds.find(L) != LoopBounds.end())
+      continue;
+
+    const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
+    LoopBounds[L] = BackedgeTakenCount;
+
+    Loop *OL = R.outermostLoopInRegion(L);
+    unsigned LoopDepth = L->getLoopDepth() - OL->getLoopDepth() + 1;
+
+    if (LoopDepth > MaxLoopDepth)
+      MaxLoopDepth = LoopDepth;
+  }
+
+  Scop.MaxLoopDepth = MaxLoopDepth;
+}
+
+void TempScopInfo::buildAffineCondition(Value &V, bool inverted,
+                                        Comparison **Comp) const {
+  if (ConstantInt *C = dyn_cast<ConstantInt>(&V)) {
+    // If this is always true condition, we will create 0 <= 1,
+    // otherwise we will create 0 >= 1.
+    const SCEV *LHS = SE->getConstant(C->getType(), 0);
+    const SCEV *RHS = SE->getConstant(C->getType(), 1);
+
+    if (C->isOne() == inverted)
+      *Comp = new Comparison(LHS, RHS, ICmpInst::ICMP_SLE);
+    else
+      *Comp = new Comparison(LHS, RHS, ICmpInst::ICMP_SGE);
+
+    return;
+  }
+
+  ICmpInst *ICmp = dyn_cast<ICmpInst>(&V);
+  assert(ICmp && "Only ICmpInst of constant as condition supported!");
+
+  Loop *L = LI->getLoopFor(ICmp->getParent());
+  const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
+  const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
+
+  ICmpInst::Predicate Pred = ICmp->getPredicate();
+
+  // Invert the predicate if needed.
+  if (inverted)
+    Pred = ICmpInst::getInversePredicate(Pred);
+
+  switch (Pred) {
+  case ICmpInst::ICMP_UGT:
+  case ICmpInst::ICMP_UGE:
+  case ICmpInst::ICMP_ULT:
+  case ICmpInst::ICMP_ULE:
+    // TODO: At the moment we need to see everything as signed. This is an
+    //       correctness issue that needs to be solved.
+    // AffLHS->setUnsigned();
+    // AffRHS->setUnsigned();
+    break;
+  default:
+    break;
+  }
+
+  *Comp = new Comparison(LHS, RHS, Pred);
+}
+
+void TempScopInfo::buildCondition(BasicBlock *BB, BasicBlock *RegionEntry) {
+  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);
+    Cond.push_back(*Cmp);
+  }
+
+  if (!Cond.empty())
+    BBConds[BB] = Cond;
+}
+
+TempScop *TempScopInfo::buildTempScop(Region &R) {
+  TempScop *TScop = new TempScop(R, LoopBounds, BBConds, AccFuncMap);
+
+  for (const auto &BB : R.blocks()) {
+    buildAccessFunctions(R, *BB);
+    buildCondition(BB, R.getEntry());
+  }
+
+  buildLoopBounds(*TScop);
+
+  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<DominatorTreeWrapperPass>().getDomTree();
+  PDT = &getAnalysis<PostDominatorTree>();
+  SE = &getAnalysis<ScalarEvolution>();
+  LI = &getAnalysis<LoopInfo>();
+  SD = &getAnalysis<ScopDetection>();
+  AA = &getAnalysis<AliasAnalysis>();
+  TD = &getAnalysis<DataLayoutPass>().getDataLayout();
+  ZeroOffset = SE->getConstant(TD->getIntPtrType(F.getContext()), 0);
+
+  for (ScopDetection::iterator I = SD->begin(), E = SD->end(); I != E; ++I) {
+    if (!SD->isMaxRegionInScop(**I))
+      continue;
+    Region *R = const_cast<Region *>(*I);
+    TempScops.insert(std::make_pair(R, buildTempScop(*R)));
+  }
+
+  return false;
+}
+
+void TempScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<DataLayoutPass>();
+  AU.addRequiredTransitive<DominatorTreeWrapperPass>();
+  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;
+
+Pass *polly::createTempScopInfoPass() { return new TempScopInfo(); }
+
+INITIALIZE_PASS_BEGIN(TempScopInfo, "polly-analyze-ir",
+                      "Polly - Analyse the LLVM-IR in the detected regions",
+                      false, false);
+INITIALIZE_AG_DEPENDENCY(AliasAnalysis);
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
+INITIALIZE_PASS_DEPENDENCY(LoopInfo);
+INITIALIZE_PASS_DEPENDENCY(PostDominatorTree);
+INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
+INITIALIZE_PASS_DEPENDENCY(DataLayoutPass);
+INITIALIZE_PASS_END(TempScopInfo, "polly-analyze-ir",
+                    "Polly - Analyse the LLVM-IR in the detected regions",
+                    false, false)
diff --git a/rc1/lib/CMakeLists.txt b/rc1/lib/CMakeLists.txt
new file mode 100644
index 0000000..ace15d7
--- /dev/null
+++ b/rc1/lib/CMakeLists.txt
@@ -0,0 +1,83 @@
+set(LLVM_NO_RTTI 1)
+
+if (PLUTO_FOUND)
+  set(POLLY_PLUTO_FILES Transform/Pluto.cpp)
+endif (PLUTO_FOUND)
+
+set(POLLY_JSON_FILES
+    JSON/json_reader.cpp
+    JSON/json_value.cpp
+    JSON/json_writer.cpp
+)
+
+if (CLOOG_FOUND)
+  set(CLOOG_FILES
+      CodeGen/Cloog.cpp
+      CodeGen/CodeGeneration.cpp)
+endif (CLOOG_FOUND)
+
+set(ISL_CODEGEN_FILES
+    CodeGen/IslAst.cpp
+    CodeGen/IslCodeGeneration.cpp)
+
+if (GPU_CODEGEN)
+  set (GPGPU_CODEGEN_FILES
+       CodeGen/PTXGenerator.cpp)
+endif (GPU_CODEGEN)
+
+if (SCOPLIB_FOUND)
+  set(POLLY_SCOPLIB_FILES
+      Transform/Pocc.cpp
+      Exchange/ScopLib.cpp
+      Exchange/ScopLibExporter.cpp
+      Exchange/ScopLibImporter.cpp)
+endif (SCOPLIB_FOUND)
+
+add_polly_library(Polly
+  Analysis/Dependences.cpp
+  Analysis/ScopDetection.cpp
+  Analysis/ScopDetectionDiagnostic.cpp
+  Analysis/ScopInfo.cpp
+  Analysis/ScopGraphPrinter.cpp
+  Analysis/ScopPass.cpp
+  Analysis/TempScopInfo.cpp
+  CodeGen/BlockGenerators.cpp
+  ${CLOOG_FILES}
+  ${ISL_CODEGEN_FILES}
+  CodeGen/LoopGenerators.cpp
+  CodeGen/IRBuilder.cpp
+  CodeGen/Utils.cpp
+  ${GPGPU_CODEGEN_FILES}
+  Exchange/JSONExporter.cpp
+  ${POLLY_SCOPLIB_FILES}
+  Support/GICHelper.cpp
+  Support/SCEVValidator.cpp
+  Support/RegisterPasses.cpp
+  Support/ScopHelper.cpp
+  ${POLLY_JSON_FILES}
+  Transform/Canonicalization.cpp
+  Transform/CodePreparation.cpp
+  Transform/DeadCodeElimination.cpp
+  Transform/IndependentBlocks.cpp
+  Transform/IndVarSimplify.cpp
+  Transform/ScheduleOptimizer.cpp
+  ${POLLY_PLUTO_FILES}
+  )
+
+# Build a monolithic Polly.a and a thin module LLVMPolly.moduleext that links to
+# that static library.
+add_polly_loadable_module(LLVMPolly
+  Polly.cpp
+)
+
+if (TARGET intrinsics_gen)
+  # Check if we are building as part of an LLVM build
+  add_dependencies(Polly intrinsics_gen)
+endif()
+
+target_link_libraries(LLVMPolly Polly)
+
+set_target_properties(LLVMPolly
+  PROPERTIES
+  LINKER_LANGUAGE CXX
+  PREFIX "")
diff --git a/rc1/lib/CodeGen/BlockGenerators.cpp b/rc1/lib/CodeGen/BlockGenerators.cpp
new file mode 100644
index 0000000..3cfdb4b
--- /dev/null
+++ b/rc1/lib/CodeGen/BlockGenerators.cpp
@@ -0,0 +1,744 @@
+//===--- BlockGenerators.cpp - Generate code for statements -----*- C++ -*-===//
+//
+//                     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 BlockGenerator and VectorBlockGenerator classes,
+// which generate sequential code and vectorized code for a polyhedral
+// statement, respectively.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/ScopInfo.h"
+#include "isl/aff.h"
+#include "isl/set.h"
+#include "polly/CodeGen/BlockGenerators.h"
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/Options.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/SCEVValidator.h"
+#include "polly/Support/ScopHelper.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+using namespace llvm;
+using namespace polly;
+
+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), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool, true>
+    SCEVCodegenF("polly-codegen-scev",
+                 cl::desc("Use SCEV based code generation."), cl::Hidden,
+                 cl::location(SCEVCodegen), cl::init(false), cl::ZeroOrMore,
+                 cl::cat(PollyCategory));
+
+bool polly::SCEVCodegen;
+
+bool polly::canSynthesize(const Instruction *I, const llvm::LoopInfo *LI,
+                          ScalarEvolution *SE, const Region *R) {
+  if (SCEVCodegen) {
+    if (!I || !SE->isSCEVable(I->getType()))
+      return false;
+
+    if (const SCEV *Scev = SE->getSCEV(const_cast<Instruction *>(I)))
+      if (!isa<SCEVCouldNotCompute>(Scev))
+        if (!hasScalarDepsInsideRegion(Scev, R))
+          return true;
+
+    return false;
+  }
+
+  Loop *L = LI->getLoopFor(I->getParent());
+  return L && I == L->getCanonicalInductionVariable() && R->contains(L);
+}
+
+// Helper class to generate memory location.
+namespace {
+class IslGenerator {
+public:
+  IslGenerator(PollyIRBuilder &Builder, std::vector<Value *> &IVS)
+      : Builder(Builder), IVS(IVS) {}
+  Value *generateIslVal(__isl_take isl_val *Val);
+  Value *generateIslAff(__isl_take isl_aff *Aff);
+  Value *generateIslPwAff(__isl_take isl_pw_aff *PwAff);
+
+private:
+  typedef struct {
+    Value *Result;
+    class IslGenerator *Generator;
+  } IslGenInfo;
+
+  PollyIRBuilder &Builder;
+  std::vector<Value *> &IVS;
+  static int mergeIslAffValues(__isl_take isl_set *Set, __isl_take isl_aff *Aff,
+                               void *User);
+};
+}
+
+Value *IslGenerator::generateIslVal(__isl_take isl_val *Val) {
+  Value *IntValue = Builder.getInt(APIntFromVal(Val));
+  return IntValue;
+}
+
+Value *IslGenerator::generateIslAff(__isl_take isl_aff *Aff) {
+  Value *Result;
+  Value *ConstValue;
+  isl_val *Val;
+
+  Val = isl_aff_get_constant_val(Aff);
+  ConstValue = generateIslVal(Val);
+  Type *Ty = Builder.getInt64Ty();
+
+  // FIXME: We should give the constant and coefficients the right type. Here
+  // we force it into i64.
+  Result = Builder.CreateSExtOrBitCast(ConstValue, Ty);
+
+  unsigned int NbInputDims = isl_aff_dim(Aff, isl_dim_in);
+
+  assert((IVS.size() == NbInputDims) &&
+         "The Dimension of Induction Variables must match the dimension of the "
+         "affine space.");
+
+  for (unsigned int i = 0; i < NbInputDims; ++i) {
+    Value *CoefficientValue;
+    Val = isl_aff_get_coefficient_val(Aff, isl_dim_in, i);
+
+    if (isl_val_is_zero(Val)) {
+      isl_val_free(Val);
+      continue;
+    }
+
+    CoefficientValue = generateIslVal(Val);
+    CoefficientValue = Builder.CreateIntCast(CoefficientValue, Ty, true);
+    Value *IV = Builder.CreateIntCast(IVS[i], Ty, true);
+    Value *PAdd = Builder.CreateMul(CoefficientValue, IV, "p_mul_coeff");
+    Result = Builder.CreateAdd(Result, PAdd, "p_sum_coeff");
+  }
+
+  isl_aff_free(Aff);
+
+  return Result;
+}
+
+int IslGenerator::mergeIslAffValues(__isl_take isl_set *Set,
+                                    __isl_take isl_aff *Aff, void *User) {
+  IslGenInfo *GenInfo = (IslGenInfo *)User;
+
+  assert((GenInfo->Result == nullptr) &&
+         "Result is already set. Currently only single isl_aff is supported");
+  assert(isl_set_plain_is_universe(Set) &&
+         "Code generation failed because the set is not universe");
+
+  GenInfo->Result = GenInfo->Generator->generateIslAff(Aff);
+
+  isl_set_free(Set);
+  return 0;
+}
+
+Value *IslGenerator::generateIslPwAff(__isl_take isl_pw_aff *PwAff) {
+  IslGenInfo User;
+  User.Result = nullptr;
+  User.Generator = this;
+  isl_pw_aff_foreach_piece(PwAff, mergeIslAffValues, &User);
+  assert(User.Result && "Code generation for isl_pw_aff failed");
+
+  isl_pw_aff_free(PwAff);
+  return User.Result;
+}
+
+BlockGenerator::BlockGenerator(PollyIRBuilder &B, ScopStmt &Stmt, Pass *P)
+    : Builder(B), Statement(Stmt), P(P), SE(P->getAnalysis<ScalarEvolution>()) {
+}
+
+Value *BlockGenerator::lookupAvailableValue(const Value *Old, ValueMapT &BBMap,
+                                            ValueMapT &GlobalMap) const {
+  // We assume constants never change.
+  // This avoids map lookups for many calls to this function.
+  if (isa<Constant>(Old))
+    return const_cast<Value *>(Old);
+
+  if (Value *New = GlobalMap.lookup(Old)) {
+    if (Old->getType()->getScalarSizeInBits() <
+        New->getType()->getScalarSizeInBits())
+      New = Builder.CreateTruncOrBitCast(New, Old->getType());
+
+    return New;
+  }
+
+  // Or it is probably a scop-constant value defined as global, function
+  // parameter or an instruction not within the scop.
+  if (isa<GlobalValue>(Old) || isa<Argument>(Old))
+    return const_cast<Value *>(Old);
+
+  if (const Instruction *Inst = dyn_cast<Instruction>(Old))
+    if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
+      return const_cast<Value *>(Old);
+
+  if (Value *New = BBMap.lookup(Old))
+    return New;
+
+  return nullptr;
+}
+
+Value *BlockGenerator::getNewValue(const Value *Old, ValueMapT &BBMap,
+                                   ValueMapT &GlobalMap, LoopToScevMapT &LTS,
+                                   Loop *L) {
+  if (Value *New = lookupAvailableValue(Old, BBMap, GlobalMap))
+    return New;
+
+  if (SCEVCodegen && SE.isSCEVable(Old->getType()))
+    if (const SCEV *Scev = SE.getSCEVAtScope(const_cast<Value *>(Old), L)) {
+      if (!isa<SCEVCouldNotCompute>(Scev)) {
+        const SCEV *NewScev = apply(Scev, LTS, SE);
+        ValueToValueMap VTV;
+        VTV.insert(BBMap.begin(), BBMap.end());
+        VTV.insert(GlobalMap.begin(), GlobalMap.end());
+        NewScev = SCEVParameterRewriter::rewrite(NewScev, SE, VTV);
+        SCEVExpander Expander(SE, "polly");
+        Value *Expanded = Expander.expandCodeFor(NewScev, Old->getType(),
+                                                 Builder.GetInsertPoint());
+
+        BBMap[Old] = Expanded;
+        return Expanded;
+      }
+    }
+
+  // Now the scalar dependence is neither available nor SCEVCodegenable, this
+  // should never happen in the current code generator.
+  llvm_unreachable("Unexpected scalar dependence in region!");
+  return nullptr;
+}
+
+void BlockGenerator::copyInstScalar(const Instruction *Inst, ValueMapT &BBMap,
+                                    ValueMapT &GlobalMap, LoopToScevMapT &LTS) {
+  // We do not generate debug intrinsics as we did not investigate how to
+  // copy them correctly. At the current state, they just crash the code
+  // generation as the meta-data operands are not correctly copied.
+  if (isa<DbgInfoIntrinsic>(Inst))
+    return;
+
+  Instruction *NewInst = Inst->clone();
+
+  // Replace old operands with the new ones.
+  for (Value *OldOperand : Inst->operands()) {
+    Value *NewOperand =
+        getNewValue(OldOperand, BBMap, GlobalMap, LTS, getLoopForInst(Inst));
+
+    if (!NewOperand) {
+      assert(!isa<StoreInst>(NewInst) &&
+             "Store instructions are always needed!");
+      delete NewInst;
+      return;
+    }
+
+    NewInst->replaceUsesOfWith(OldOperand, NewOperand);
+  }
+
+  Builder.Insert(NewInst);
+  BBMap[Inst] = NewInst;
+
+  if (!NewInst->getType()->isVoidTy())
+    NewInst->setName("p_" + Inst->getName());
+}
+
+std::vector<Value *> BlockGenerator::getMemoryAccessIndex(
+    __isl_keep isl_map *AccessRelation, Value *BaseAddress, ValueMapT &BBMap,
+    ValueMapT &GlobalMap, LoopToScevMapT &LTS, Loop *L) {
+  assert((isl_map_dim(AccessRelation, isl_dim_out) == 1) &&
+         "Only single dimensional access functions supported");
+
+  std::vector<Value *> IVS;
+  for (unsigned i = 0; i < Statement.getNumIterators(); ++i) {
+    const Value *OriginalIV = Statement.getInductionVariableForDimension(i);
+    Value *NewIV = getNewValue(OriginalIV, BBMap, GlobalMap, LTS, L);
+    IVS.push_back(NewIV);
+  }
+
+  isl_pw_aff *PwAff = isl_map_dim_max(isl_map_copy(AccessRelation), 0);
+  IslGenerator IslGen(Builder, IVS);
+  Value *OffsetValue = IslGen.generateIslPwAff(PwAff);
+
+  Type *Ty = Builder.getInt64Ty();
+  OffsetValue = Builder.CreateIntCast(OffsetValue, Ty, true);
+
+  std::vector<Value *> IndexArray;
+  Value *NullValue = Constant::getNullValue(Ty);
+  IndexArray.push_back(NullValue);
+  IndexArray.push_back(OffsetValue);
+  return IndexArray;
+}
+
+Value *BlockGenerator::getNewAccessOperand(
+    __isl_keep isl_map *NewAccessRelation, Value *BaseAddress, ValueMapT &BBMap,
+    ValueMapT &GlobalMap, LoopToScevMapT &LTS, Loop *L) {
+  std::vector<Value *> IndexArray = getMemoryAccessIndex(
+      NewAccessRelation, BaseAddress, BBMap, GlobalMap, LTS, L);
+  Value *NewOperand =
+      Builder.CreateGEP(BaseAddress, IndexArray, "p_newarrayidx_");
+  return NewOperand;
+}
+
+Value *BlockGenerator::generateLocationAccessed(const Instruction *Inst,
+                                                const Value *Pointer,
+                                                ValueMapT &BBMap,
+                                                ValueMapT &GlobalMap,
+                                                LoopToScevMapT &LTS) {
+  const MemoryAccess &Access = Statement.getAccessFor(Inst);
+  isl_map *CurrentAccessRelation = Access.getAccessRelation();
+  isl_map *NewAccessRelation = Access.getNewAccessRelation();
+
+  assert(isl_map_has_equal_space(CurrentAccessRelation, NewAccessRelation) &&
+         "Current and new access function use different spaces");
+
+  Value *NewPointer;
+
+  if (!NewAccessRelation) {
+    NewPointer =
+        getNewValue(Pointer, BBMap, GlobalMap, LTS, getLoopForInst(Inst));
+  } else {
+    Value *BaseAddress = const_cast<Value *>(Access.getBaseAddr());
+    NewPointer = getNewAccessOperand(NewAccessRelation, BaseAddress, BBMap,
+                                     GlobalMap, LTS, getLoopForInst(Inst));
+  }
+
+  isl_map_free(CurrentAccessRelation);
+  isl_map_free(NewAccessRelation);
+  return NewPointer;
+}
+
+Loop *BlockGenerator::getLoopForInst(const llvm::Instruction *Inst) {
+  return P->getAnalysis<LoopInfo>().getLoopFor(Inst->getParent());
+}
+
+Value *BlockGenerator::generateScalarLoad(const LoadInst *Load,
+                                          ValueMapT &BBMap,
+                                          ValueMapT &GlobalMap,
+                                          LoopToScevMapT &LTS) {
+  const Value *Pointer = Load->getPointerOperand();
+  const Instruction *Inst = dyn_cast<Instruction>(Load);
+  Value *NewPointer =
+      generateLocationAccessed(Inst, Pointer, BBMap, GlobalMap, LTS);
+  Value *ScalarLoad =
+      Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_");
+  return ScalarLoad;
+}
+
+Value *BlockGenerator::generateScalarStore(const StoreInst *Store,
+                                           ValueMapT &BBMap,
+                                           ValueMapT &GlobalMap,
+                                           LoopToScevMapT &LTS) {
+  const Value *Pointer = Store->getPointerOperand();
+  Value *NewPointer =
+      generateLocationAccessed(Store, Pointer, BBMap, GlobalMap, LTS);
+  Value *ValueOperand = getNewValue(Store->getValueOperand(), BBMap, GlobalMap,
+                                    LTS, getLoopForInst(Store));
+
+  return Builder.CreateStore(ValueOperand, NewPointer);
+}
+
+void BlockGenerator::copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
+                                     ValueMapT &GlobalMap,
+                                     LoopToScevMapT &LTS) {
+  // Terminator instructions control the control flow. They are explicitly
+  // expressed in the clast and do not need to be copied.
+  if (Inst->isTerminator())
+    return;
+
+  if (canSynthesize(Inst, &P->getAnalysis<LoopInfo>(), &SE,
+                    &Statement.getParent()->getRegion()))
+    return;
+
+  if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
+    Value *NewLoad = generateScalarLoad(Load, BBMap, GlobalMap, LTS);
+    // Compute NewLoad before its insertion in BBMap to make the insertion
+    // deterministic.
+    BBMap[Load] = NewLoad;
+    return;
+  }
+
+  if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
+    Value *NewStore = generateScalarStore(Store, BBMap, GlobalMap, LTS);
+    // Compute NewStore before its insertion in BBMap to make the insertion
+    // deterministic.
+    BBMap[Store] = NewStore;
+    return;
+  }
+
+  copyInstScalar(Inst, BBMap, GlobalMap, LTS);
+}
+
+void BlockGenerator::copyBB(ValueMapT &GlobalMap, LoopToScevMapT &LTS) {
+  BasicBlock *BB = Statement.getBasicBlock();
+  BasicBlock *CopyBB =
+      SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P);
+  CopyBB->setName("polly.stmt." + BB->getName());
+  Builder.SetInsertPoint(CopyBB->begin());
+
+  ValueMapT BBMap;
+
+  for (Instruction &Inst : *BB)
+    copyInstruction(&Inst, BBMap, GlobalMap, LTS);
+}
+
+VectorBlockGenerator::VectorBlockGenerator(PollyIRBuilder &B,
+                                           VectorValueMapT &GlobalMaps,
+                                           std::vector<LoopToScevMapT> &VLTS,
+                                           ScopStmt &Stmt,
+                                           __isl_keep isl_map *Schedule,
+                                           Pass *P)
+    : BlockGenerator(B, Stmt, P), GlobalMaps(GlobalMaps), VLTS(VLTS),
+      Schedule(Schedule) {
+  assert(GlobalMaps.size() > 1 && "Only one vector lane found");
+  assert(Schedule && "No statement domain provided");
+}
+
+Value *VectorBlockGenerator::getVectorValue(const Value *Old,
+                                            ValueMapT &VectorMap,
+                                            VectorValueMapT &ScalarMaps,
+                                            Loop *L) {
+  if (Value *NewValue = VectorMap.lookup(Old))
+    return NewValue;
+
+  int Width = getVectorWidth();
+
+  Value *Vector = UndefValue::get(VectorType::get(Old->getType(), Width));
+
+  for (int Lane = 0; Lane < Width; Lane++)
+    Vector = Builder.CreateInsertElement(
+        Vector,
+        getNewValue(Old, ScalarMaps[Lane], GlobalMaps[Lane], VLTS[Lane], L),
+        Builder.getInt32(Lane));
+
+  VectorMap[Old] = Vector;
+
+  return Vector;
+}
+
+Type *VectorBlockGenerator::getVectorPtrTy(const Value *Val, int Width) {
+  PointerType *PointerTy = dyn_cast<PointerType>(Val->getType());
+  assert(PointerTy && "PointerType expected");
+
+  Type *ScalarType = PointerTy->getElementType();
+  VectorType *VectorType = VectorType::get(ScalarType, Width);
+
+  return PointerType::getUnqual(VectorType);
+}
+
+Value *
+VectorBlockGenerator::generateStrideOneLoad(const LoadInst *Load,
+                                            VectorValueMapT &ScalarMaps,
+                                            bool NegativeStride = false) {
+  unsigned VectorWidth = getVectorWidth();
+  const Value *Pointer = Load->getPointerOperand();
+  Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
+  unsigned Offset = NegativeStride ? VectorWidth - 1 : 0;
+
+  Value *NewPointer = nullptr;
+  NewPointer = getNewValue(Pointer, ScalarMaps[Offset], GlobalMaps[Offset],
+                           VLTS[Offset], getLoopForInst(Load));
+  Value *VectorPtr =
+      Builder.CreateBitCast(NewPointer, VectorPtrType, "vector_ptr");
+  LoadInst *VecLoad =
+      Builder.CreateLoad(VectorPtr, Load->getName() + "_p_vec_full");
+  if (!Aligned)
+    VecLoad->setAlignment(8);
+
+  if (NegativeStride) {
+    SmallVector<Constant *, 16> Indices;
+    for (int i = VectorWidth - 1; i >= 0; i--)
+      Indices.push_back(ConstantInt::get(Builder.getInt32Ty(), i));
+    Constant *SV = llvm::ConstantVector::get(Indices);
+    Value *RevVecLoad = Builder.CreateShuffleVector(
+        VecLoad, VecLoad, SV, Load->getName() + "_reverse");
+    return RevVecLoad;
+  }
+
+  return VecLoad;
+}
+
+Value *VectorBlockGenerator::generateStrideZeroLoad(const LoadInst *Load,
+                                                    ValueMapT &BBMap) {
+  const Value *Pointer = Load->getPointerOperand();
+  Type *VectorPtrType = getVectorPtrTy(Pointer, 1);
+  Value *NewPointer =
+      getNewValue(Pointer, BBMap, GlobalMaps[0], VLTS[0], getLoopForInst(Load));
+  Value *VectorPtr = Builder.CreateBitCast(NewPointer, VectorPtrType,
+                                           Load->getName() + "_p_vec_p");
+  LoadInst *ScalarLoad =
+      Builder.CreateLoad(VectorPtr, Load->getName() + "_p_splat_one");
+
+  if (!Aligned)
+    ScalarLoad->setAlignment(8);
+
+  Constant *SplatVector = Constant::getNullValue(
+      VectorType::get(Builder.getInt32Ty(), getVectorWidth()));
+
+  Value *VectorLoad = Builder.CreateShuffleVector(
+      ScalarLoad, ScalarLoad, SplatVector, Load->getName() + "_p_splat");
+  return VectorLoad;
+}
+
+Value *
+VectorBlockGenerator::generateUnknownStrideLoad(const LoadInst *Load,
+                                                VectorValueMapT &ScalarMaps) {
+  int VectorWidth = getVectorWidth();
+  const Value *Pointer = Load->getPointerOperand();
+  VectorType *VectorType = VectorType::get(
+      dyn_cast<PointerType>(Pointer->getType())->getElementType(), VectorWidth);
+
+  Value *Vector = UndefValue::get(VectorType);
+
+  for (int i = 0; i < VectorWidth; i++) {
+    Value *NewPointer = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i],
+                                    VLTS[i], getLoopForInst(Load));
+    Value *ScalarLoad =
+        Builder.CreateLoad(NewPointer, Load->getName() + "_p_scalar_");
+    Vector = Builder.CreateInsertElement(
+        Vector, ScalarLoad, Builder.getInt32(i), Load->getName() + "_p_vec_");
+  }
+
+  return Vector;
+}
+
+void VectorBlockGenerator::generateLoad(const LoadInst *Load,
+                                        ValueMapT &VectorMap,
+                                        VectorValueMapT &ScalarMaps) {
+  if (PollyVectorizerChoice >= VECTORIZER_FIRST_NEED_GROUPED_UNROLL ||
+      !VectorType::isValidElementType(Load->getType())) {
+    for (int i = 0; i < getVectorWidth(); i++)
+      ScalarMaps[i][Load] =
+          generateScalarLoad(Load, ScalarMaps[i], GlobalMaps[i], VLTS[i]);
+    return;
+  }
+
+  const MemoryAccess &Access = Statement.getAccessFor(Load);
+
+  // Make sure we have scalar values available to access the pointer to
+  // the data location.
+  extractScalarValues(Load, VectorMap, ScalarMaps);
+
+  Value *NewLoad;
+  if (Access.isStrideZero(isl_map_copy(Schedule)))
+    NewLoad = generateStrideZeroLoad(Load, ScalarMaps[0]);
+  else if (Access.isStrideOne(isl_map_copy(Schedule)))
+    NewLoad = generateStrideOneLoad(Load, ScalarMaps);
+  else if (Access.isStrideX(isl_map_copy(Schedule), -1))
+    NewLoad = generateStrideOneLoad(Load, ScalarMaps, true);
+  else
+    NewLoad = generateUnknownStrideLoad(Load, ScalarMaps);
+
+  VectorMap[Load] = NewLoad;
+}
+
+void VectorBlockGenerator::copyUnaryInst(const UnaryInstruction *Inst,
+                                         ValueMapT &VectorMap,
+                                         VectorValueMapT &ScalarMaps) {
+  int VectorWidth = getVectorWidth();
+  Value *NewOperand = getVectorValue(Inst->getOperand(0), VectorMap, ScalarMaps,
+                                     getLoopForInst(Inst));
+
+  assert(isa<CastInst>(Inst) && "Can not generate vector code for instruction");
+
+  const CastInst *Cast = dyn_cast<CastInst>(Inst);
+  VectorType *DestType = VectorType::get(Inst->getType(), VectorWidth);
+  VectorMap[Inst] = Builder.CreateCast(Cast->getOpcode(), NewOperand, DestType);
+}
+
+void VectorBlockGenerator::copyBinaryInst(const BinaryOperator *Inst,
+                                          ValueMapT &VectorMap,
+                                          VectorValueMapT &ScalarMaps) {
+  Loop *L = getLoopForInst(Inst);
+  Value *OpZero = Inst->getOperand(0);
+  Value *OpOne = Inst->getOperand(1);
+
+  Value *NewOpZero, *NewOpOne;
+  NewOpZero = getVectorValue(OpZero, VectorMap, ScalarMaps, L);
+  NewOpOne = getVectorValue(OpOne, VectorMap, ScalarMaps, L);
+
+  Value *NewInst = Builder.CreateBinOp(Inst->getOpcode(), NewOpZero, NewOpOne,
+                                       Inst->getName() + "p_vec");
+  VectorMap[Inst] = NewInst;
+}
+
+void VectorBlockGenerator::copyStore(const StoreInst *Store,
+                                     ValueMapT &VectorMap,
+                                     VectorValueMapT &ScalarMaps) {
+  int VectorWidth = getVectorWidth();
+
+  const MemoryAccess &Access = Statement.getAccessFor(Store);
+
+  const Value *Pointer = Store->getPointerOperand();
+  Value *Vector = getVectorValue(Store->getValueOperand(), VectorMap,
+                                 ScalarMaps, getLoopForInst(Store));
+
+  // Make sure we have scalar values available to access the pointer to
+  // the data location.
+  extractScalarValues(Store, VectorMap, ScalarMaps);
+
+  if (Access.isStrideOne(isl_map_copy(Schedule))) {
+    Type *VectorPtrType = getVectorPtrTy(Pointer, VectorWidth);
+    Value *NewPointer = getNewValue(Pointer, ScalarMaps[0], GlobalMaps[0],
+                                    VLTS[0], getLoopForInst(Store));
+
+    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 = getNewValue(Pointer, ScalarMaps[i], GlobalMaps[i],
+                                      VLTS[i], getLoopForInst(Store));
+      Builder.CreateStore(Scalar, NewPointer);
+    }
+  }
+}
+
+bool VectorBlockGenerator::hasVectorOperands(const Instruction *Inst,
+                                             ValueMapT &VectorMap) {
+  for (Value *Operand : Inst->operands())
+    if (VectorMap.count(Operand))
+      return true;
+  return false;
+}
+
+bool VectorBlockGenerator::extractScalarValues(const Instruction *Inst,
+                                               ValueMapT &VectorMap,
+                                               VectorValueMapT &ScalarMaps) {
+  bool HasVectorOperand = false;
+  int VectorWidth = getVectorWidth();
+
+  for (Value *Operand : Inst->operands()) {
+    ValueMapT::iterator VecOp = VectorMap.find(Operand);
+
+    if (VecOp == VectorMap.end())
+      continue;
+
+    HasVectorOperand = true;
+    Value *NewVector = VecOp->second;
+
+    for (int i = 0; i < VectorWidth; ++i) {
+      ValueMapT &SM = ScalarMaps[i];
+
+      // If there is one scalar extracted, all scalar elements should have
+      // already been extracted by the code here. So no need to check for the
+      // existance of all of them.
+      if (SM.count(Operand))
+        break;
+
+      SM[Operand] =
+          Builder.CreateExtractElement(NewVector, Builder.getInt32(i));
+    }
+  }
+
+  return HasVectorOperand;
+}
+
+void VectorBlockGenerator::copyInstScalarized(const Instruction *Inst,
+                                              ValueMapT &VectorMap,
+                                              VectorValueMapT &ScalarMaps) {
+  bool HasVectorOperand;
+  int VectorWidth = getVectorWidth();
+
+  HasVectorOperand = extractScalarValues(Inst, VectorMap, ScalarMaps);
+
+  for (int VectorLane = 0; VectorLane < getVectorWidth(); VectorLane++)
+    copyInstScalar(Inst, ScalarMaps[VectorLane], GlobalMaps[VectorLane],
+                   VLTS[VectorLane]);
+
+  if (!VectorType::isValidElementType(Inst->getType()) || !HasVectorOperand)
+    return;
+
+  // Make the result available as vector value.
+  VectorType *VectorType = VectorType::get(Inst->getType(), VectorWidth);
+  Value *Vector = UndefValue::get(VectorType);
+
+  for (int i = 0; i < VectorWidth; i++)
+    Vector = Builder.CreateInsertElement(Vector, ScalarMaps[i][Inst],
+                                         Builder.getInt32(i));
+
+  VectorMap[Inst] = Vector;
+}
+
+int VectorBlockGenerator::getVectorWidth() { return GlobalMaps.size(); }
+
+void VectorBlockGenerator::copyInstruction(const Instruction *Inst,
+                                           ValueMapT &VectorMap,
+                                           VectorValueMapT &ScalarMaps) {
+  // Terminator instructions control the control flow. They are explicitly
+  // expressed in the clast and do not need to be copied.
+  if (Inst->isTerminator())
+    return;
+
+  if (canSynthesize(Inst, &P->getAnalysis<LoopInfo>(), &SE,
+                    &Statement.getParent()->getRegion()))
+    return;
+
+  if (const LoadInst *Load = dyn_cast<LoadInst>(Inst)) {
+    generateLoad(Load, VectorMap, ScalarMaps);
+    return;
+  }
+
+  if (hasVectorOperands(Inst, VectorMap)) {
+    if (const StoreInst *Store = dyn_cast<StoreInst>(Inst)) {
+      copyStore(Store, VectorMap, ScalarMaps);
+      return;
+    }
+
+    if (const UnaryInstruction *Unary = dyn_cast<UnaryInstruction>(Inst)) {
+      copyUnaryInst(Unary, VectorMap, ScalarMaps);
+      return;
+    }
+
+    if (const BinaryOperator *Binary = dyn_cast<BinaryOperator>(Inst)) {
+      copyBinaryInst(Binary, VectorMap, ScalarMaps);
+      return;
+    }
+
+    // Falltrough: We generate scalar instructions, if we don't know how to
+    // generate vector code.
+  }
+
+  copyInstScalarized(Inst, VectorMap, ScalarMaps);
+}
+
+void VectorBlockGenerator::copyBB() {
+  BasicBlock *BB = Statement.getBasicBlock();
+  BasicBlock *CopyBB =
+      SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P);
+  CopyBB->setName("polly.stmt." + BB->getName());
+  Builder.SetInsertPoint(CopyBB->begin());
+
+  // Create two maps that store the mapping from the original instructions of
+  // the old basic block to their copies in the new basic block. Those maps
+  // are basic block local.
+  //
+  // As vector code generation is supported there is one map for scalar values
+  // and one for vector values.
+  //
+  // In case we just do scalar code generation, the vectorMap is not used and
+  // the scalarMap has just one dimension, which contains the mapping.
+  //
+  // In case vector code generation is done, an instruction may either appear
+  // in the vector map once (as it is calculating >vectorwidth< values at a
+  // time. Or (if the values are calculated using scalar operations), it
+  // appears once in every dimension of the scalarMap.
+  VectorValueMapT ScalarBlockMap(getVectorWidth());
+  ValueMapT VectorBlockMap;
+
+  for (Instruction &Inst : *BB)
+    copyInstruction(&Inst, VectorBlockMap, ScalarBlockMap);
+}
diff --git a/rc1/lib/CodeGen/Cloog.cpp b/rc1/lib/CodeGen/Cloog.cpp
new file mode 100644
index 0000000..fee863e
--- /dev/null
+++ b/rc1/lib/CodeGen/Cloog.cpp
@@ -0,0 +1,365 @@
+//===- 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/CodeGen/Cloog.h"
+#ifdef CLOOG_FOUND
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopInfo.h"
+
+#include "llvm/IR/Module.h"
+#include "llvm/Support/Debug.h"
+
+#include "cloog/isl/domain.h"
+#include "cloog/isl/cloog.h"
+
+#include <unistd.h>
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-cloog"
+
+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.
+  clast_root *getClast();
+};
+
+Cloog::Cloog(Scop *Scop) : S(Scop) {
+  State = cloog_isl_state_malloc(Scop->getIslCtx());
+  buildCloogOptions();
+  ClastRoot = cloog_clast_create_from_input(buildCloogInput(), Options);
+}
+
+Cloog::~Cloog() {
+  cloog_clast_free(ClastRoot);
+  cloog_options_free(Options);
+  cloog_state_free(State);
+}
+
+// Create a FILE* write stream and get the output to it written
+// to a std::string.
+class FileToString {
+  int FD[2];
+  FILE *input;
+  static const int BUFFERSIZE = 20;
+
+  char buf[BUFFERSIZE + 1];
+
+public:
+  FileToString() {
+    pipe(FD);
+    input = fdopen(FD[1], "w");
+  }
+  ~FileToString() {
+    close(FD[0]);
+    // close(FD[1]);
+  }
+
+  FILE *getInputFile() { return input; }
+
+  void closeInput() {
+    fclose(input);
+    close(FD[1]);
+  }
+
+  std::string getOutput() {
+    std::string output;
+    int readSize;
+
+    while (true) {
+      readSize = read(FD[0], &buf, BUFFERSIZE);
+
+      if (readSize <= 0)
+        break;
+
+      output += std::string(buf, readSize);
+    }
+
+    return output;
+  }
+};
+
+/// Write .cloog input file.
+void Cloog::dump(FILE *F) {
+  CloogInput *Input = buildCloogInput();
+  cloog_input_dump_cloog(F, Input, Options);
+  cloog_input_free(Input);
+}
+
+/// Print a source code representation of the program.
+void Cloog::pprint(raw_ostream &OS) {
+  FileToString *Output = new FileToString();
+  clast_pprint(Output->getInputFile(), ClastRoot, 0, Options);
+  Output->closeInput();
+  OS << Output->getOutput();
+  delete (Output);
+}
+
+/// Create the Cloog AST from this program.
+clast_root *Cloog::getClast() { return (clast_root *)ClastRoot; }
+
+void Cloog::buildCloogOptions() {
+  Options = cloog_options_malloc(State);
+  Options->quiet = 1;
+  Options->strides = 1;
+  Options->save_domains = 1;
+  Options->noscalars = 1;
+
+  // Compute simple hulls to reduce code generation time.
+  Options->sh = 1;
+
+  // The last loop depth to optimize should be the last scattering dimension.
+  // CLooG by default will continue to split the loops even after the last
+  // scattering dimension. This splitting is problematic for the schedules
+  // calculated by the PoCC/isl/Pluto optimizer. Such schedules contain may
+  // not be fully defined, but statements without dependences may be mapped
+  // to the same exeuction time. For such schedules, continuing to split
+  // may lead to a larger set of if-conditions in the innermost loop.
+  Options->l = 0;
+}
+
+CloogUnionDomain *Cloog::buildCloogUnionDomain() {
+  CloogUnionDomain *DU = cloog_union_domain_alloc(S->getNumParams());
+
+  for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+    ScopStmt *Stmt = *SI;
+    CloogScattering *Scattering;
+    CloogDomain *Domain;
+
+    Scattering = cloog_scattering_from_isl_map(Stmt->getScattering());
+    Domain = cloog_domain_from_isl_set(Stmt->getDomain());
+
+    std::string entryName = Stmt->getBaseName();
+
+    DU = cloog_union_domain_add_domain(DU, entryName.c_str(), Domain,
+                                       Scattering, Stmt);
+  }
+
+  return DU;
+}
+
+CloogInput *Cloog::buildCloogInput() {
+  // XXX: We do not copy the context of the scop, but use an unconstrained
+  //      context. This 'hack' is necessary as the context may contain bounds
+  //      on parameters such as [n] -> {:0 <= n < 2^32}. Those large
+  //      integers will cause CLooG to construct a clast that contains
+  //      expressions that include these large integers. Such expressions can
+  //      possibly not be evaluated correctly with i64 types. The cloog
+  //      based code generation backend, however, can not derive types
+  //      automatically and just assumes i64 types. Hence, it will break or
+  //      generate incorrect code.
+  //      This hack does not remove all possibilities of incorrectly generated
+  //      code, but it is ensures that for most problems the problems do not
+  //      show up. The correct solution, will be to automatically derive the
+  //      minimal types for each expression. This could be added to CLooG and it
+  //      will be available in the isl based code generation.
+  isl_set *EmptyContext = isl_set_universe(S->getParamSpace());
+  CloogDomain *Context = cloog_domain_from_isl_set(EmptyContext);
+  CloogUnionDomain *Statements = buildCloogUnionDomain();
+
+  isl_set *ScopContext = S->getContext();
+
+  for (unsigned i = 0; i < isl_set_dim(ScopContext, isl_dim_param); i++) {
+    isl_id *id = isl_set_get_dim_id(ScopContext, isl_dim_param, i);
+    Statements = cloog_union_domain_set_name(Statements, CLOOG_PARAM, i,
+                                             isl_id_get_name(id));
+    isl_id_free(id);
+  }
+
+  isl_set_free(ScopContext);
+
+  CloogInput *Input = cloog_input_alloc(Context, Statements);
+  return Input;
+}
+
+void ClastVisitor::visit(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))
+    return visitAssignment((const clast_assignment *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_user))
+    return visitUser((const clast_user_stmt *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_block))
+    return visitBlock((const clast_block *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_for))
+    return visitFor((const clast_for *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_guard))
+    return visitGuard((const clast_guard *)stmt);
+
+  if (stmt->next)
+    visit(stmt->next);
+}
+
+void ClastVisitor::visitAssignment(const clast_assignment *stmt) {}
+
+void ClastVisitor::visitBlock(const clast_block *stmt) { visit(stmt->body); }
+
+void ClastVisitor::visitFor(const clast_for *stmt) { visit(stmt->body); }
+
+void ClastVisitor::visitGuard(const clast_guard *stmt) { visit(stmt->then); }
+
+} // End namespace polly.
+
+namespace {
+
+struct CloogExporter : public ScopPass {
+  static char ID;
+  Scop *S;
+  explicit CloogExporter() : ScopPass(ID) {}
+
+  std::string getFileName(Region *R) const;
+  virtual bool runOnScop(Scop &S);
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+}
+std::string CloogExporter::getFileName(Region *R) const {
+  std::string FunctionName = R->getEntry()->getParent()->getName();
+  std::string ExitName, EntryName;
+
+  raw_string_ostream ExitStr(ExitName);
+  raw_string_ostream EntryStr(EntryName);
+
+  R->getEntry()->printAsOperand(EntryStr, false);
+  EntryStr.str();
+
+  if (R->getExit()) {
+    R->getExit()->printAsOperand(ExitStr, 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()->getName();
+  std::string Filename = getFileName(&R);
+
+  errs() << "Writing Scop '" << R.getNameStr() << "' in function '"
+         << FunctionName << "' to '" << Filename << "'...\n";
+
+  FILE *F = fopen(Filename.c_str(), "w");
+  C.dump(F);
+  fclose(F);
+
+  return false;
+}
+
+void CloogExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+  // Get the Common analysis usage of ScopPasses.
+  ScopPass::getAnalysisUsage(AU);
+  AU.addRequired<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_root *CloogInfo::getClast() { return C->getClast(); }
+
+void CloogInfo::releaseMemory() {
+  if (C) {
+    delete C;
+    C = 0;
+  }
+}
+
+bool CloogInfo::runOnScop(Scop &S) {
+  if (C)
+    delete C;
+
+  scop = &S;
+
+  C = new Cloog(&S);
+
+  Function *F = S.getRegion().getEntry()->getParent();
+  (void)F;
+
+  DEBUG(dbgs() << ":: " << F->getName());
+  DEBUG(dbgs() << " : " << S.getRegion().getNameStr() << "\n");
+  DEBUG(C->pprint(dbgs()));
+
+  return false;
+}
+
+void CloogInfo::printScop(raw_ostream &OS) const {
+  Function *function = scop->getRegion().getEntry()->getParent();
+
+  OS << function->getName() << "():\n";
+
+  C->pprint(OS);
+}
+
+void CloogInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+  // Get the Common analysis usage of ScopPasses.
+  ScopPass::getAnalysisUsage(AU);
+}
+char CloogInfo::ID = 0;
+
+Pass *polly::createCloogInfoPass() { return new CloogInfo(); }
+
+INITIALIZE_PASS_BEGIN(CloogInfo, "polly-cloog", "Execute Cloog code generation",
+                      false, false);
+INITIALIZE_PASS_DEPENDENCY(ScopInfo);
+INITIALIZE_PASS_END(CloogInfo, "polly-cloog", "Execute Cloog code generation",
+                    false, false)
+
+#endif // CLOOG_FOUND
diff --git a/rc1/lib/CodeGen/CodeGeneration.cpp b/rc1/lib/CodeGen/CodeGeneration.cpp
new file mode 100644
index 0000000..1f093fb
--- /dev/null
+++ b/rc1/lib/CodeGen/CodeGeneration.cpp
@@ -0,0 +1,1094 @@
+//===------ 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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/CodeGen/Cloog.h"
+#ifdef CLOOG_FOUND
+
+#include "polly/Dependences.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
+#include "polly/ScopInfo.h"
+#include "polly/TempScopInfo.h"
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/CodeGen/BlockGenerators.h"
+#include "polly/CodeGen/LoopGenerators.h"
+#include "polly/CodeGen/PTXGenerator.h"
+#include "polly/CodeGen/Utils.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/ScopHelper.h"
+
+#include "llvm/IR/Module.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+#define CLOOG_INT_GMP 1
+#include "cloog/cloog.h"
+#include "cloog/isl/cloog.h"
+
+#include "isl/aff.h"
+
+#include <vector>
+#include <utility>
+
+using namespace polly;
+using namespace llvm;
+
+#define DEBUG_TYPE "polly-codegen"
+
+struct isl_set;
+
+namespace polly {
+static cl::opt<bool>
+    OpenMP("enable-polly-openmp", cl::desc("Generate OpenMP parallel code"),
+           cl::value_desc("OpenMP code generation enabled if true"),
+           cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+#ifdef GPU_CODEGEN
+static cl::opt<bool>
+    GPGPU("enable-polly-gpgpu", cl::desc("Generate GPU parallel code"),
+          cl::Hidden, cl::value_desc("GPGPU code generation enabled if true"),
+          cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<std::string>
+    GPUTriple("polly-gpgpu-triple",
+              cl::desc("Target triple for GPU code generation"), cl::Hidden,
+              cl::init(""), cl::cat(PollyCategory));
+#endif /* GPU_CODEGEN */
+
+typedef DenseMap<const char *, Value *> CharMapT;
+
+/// Class to generate LLVM-IR that calculates the value of a clast_expr.
+class ClastExpCodeGen {
+  PollyIRBuilder &Builder;
+  const CharMapT &IVS;
+
+  Value *codegen(const clast_name *e, Type *Ty);
+  Value *codegen(const clast_term *e, Type *Ty);
+  Value *codegen(const clast_binary *e, Type *Ty);
+  Value *codegen(const clast_reduction *r, Type *Ty);
+
+public:
+  // A generator for clast expressions.
+  //
+  // @param B The IRBuilder that defines where the code to calculate the
+  //          clast expressions should be inserted.
+  // @param IVMAP A Map that translates strings describing the induction
+  //              variables to the Values* that represent these variables
+  //              on the LLVM side.
+  ClastExpCodeGen(PollyIRBuilder &B, CharMapT &IVMap);
+
+  // Generates code to calculate a given clast expression.
+  //
+  // @param e The expression to calculate.
+  // @return The Value that holds the result.
+  Value *codegen(const clast_expr *e, Type *Ty);
+};
+
+Value *ClastExpCodeGen::codegen(const clast_name *e, Type *Ty) {
+  CharMapT::const_iterator I = IVS.find(e->name);
+
+  assert(I != IVS.end() && "Clast name not found");
+
+  return Builder.CreateSExtOrBitCast(I->second, Ty);
+}
+
+static APInt APInt_from_MPZ(const mpz_t mpz) {
+  uint64_t *p = nullptr;
+  size_t sz;
+
+  p = (uint64_t *)mpz_export(p, &sz, -1, sizeof(uint64_t), 0, 0, mpz);
+
+  if (p) {
+    APInt A((unsigned)mpz_sizeinbase(mpz, 2), (unsigned)sz, p);
+    A = A.zext(A.getBitWidth() + 1);
+    free(p);
+
+    if (mpz_sgn(mpz) == -1)
+      return -A;
+    else
+      return A;
+  } else {
+    uint64_t val = 0;
+    return APInt(1, 1, &val);
+  }
+}
+
+Value *ClastExpCodeGen::codegen(const clast_term *e, Type *Ty) {
+  APInt a = APInt_from_MPZ(e->val);
+
+  Value *ConstOne = ConstantInt::get(Builder.getContext(), a);
+  ConstOne = Builder.CreateSExtOrBitCast(ConstOne, Ty);
+
+  if (!e->var)
+    return ConstOne;
+
+  Value *var = codegen(e->var, Ty);
+  return Builder.CreateMul(ConstOne, var);
+}
+
+Value *ClastExpCodeGen::codegen(const clast_binary *e, Type *Ty) {
+  Value *LHS = codegen(e->LHS, Ty);
+
+  APInt RHS_AP = APInt_from_MPZ(e->RHS);
+
+  Value *RHS = ConstantInt::get(Builder.getContext(), RHS_AP);
+  RHS = Builder.CreateSExtOrBitCast(RHS, Ty);
+
+  switch (e->type) {
+  case clast_bin_mod:
+    return Builder.CreateSRem(LHS, RHS);
+  case clast_bin_fdiv: {
+    // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
+    Value *One = ConstantInt::get(Ty, 1);
+    Value *Zero = ConstantInt::get(Ty, 0);
+    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(Ty, 1);
+    Value *Zero = ConstantInt::get(Ty, 0);
+    Value *Sum1 = Builder.CreateAdd(LHS, RHS);
+    Value *Sum2 = Builder.CreateSub(Sum1, One);
+    Value *isNegative = Builder.CreateICmpSLT(LHS, Zero);
+    Value *Dividend = Builder.CreateSelect(isNegative, LHS, Sum2);
+    return Builder.CreateSDiv(Dividend, RHS);
+  }
+  case clast_bin_div:
+    return Builder.CreateSDiv(LHS, RHS);
+  }
+
+  llvm_unreachable("Unknown clast binary expression type");
+}
+
+Value *ClastExpCodeGen::codegen(const clast_reduction *r, Type *Ty) {
+  assert((r->type == clast_red_min || r->type == clast_red_max ||
+          r->type == clast_red_sum) &&
+         "Clast reduction type not supported");
+  Value *old = codegen(r->elts[0], Ty);
+
+  for (int i = 1; i < r->n; ++i) {
+    Value *exprValue = codegen(r->elts[i], Ty);
+
+    switch (r->type) {
+    case clast_red_min: {
+      Value *cmp = Builder.CreateICmpSLT(old, exprValue);
+      old = Builder.CreateSelect(cmp, old, exprValue);
+      break;
+    }
+    case clast_red_max: {
+      Value *cmp = Builder.CreateICmpSGT(old, exprValue);
+      old = Builder.CreateSelect(cmp, old, exprValue);
+      break;
+    }
+    case clast_red_sum:
+      old = Builder.CreateAdd(old, exprValue);
+      break;
+    }
+  }
+
+  return old;
+}
+
+ClastExpCodeGen::ClastExpCodeGen(PollyIRBuilder &B, CharMapT &IVMap)
+    : Builder(B), IVS(IVMap) {}
+
+Value *ClastExpCodeGen::codegen(const clast_expr *e, Type *Ty) {
+  switch (e->type) {
+  case clast_expr_name:
+    return codegen((const clast_name *)e, Ty);
+  case clast_expr_term:
+    return codegen((const clast_term *)e, Ty);
+  case clast_expr_bin:
+    return codegen((const clast_binary *)e, Ty);
+  case clast_expr_red:
+    return codegen((const clast_reduction *)e, Ty);
+  }
+
+  llvm_unreachable("Unknown clast expression!");
+}
+
+class ClastStmtCodeGen {
+public:
+  const std::vector<std::string> &getParallelLoops();
+
+private:
+  // The Scop we code generate.
+  Scop *S;
+  Pass *P;
+
+  // The Builder specifies the current location to code generate at.
+  PollyIRBuilder &Builder;
+
+  // Map the Values from the old code to their counterparts in the new code.
+  ValueMapT ValueMap;
+
+  // Map the loops from the old code to expressions function of the induction
+  // variables in the new code.  For example, when the code generator produces
+  // this AST:
+  //
+  //   for (int c1 = 0; c1 <= 1023; c1 += 1)
+  //     for (int c2 = 0; c2 <= 1023; c2 += 1)
+  //       Stmt(c2 + 3, c1);
+  //
+  // LoopToScev is a map associating:
+  //   "outer loop in the old loop nest" -> SCEV("c2 + 3"),
+  //   "inner loop in the old loop nest" -> SCEV("c1").
+  LoopToScevMapT LoopToScev;
+
+  // 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;
+
+  void codegen(const clast_assignment *a);
+
+  void codegen(const clast_assignment *a, ScopStmt *Statement,
+               unsigned Dimension, int vectorDim,
+               std::vector<ValueMapT> *VectorVMap = 0,
+               std::vector<LoopToScevMapT> *VLTS = 0);
+
+  void codegenSubstitutions(const clast_stmt *Assignment, ScopStmt *Statement,
+                            int vectorDim = 0,
+                            std::vector<ValueMapT> *VectorVMap = 0,
+                            std::vector<LoopToScevMapT> *VLTS = 0);
+
+  void codegen(const clast_user_stmt *u, std::vector<Value *> *IVS = nullptr,
+               const char *iterator = nullptr,
+               __isl_take isl_set *scatteringDomain = 0);
+
+  void codegen(const clast_block *b);
+
+  /// @brief Create a classical sequential loop.
+  void codegenForSequential(const clast_for *f);
+
+  /// @brief Create OpenMP structure values.
+  ///
+  /// Create a list of values that has to be stored into the OpenMP subfuncition
+  /// structure.
+  SetVector<Value *> getOMPValues(const clast_stmt *Body);
+
+  /// @brief Update ClastVars and ValueMap according to a value map.
+  ///
+  /// @param VMap A map from old to new values.
+  void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap);
+
+  /// @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);
+
+#ifdef GPU_CODEGEN
+  /// @brief Create GPGPU device memory access values.
+  ///
+  /// Create a list of values that will be set to be parameters of the GPGPU
+  /// subfunction. These parameters represent device memory base addresses
+  /// and the size in bytes.
+  SetVector<Value *> getGPUValues(unsigned &OutputBytes);
+
+  /// @brief Create a GPU parallel for loop.
+  ///
+  /// This loop reflects a loop as if it would have been created by a GPU
+  /// statement.
+  void codegenForGPGPU(const clast_for *F);
+
+  /// @brief Get innermost for loop.
+  const clast_stmt *getScheduleInfo(const clast_for *F,
+                                    std::vector<int> &NumIters,
+                                    unsigned &LoopDepth,
+                                    unsigned &NonPLoopDepth);
+#endif /* GPU_CODEGEN */
+
+  /// @brief Check if a loop is parallel
+  ///
+  /// Detect if a clast_for loop can be executed in parallel.
+  ///
+  /// @param For The clast for loop to check.
+  ///
+  /// @return bool Returns true if the incoming clast_for statement can
+  ///              execute in parallel.
+  bool isParallelFor(const clast_for *For);
+
+  bool isInnermostLoop(const clast_for *f);
+
+  /// @brief Get the number of loop iterations for this loop.
+  /// @param f The clast for loop to check.
+  int getNumberOfIterations(const clast_for *f);
+
+  /// @brief Create vector instructions for this loop.
+  void codegenForVector(const clast_for *f);
+
+  void codegen(const clast_for *f);
+
+  Value *codegen(const clast_equation *eq);
+
+  void codegen(const clast_guard *g);
+
+  void codegen(const clast_stmt *stmt);
+
+  void addParameters(const CloogNames *names);
+
+  IntegerType *getIntPtrTy();
+
+public:
+  void codegen(const clast_root *r);
+
+  ClastStmtCodeGen(Scop *scop, PollyIRBuilder &B, Pass *P);
+};
+}
+
+IntegerType *ClastStmtCodeGen::getIntPtrTy() {
+  return P->getAnalysis<DataLayoutPass>().getDataLayout().getIntPtrType(
+      Builder.getContext());
+}
+
+const std::vector<std::string> &ClastStmtCodeGen::getParallelLoops() {
+  return parallelLoops;
+}
+
+void ClastStmtCodeGen::codegen(const clast_assignment *a) {
+  Value *V = ExpGen.codegen(a->RHS, getIntPtrTy());
+  ClastVars[a->LHS] = V;
+}
+
+void ClastStmtCodeGen::codegen(const clast_assignment *A, ScopStmt *Stmt,
+                               unsigned Dim, int VectorDim,
+                               std::vector<ValueMapT> *VectorVMap,
+                               std::vector<LoopToScevMapT> *VLTS) {
+  Value *RHS;
+
+  assert(!A->LHS && "Statement assignments do not have left hand side");
+
+  RHS = ExpGen.codegen(A->RHS, Builder.getInt64Ty());
+
+  const llvm::SCEV *URHS = S->getSE()->getUnknown(RHS);
+  if (VLTS)
+    (*VLTS)[VectorDim][Stmt->getLoopForDimension(Dim)] = URHS;
+  LoopToScev[Stmt->getLoopForDimension(Dim)] = URHS;
+
+  const PHINode *PN = Stmt->getInductionVariableForDimension(Dim);
+  if (PN) {
+    RHS = Builder.CreateTruncOrBitCast(RHS, PN->getType());
+
+    if (VectorVMap)
+      (*VectorVMap)[VectorDim][PN] = RHS;
+
+    ValueMap[PN] = RHS;
+  }
+}
+
+void ClastStmtCodeGen::codegenSubstitutions(const clast_stmt *Assignment,
+                                            ScopStmt *Statement, int vectorDim,
+                                            std::vector<ValueMapT> *VectorVMap,
+                                            std::vector<LoopToScevMapT> *VLTS) {
+  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, VLTS);
+    Assignment = Assignment->next;
+    Dimension++;
+  }
+}
+
+// Takes the cloog specific domain and translates it into a map Statement ->
+// PartialSchedule, where the PartialSchedule contains all the dimensions that
+// have been code generated up to this point.
+static __isl_give isl_map *extractPartialSchedule(ScopStmt *Statement,
+                                                  __isl_take isl_set *Domain) {
+  isl_map *Schedule = Statement->getScattering();
+  int ScheduledDimensions = isl_set_dim(Domain, isl_dim_set);
+  int UnscheduledDimensions =
+      isl_map_dim(Schedule, isl_dim_out) - ScheduledDimensions;
+
+  isl_set_free(Domain);
+
+  return isl_map_project_out(Schedule, isl_dim_out, ScheduledDimensions,
+                             UnscheduledDimensions);
+}
+
+void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
+                               std::vector<Value *> *IVS, const char *iterator,
+                               __isl_take isl_set *Domain) {
+  ScopStmt *Statement = (ScopStmt *)u->statement->usr;
+
+  if (u->substitutions)
+    codegenSubstitutions(u->substitutions, Statement);
+
+  int VectorDimensions = IVS ? IVS->size() : 1;
+
+  if (VectorDimensions == 1) {
+    BlockGenerator::generate(Builder, *Statement, ValueMap, LoopToScev, P);
+    isl_set_free(Domain);
+    return;
+  }
+
+  VectorValueMapT VectorMap(VectorDimensions);
+  std::vector<LoopToScevMapT> VLTS(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, &VectorMap, &VLTS);
+      i++;
+    }
+  }
+
+  // Copy the current value map into all vector maps if the key wasn't
+  // available yet. This is needed in case vector codegen is performed in
+  // OpenMP subfunctions.
+  for (auto KV : ValueMap)
+    for (int i = 0; i < VectorDimensions; ++i)
+      VectorMap[i].insert(KV);
+
+  isl_map *Schedule = extractPartialSchedule(Statement, Domain);
+  VectorBlockGenerator::generate(Builder, *Statement, VectorMap, VLTS, Schedule,
+                                 P);
+  isl_map_free(Schedule);
+}
+
+void ClastStmtCodeGen::codegen(const clast_block *b) {
+  if (b->body)
+    codegen(b->body);
+}
+
+void ClastStmtCodeGen::codegenForSequential(const clast_for *f) {
+  Value *LowerBound, *UpperBound, *IV, *Stride;
+  BasicBlock *ExitBlock;
+  Type *IntPtrTy = getIntPtrTy();
+
+  LowerBound = ExpGen.codegen(f->LB, IntPtrTy);
+  UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
+  Stride = Builder.getInt(APInt_from_MPZ(f->stride));
+
+  IV = createLoop(LowerBound, UpperBound, Stride, Builder, P, ExitBlock,
+                  CmpInst::ICMP_SLE);
+
+  // Add loop iv to symbols.
+  ClastVars[f->iterator] = IV;
+
+  if (f->body)
+    codegen(f->body);
+
+  // Loop is finished, so remove its iv from the live symbols.
+  ClastVars.erase(f->iterator);
+  Builder.SetInsertPoint(ExitBlock->begin());
+}
+
+// Helper class to determine all scalar parameters used in the basic blocks of a
+// clast. Scalar parameters are scalar variables defined outside of the SCoP.
+class ParameterVisitor : public ClastVisitor {
+  std::set<Value *> Values;
+
+public:
+  ParameterVisitor() : ClastVisitor(), Values() {}
+
+  void visitUser(const clast_user_stmt *Stmt) {
+    const ScopStmt *S = static_cast<const ScopStmt *>(Stmt->statement->usr);
+    const BasicBlock *BB = S->getBasicBlock();
+
+    // Check all the operands of instructions in the basic block.
+    for (const Instruction &Inst : *BB) {
+      for (Value *SrcVal : Inst.operands()) {
+        if (Instruction *OpInst = dyn_cast<Instruction>(SrcVal))
+          if (S->getParent()->getRegion().contains(OpInst))
+            continue;
+
+        if (isa<Instruction>(SrcVal) || isa<Argument>(SrcVal))
+          Values.insert(SrcVal);
+      }
+    }
+  }
+
+  // Iterator to iterate over the values found.
+  typedef std::set<Value *>::const_iterator const_iterator;
+  inline const_iterator begin() const { return Values.begin(); }
+  inline const_iterator end() const { return Values.end(); }
+};
+
+SetVector<Value *> ClastStmtCodeGen::getOMPValues(const clast_stmt *Body) {
+  SetVector<Value *> Values;
+
+  // The clast variables
+  for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end(); I != E;
+       I++)
+    Values.insert(I->second);
+
+  // Find the temporaries that are referenced in the clast statements'
+  // basic blocks but are not defined by these blocks (e.g., references
+  // to function arguments or temporaries defined before the start of
+  // the SCoP).
+  ParameterVisitor Params;
+  Params.visit(Body);
+
+  for (ParameterVisitor::const_iterator PI = Params.begin(), PE = Params.end();
+       PI != PE; ++PI) {
+    Value *V = *PI;
+    Values.insert(V);
+    DEBUG(dbgs() << "Adding temporary for OMP copy-in: " << *V << "\n");
+  }
+
+  return Values;
+}
+
+void
+ClastStmtCodeGen::updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap) {
+  std::set<Value *> Inserted;
+
+  for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end(); I != E;
+       I++) {
+    ClastVars[I->first] = VMap[I->second];
+    Inserted.insert(I->second);
+  }
+
+  for (OMPGenerator::ValueToValueMapTy::iterator I = VMap.begin(),
+                                                 E = VMap.end();
+       I != E; ++I) {
+    if (Inserted.count(I->first))
+      continue;
+
+    ValueMap[I->first] = I->second;
+  }
+}
+
+static void clearDomtree(Function *F, DominatorTree &DT) {
+  DomTreeNode *N = DT.getNode(&F->getEntryBlock());
+  std::vector<BasicBlock *> Nodes;
+  for (po_iterator<DomTreeNode *> I = po_begin(N), E = po_end(N); I != E; ++I)
+    Nodes.push_back(I->getBlock());
+
+  for (std::vector<BasicBlock *>::iterator I = Nodes.begin(), E = Nodes.end();
+       I != E; ++I)
+    DT.eraseNode(*I);
+}
+
+void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) {
+  Value *Stride, *LB, *UB, *IV;
+  BasicBlock::iterator LoopBody;
+  IntegerType *IntPtrTy = getIntPtrTy();
+  SetVector<Value *> Values;
+  OMPGenerator::ValueToValueMapTy VMap;
+  OMPGenerator OMPGen(Builder, P);
+
+  Stride = Builder.getInt(APInt_from_MPZ(For->stride));
+  Stride = Builder.CreateSExtOrBitCast(Stride, IntPtrTy);
+  LB = ExpGen.codegen(For->LB, IntPtrTy);
+  UB = ExpGen.codegen(For->UB, IntPtrTy);
+
+  Values = getOMPValues(For->body);
+
+  IV = OMPGen.createParallelLoop(LB, UB, Stride, Values, VMap, &LoopBody);
+  BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
+  Builder.SetInsertPoint(LoopBody);
+
+  // Save the current values.
+  const ValueMapT ValueMapCopy = ValueMap;
+  const CharMapT ClastVarsCopy = ClastVars;
+
+  updateWithValueMap(VMap);
+  ClastVars[For->iterator] = IV;
+
+  if (For->body)
+    codegen(For->body);
+
+  // Restore the original values.
+  ValueMap = ValueMapCopy;
+  ClastVars = ClastVarsCopy;
+
+  clearDomtree((*LoopBody).getParent()->getParent(),
+               P->getAnalysis<DominatorTreeWrapperPass>().getDomTree());
+
+  Builder.SetInsertPoint(AfterLoop);
+}
+
+#ifdef GPU_CODEGEN
+static unsigned getArraySizeInBytes(const ArrayType *AT) {
+  unsigned Bytes = AT->getNumElements();
+  if (const ArrayType *T = dyn_cast<ArrayType>(AT->getElementType()))
+    Bytes *= getArraySizeInBytes(T);
+  else
+    Bytes *= AT->getElementType()->getPrimitiveSizeInBits() / 8;
+
+  return Bytes;
+}
+
+SetVector<Value *> ClastStmtCodeGen::getGPUValues(unsigned &OutputBytes) {
+  SetVector<Value *> Values;
+  OutputBytes = 0;
+
+  // Record the memory reference base addresses.
+  for (ScopStmt *Stmt : *S) {
+    for (MemoryAccess *MA : *Stmt) {
+      Value *BaseAddr = const_cast<Value *>(MA->getBaseAddr());
+      Values.insert((BaseAddr));
+
+      // FIXME: we assume that there is one and only one array to be written
+      // in a SCoP.
+      int NumWrites = 0;
+      if (MA->isWrite()) {
+        ++NumWrites;
+        assert(NumWrites <= 1 &&
+               "We support at most one array to be written in a SCoP.");
+        if (const PointerType *PT =
+                dyn_cast<PointerType>(BaseAddr->getType())) {
+          Type *T = PT->getArrayElementType();
+          const ArrayType *ATy = dyn_cast<ArrayType>(T);
+          OutputBytes = getArraySizeInBytes(ATy);
+        }
+      }
+    }
+  }
+
+  return Values;
+}
+
+const clast_stmt *ClastStmtCodeGen::getScheduleInfo(const clast_for *F,
+                                                    std::vector<int> &NumIters,
+                                                    unsigned &LoopDepth,
+                                                    unsigned &NonPLoopDepth) {
+  clast_stmt *Stmt = (clast_stmt *)F;
+  const clast_for *Result;
+  bool NonParaFlag = false;
+  LoopDepth = 0;
+  NonPLoopDepth = 0;
+
+  while (Stmt) {
+    if (CLAST_STMT_IS_A(Stmt, stmt_for)) {
+      const clast_for *T = (clast_for *)Stmt;
+      if (isParallelFor(T)) {
+        if (!NonParaFlag) {
+          NumIters.push_back(getNumberOfIterations(T));
+          Result = T;
+        }
+      } else
+        NonParaFlag = true;
+
+      Stmt = T->body;
+      LoopDepth++;
+      continue;
+    }
+    Stmt = Stmt->next;
+  }
+
+  assert(NumIters.size() == 4 &&
+         "The loops should be tiled into 4-depth parallel loops and an "
+         "innermost non-parallel one (if exist).");
+  NonPLoopDepth = LoopDepth - NumIters.size();
+  assert(NonPLoopDepth <= 1 &&
+         "We support only one innermost non-parallel loop currently.");
+  return (const clast_stmt *)Result->body;
+}
+
+void ClastStmtCodeGen::codegenForGPGPU(const clast_for *F) {
+  BasicBlock::iterator LoopBody;
+  SetVector<Value *> Values;
+  SetVector<Value *> IVS;
+  std::vector<int> NumIterations;
+  PTXGenerator::ValueToValueMapTy VMap;
+
+  assert(!GPUTriple.empty() &&
+         "Target triple should be set properly for GPGPU code generation.");
+  PTXGenerator PTXGen(Builder, P, GPUTriple);
+
+  // Get original IVS and ScopStmt
+  unsigned TiledLoopDepth, NonPLoopDepth;
+  const clast_stmt *InnerStmt =
+      getScheduleInfo(F, NumIterations, TiledLoopDepth, NonPLoopDepth);
+  const clast_stmt *TmpStmt;
+  const clast_user_stmt *U;
+  const clast_for *InnerFor;
+  if (CLAST_STMT_IS_A(InnerStmt, stmt_for)) {
+    InnerFor = (const clast_for *)InnerStmt;
+    TmpStmt = InnerFor->body;
+  } else
+    TmpStmt = InnerStmt;
+  U = (const clast_user_stmt *)TmpStmt;
+  ScopStmt *Statement = (ScopStmt *)U->statement->usr;
+  for (unsigned i = 0; i < Statement->getNumIterators() - NonPLoopDepth; i++) {
+    const Value *IV = Statement->getInductionVariableForDimension(i);
+    IVS.insert(const_cast<Value *>(IV));
+  }
+
+  unsigned OutBytes;
+  Values = getGPUValues(OutBytes);
+  PTXGen.setOutputBytes(OutBytes);
+  PTXGen.startGeneration(Values, IVS, VMap, &LoopBody);
+
+  BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
+  Builder.SetInsertPoint(LoopBody);
+
+  BasicBlock *AfterBB = 0;
+  if (NonPLoopDepth) {
+    Value *LowerBound, *UpperBound, *IV, *Stride;
+    Type *IntPtrTy = getIntPtrTy();
+    LowerBound = ExpGen.codegen(InnerFor->LB, IntPtrTy);
+    UpperBound = ExpGen.codegen(InnerFor->UB, IntPtrTy);
+    Stride = Builder.getInt(APInt_from_MPZ(InnerFor->stride));
+    IV = createLoop(LowerBound, UpperBound, Stride, Builder, P, AfterBB,
+                    CmpInst::ICMP_SLE);
+    const Value *OldIV_ = Statement->getInductionVariableForDimension(2);
+    Value *OldIV = const_cast<Value *>(OldIV_);
+    VMap.insert(std::make_pair(OldIV, IV));
+  }
+
+  updateWithValueMap(VMap);
+
+  BlockGenerator::generate(Builder, *Statement, ValueMap, LoopToScev, P);
+
+  if (AfterBB)
+    Builder.SetInsertPoint(AfterBB->begin());
+
+  // FIXME: The replacement of the host base address with the parameter of ptx
+  // subfunction should have been done by updateWithValueMap. We use the
+  // following codes to avoid affecting other parts of Polly. This should be
+  // fixed later.
+  Function *FN = Builder.GetInsertBlock()->getParent();
+  for (unsigned j = 0; j < Values.size(); j++) {
+    Value *baseAddr = Values[j];
+    for (Function::iterator B = FN->begin(); B != FN->end(); ++B) {
+      for (BasicBlock::iterator I = B->begin(); I != B->end(); ++I)
+        I->replaceUsesOfWith(baseAddr, ValueMap[baseAddr]);
+    }
+  }
+  Builder.SetInsertPoint(AfterLoop);
+  PTXGen.setLaunchingParameters(NumIterations[0], NumIterations[1],
+                                NumIterations[2], NumIterations[3]);
+  PTXGen.finishGeneration(FN);
+}
+#endif
+
+bool ClastStmtCodeGen::isInnermostLoop(const clast_for *f) {
+  const clast_stmt *stmt = f->body;
+
+  while (stmt) {
+    if (!CLAST_STMT_IS_A(stmt, stmt_user))
+      return false;
+
+    stmt = stmt->next;
+  }
+
+  return true;
+}
+
+int ClastStmtCodeGen::getNumberOfIterations(const clast_for *For) {
+  isl_set *LoopDomain = isl_set_copy(isl_set_from_cloog_domain(For->domain));
+  int NumberOfIterations = polly::getNumberOfIterations(LoopDomain);
+  if (NumberOfIterations == -1)
+    return -1;
+  return NumberOfIterations / mpz_get_si(For->stride) + 1;
+}
+
+void ClastStmtCodeGen::codegenForVector(const clast_for *F) {
+  DEBUG(dbgs() << "Vectorizing loop '" << F->iterator << "'\n";);
+  int VectorWidth = getNumberOfIterations(F);
+
+  Value *LB = ExpGen.codegen(F->LB, getIntPtrTy());
+
+  APInt Stride = APInt_from_MPZ(F->stride);
+  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 *Domain = isl_set_copy(isl_set_from_cloog_domain(F->domain));
+
+  // Add loop iv to symbols.
+  ClastVars[F->iterator] = LB;
+
+  const clast_stmt *Stmt = F->body;
+
+  while (Stmt) {
+    codegen((const clast_user_stmt *)Stmt, &IVS, F->iterator,
+            isl_set_copy(Domain));
+    Stmt = Stmt->next;
+  }
+
+  // Loop is finished, so remove its iv from the live symbols.
+  isl_set_free(Domain);
+  ClastVars.erase(F->iterator);
+}
+
+bool ClastStmtCodeGen::isParallelFor(const clast_for *f) {
+  isl_set *Domain = isl_set_copy(isl_set_from_cloog_domain(f->domain));
+  assert(Domain && "Cannot access domain of loop");
+
+  Dependences &D = P->getAnalysis<Dependences>();
+
+  return D.isParallelDimension(Domain, isl_set_n_dim(Domain));
+}
+
+void ClastStmtCodeGen::codegen(const clast_for *f) {
+  bool Vector = PollyVectorizerChoice != VECTORIZER_NONE;
+  if ((Vector || OpenMP) && isParallelFor(f)) {
+    if (Vector && isInnermostLoop(f) && (-1 != getNumberOfIterations(f)) &&
+        (getNumberOfIterations(f) <= 16)) {
+      codegenForVector(f);
+      return;
+    }
+
+    if (OpenMP && !parallelCodeGeneration) {
+      parallelCodeGeneration = true;
+      parallelLoops.push_back(f->iterator);
+      codegenForOpenMP(f);
+      parallelCodeGeneration = false;
+      return;
+    }
+  }
+
+#ifdef GPU_CODEGEN
+  if (GPGPU && isParallelFor(f)) {
+    if (!parallelCodeGeneration) {
+      parallelCodeGeneration = true;
+      parallelLoops.push_back(f->iterator);
+      codegenForGPGPU(f);
+      parallelCodeGeneration = false;
+      return;
+    }
+  }
+#endif
+
+  codegenForSequential(f);
+}
+
+Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
+  Value *LHS = ExpGen.codegen(eq->LHS, getIntPtrTy());
+  Value *RHS = ExpGen.codegen(eq->RHS, getIntPtrTy());
+  CmpInst::Predicate P;
+
+  if (eq->sign == 0)
+    P = ICmpInst::ICMP_EQ;
+  else if (eq->sign > 0)
+    P = ICmpInst::ICMP_SGE;
+  else
+    P = ICmpInst::ICMP_SLE;
+
+  return Builder.CreateICmp(P, LHS, RHS);
+}
+
+void ClastStmtCodeGen::codegen(const clast_guard *g) {
+  Function *F = Builder.GetInsertBlock()->getParent();
+  LLVMContext &Context = F->getContext();
+
+  BasicBlock *CondBB =
+      SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P);
+  CondBB->setName("polly.cond");
+  BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
+  MergeBB->setName("polly.merge");
+  BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
+
+  DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  DT.addNewBlock(ThenBB, CondBB);
+  DT.changeImmediateDominator(MergeBB, CondBB);
+
+  CondBB->getTerminator()->eraseFromParent();
+
+  Builder.SetInsertPoint(CondBB);
+
+  Value *Predicate = codegen(&(g->eq[0]));
+
+  for (int i = 1; i < g->n; ++i) {
+    Value *TmpPredicate = codegen(&(g->eq[i]));
+    Predicate = Builder.CreateAnd(Predicate, TmpPredicate);
+  }
+
+  Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
+  Builder.SetInsertPoint(ThenBB);
+  Builder.CreateBr(MergeBB);
+  Builder.SetInsertPoint(ThenBB->begin());
+
+  LoopInfo &LI = P->getAnalysis<LoopInfo>();
+  Loop *L = LI.getLoopFor(CondBB);
+  if (L)
+    L->addBasicBlockToLoop(ThenBB, LI.getBase());
+
+  codegen(g->then);
+
+  Builder.SetInsertPoint(MergeBB->begin());
+}
+
+void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
+  if (CLAST_STMT_IS_A(stmt, stmt_root))
+    assert(false && "No second root statement expected");
+  else if (CLAST_STMT_IS_A(stmt, stmt_ass))
+    codegen((const clast_assignment *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_user))
+    codegen((const clast_user_stmt *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_block))
+    codegen((const clast_block *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_for))
+    codegen((const clast_for *)stmt);
+  else if (CLAST_STMT_IS_A(stmt, stmt_guard))
+    codegen((const clast_guard *)stmt);
+
+  if (stmt->next)
+    codegen(stmt->next);
+}
+
+void ClastStmtCodeGen::addParameters(const CloogNames *names) {
+  SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
+
+  int i = 0;
+  for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
+       PI != PE; ++PI) {
+    assert(i < names->nb_parameters && "Not enough parameter names");
+
+    const SCEV *Param = *PI;
+    Type *Ty = Param->getType();
+
+    Instruction *insertLocation = --(Builder.GetInsertBlock()->end());
+    Value *V = Rewriter.expandCodeFor(Param, Ty, insertLocation);
+    ClastVars[names->parameters[i]] = V;
+
+    ++i;
+  }
+}
+
+void ClastStmtCodeGen::codegen(const clast_root *r) {
+  addParameters(r->names);
+
+  parallelCodeGeneration = false;
+
+  const clast_stmt *stmt = (const clast_stmt *)r;
+  if (stmt->next)
+    codegen(stmt->next);
+}
+
+ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, PollyIRBuilder &B, Pass *P)
+    : S(scop), P(P), Builder(B), ExpGen(Builder, ClastVars) {}
+
+namespace {
+class CodeGeneration : public ScopPass {
+  std::vector<std::string> ParallelLoops;
+
+public:
+  static char ID;
+
+  CodeGeneration() : ScopPass(ID) {}
+
+  bool runOnScop(Scop &S) {
+    ParallelLoops.clear();
+
+    assert(!S.getRegion().isTopLevelRegion() &&
+           "Top level regions are not supported");
+
+    simplifyRegion(&S, this);
+
+    BasicBlock *StartBlock = executeScopConditionally(S, this);
+
+    PollyIRBuilder Builder(StartBlock->begin());
+
+    ClastStmtCodeGen CodeGen(&S, Builder, this);
+    CloogInfo &C = getAnalysis<CloogInfo>();
+    CodeGen.codegen(C.getClast());
+
+    ParallelLoops.insert(ParallelLoops.begin(),
+                         CodeGen.getParallelLoops().begin(),
+                         CodeGen.getParallelLoops().end());
+    return true;
+  }
+
+  virtual void printScop(raw_ostream &OS) const {
+    for (std::vector<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<DominatorTreeWrapperPass>();
+    AU.addRequired<RegionInfoPass>();
+    AU.addRequired<ScalarEvolution>();
+    AU.addRequired<ScopDetection>();
+    AU.addRequired<ScopInfo>();
+    AU.addRequired<DataLayoutPass>();
+    AU.addRequired<LoopInfo>();
+
+    AU.addPreserved<CloogInfo>();
+    AU.addPreserved<Dependences>();
+    AU.addPreserved<LoopInfo>();
+    AU.addPreserved<DominatorTreeWrapperPass>();
+    AU.addPreserved<ScopDetection>();
+    AU.addPreserved<ScalarEvolution>();
+
+    // FIXME: We do not yet add regions for the newly generated code to the
+    //        region tree.
+    AU.addPreserved<RegionInfoPass>();
+    AU.addPreserved<TempScopInfo>();
+    AU.addPreserved<ScopInfo>();
+    AU.addPreservedID(IndependentBlocksID);
+  }
+};
+}
+
+char CodeGeneration::ID = 1;
+
+Pass *polly::createCodeGenerationPass() { return new CodeGeneration(); }
+
+INITIALIZE_PASS_BEGIN(CodeGeneration, "polly-codegen",
+                      "Polly - Create LLVM-IR from SCoPs", false, false);
+INITIALIZE_PASS_DEPENDENCY(CloogInfo);
+INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
+INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
+INITIALIZE_PASS_DEPENDENCY(ScopDetection);
+INITIALIZE_PASS_DEPENDENCY(DataLayoutPass);
+INITIALIZE_PASS_END(CodeGeneration, "polly-codegen",
+                    "Polly - Create LLVM-IR from SCoPs", false, false)
+
+#endif // CLOOG_FOUND
diff --git a/rc1/lib/CodeGen/IRBuilder.cpp b/rc1/lib/CodeGen/IRBuilder.cpp
new file mode 100644
index 0000000..5347ba9
--- /dev/null
+++ b/rc1/lib/CodeGen/IRBuilder.cpp
@@ -0,0 +1,60 @@
+//===------ PollyIRBuilder.cpp --------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The Polly IRBuilder file contains Polly specific extensions for the IRBuilder
+// that are used e.g. to emit the llvm.loop.parallel metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/CodeGen/IRBuilder.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+using namespace polly;
+
+llvm::MDNode *polly::PollyLoopInfo::GetLoopID() const {
+  if (LoopID)
+    return LoopID;
+
+  llvm::Value *Args[] = {0};
+  LoopID = llvm::MDNode::get(Header->getContext(), Args);
+  LoopID->replaceOperandWith(0, LoopID);
+  return LoopID;
+}
+
+void polly::LoopAnnotator::Begin(llvm::BasicBlock *Header) {
+  Active.push_back(PollyLoopInfo(Header));
+}
+
+void polly::LoopAnnotator::End() { Active.pop_back(); }
+
+void polly::LoopAnnotator::SetCurrentParallel() {
+  Active.back().SetParallel(true);
+}
+
+void polly::LoopAnnotator::Annotate(llvm::Instruction *Inst) {
+  if (Active.empty())
+    return;
+
+  const PollyLoopInfo &L = Active.back();
+  if (!L.IsParallel())
+    return;
+
+  if (TerminatorInst *TI = dyn_cast<llvm::TerminatorInst>(Inst)) {
+    for (unsigned i = 0, ie = TI->getNumSuccessors(); i != ie; ++i)
+      if (TI->getSuccessor(i) == L.GetHeader()) {
+        TI->setMetadata("llvm.loop", L.GetLoopID());
+        break;
+      }
+  } else if (Inst->mayReadOrWriteMemory()) {
+    Inst->setMetadata("llvm.mem.parallel_loop_access", L.GetLoopID());
+  }
+}
diff --git a/rc1/lib/CodeGen/IslAst.cpp b/rc1/lib/CodeGen/IslAst.cpp
new file mode 100644
index 0000000..6479e8d
--- /dev/null
+++ b/rc1/lib/CodeGen/IslAst.cpp
@@ -0,0 +1,543 @@
+//===- IslAst.cpp - isl code generator interface --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The isl code generator interface takes a Scop and generates a isl_ast. This
+// ist_ast can either be returned directly or it can be pretty printed to
+// stdout.
+//
+// A typical isl_ast output looks like this:
+//
+// for (c2 = max(0, ceild(n + m, 2); c2 <= min(511, floord(5 * n, 3)); c2++) {
+//   bb2(c2);
+// }
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/CodeGen/IslAst.h"
+#include "polly/Dependences.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
+#include "polly/ScopInfo.h"
+#include "llvm/Support/Debug.h"
+
+#include "isl/union_map.h"
+#include "isl/list.h"
+#include "isl/ast_build.h"
+#include "isl/set.h"
+#include "isl/map.h"
+#include "isl/aff.h"
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-ast"
+
+static cl::opt<bool> UseContext("polly-ast-use-context",
+                                cl::desc("Use context"), cl::Hidden,
+                                cl::init(false), cl::ZeroOrMore,
+                                cl::cat(PollyCategory));
+
+static cl::opt<bool> DetectParallel("polly-ast-detect-parallel",
+                                    cl::desc("Detect parallelism"), cl::Hidden,
+                                    cl::init(false), cl::ZeroOrMore,
+                                    cl::cat(PollyCategory));
+
+namespace polly {
+class IslAst {
+public:
+  IslAst(Scop *Scop, Dependences &D);
+
+  ~IslAst();
+
+  /// Print a source code representation of the program.
+  void pprint(llvm::raw_ostream &OS);
+
+  __isl_give isl_ast_node *getAst();
+
+  /// @brief Get the run-time conditions for the Scop.
+  __isl_give isl_ast_expr *getRunCondition();
+
+private:
+  Scop *S;
+  isl_ast_node *Root;
+  isl_ast_expr *RunCondition;
+
+  void buildRunCondition(__isl_keep isl_ast_build *Context);
+};
+} // End namespace polly.
+
+// Temporary information used when building the ast.
+struct AstBuildUserInfo {
+  // The dependence information.
+  Dependences *Deps;
+
+  // We are inside a parallel for node.
+  int InParallelFor;
+};
+
+// Print a loop annotated with OpenMP or vector pragmas.
+static __isl_give isl_printer *
+printParallelFor(__isl_keep isl_ast_node *Node, __isl_take isl_printer *Printer,
+                 __isl_take isl_ast_print_options *PrintOptions,
+                 IslAstUserPayload *Info) {
+  if (Info) {
+    if (Info->IsInnermostParallel) {
+      Printer = isl_printer_start_line(Printer);
+      Printer = isl_printer_print_str(Printer, "#pragma simd");
+      if (Info->IsReductionParallel)
+        Printer = isl_printer_print_str(Printer, " reduction");
+      Printer = isl_printer_end_line(Printer);
+    }
+    if (Info->IsOutermostParallel) {
+      Printer = isl_printer_start_line(Printer);
+      Printer = isl_printer_print_str(Printer, "#pragma omp parallel for");
+      if (Info->IsReductionParallel)
+        Printer = isl_printer_print_str(Printer, " reduction");
+      Printer = isl_printer_end_line(Printer);
+    }
+  }
+  return isl_ast_node_for_print(Node, Printer, PrintOptions);
+}
+
+// Print an isl_ast_for.
+static __isl_give isl_printer *
+printFor(__isl_take isl_printer *Printer,
+         __isl_take isl_ast_print_options *PrintOptions,
+         __isl_keep isl_ast_node *Node, void *User) {
+  isl_id *Id = isl_ast_node_get_annotation(Node);
+  if (!Id)
+    return isl_ast_node_for_print(Node, Printer, PrintOptions);
+
+  struct IslAstUserPayload *Info =
+      (struct IslAstUserPayload *)isl_id_get_user(Id);
+  Printer = printParallelFor(Node, Printer, PrintOptions, Info);
+  isl_id_free(Id);
+  return Printer;
+}
+
+// Allocate an AstNodeInfo structure and initialize it with default values.
+static struct IslAstUserPayload *allocateIslAstUser() {
+  struct IslAstUserPayload *NodeInfo;
+  NodeInfo =
+      (struct IslAstUserPayload *)malloc(sizeof(struct IslAstUserPayload));
+  NodeInfo->Context = 0;
+  NodeInfo->IsOutermostParallel = 0;
+  NodeInfo->IsInnermostParallel = 0;
+  NodeInfo->IsReductionParallel = false;
+  return NodeInfo;
+}
+
+// Free the AstNodeInfo structure.
+static void freeIslAstUser(void *Ptr) {
+  struct IslAstUserPayload *UserStruct = (struct IslAstUserPayload *)Ptr;
+  isl_ast_build_free(UserStruct->Context);
+  free(UserStruct);
+}
+
+// Check if the current scheduling dimension is parallel.
+//
+// We check for parallelism by verifying that the loop does not carry any
+// dependences.
+//
+// Parallelism test: if the distance is zero in all outer dimensions, then it
+// has to be zero in the current dimension as well.
+//
+// Implementation: first, translate dependences into time space, then force
+// outer dimensions to be equal. If the distance is zero in the current
+// dimension, then the loop is parallel. The distance is zero in the current
+// dimension if it is a subset of a map with equal values for the current
+// dimension.
+static bool astScheduleDimIsParallel(__isl_keep isl_ast_build *Build,
+                                     __isl_take isl_union_map *Deps) {
+  isl_union_map *Schedule;
+  isl_map *ScheduleDeps, *Test;
+  isl_space *ScheduleSpace;
+  unsigned Dimension, IsParallel;
+
+  Schedule = isl_ast_build_get_schedule(Build);
+  ScheduleSpace = isl_ast_build_get_schedule_space(Build);
+
+  Dimension = isl_space_dim(ScheduleSpace, isl_dim_out) - 1;
+
+  Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(Schedule));
+  Deps = isl_union_map_apply_domain(Deps, Schedule);
+
+  if (isl_union_map_is_empty(Deps)) {
+    isl_union_map_free(Deps);
+    isl_space_free(ScheduleSpace);
+    return true;
+  }
+
+  ScheduleDeps = isl_map_from_union_map(Deps);
+
+  for (unsigned i = 0; i < Dimension; i++)
+    ScheduleDeps = isl_map_equate(ScheduleDeps, isl_dim_out, i, isl_dim_in, i);
+
+  Test = isl_map_universe(isl_map_get_space(ScheduleDeps));
+  Test = isl_map_equate(Test, isl_dim_out, Dimension, isl_dim_in, Dimension);
+  IsParallel = isl_map_is_subset(ScheduleDeps, Test);
+
+  isl_space_free(ScheduleSpace);
+  isl_map_free(Test);
+  isl_map_free(ScheduleDeps);
+
+  return IsParallel;
+}
+
+/// @brief Check if the current scheduling dimension is parallel
+///
+/// In case the dimension is parallel we also check if any reduction
+/// dependences is broken when we exploit this parallelism. If so,
+/// @p IsReductionParallel will be set to true. The reduction dependences we use
+/// to check are actually the union of the transitive closure of the initial
+/// reduction dependences together with their reveresal. Even though these
+/// dependences connect all iterations with each other (thus they are cyclic)
+/// we can perform the parallelism check as we are only interested in a zero
+/// (or non-zero) dependence distance on the dimension in question.
+static bool astScheduleDimIsParallel(__isl_keep isl_ast_build *Build,
+                                     Dependences *D,
+                                     bool &IsReductionParallel) {
+  if (!D->hasValidDependences())
+    return false;
+
+  isl_union_map *Deps = D->getDependences(
+      Dependences::TYPE_RAW | Dependences::TYPE_WAW | Dependences::TYPE_WAR);
+  if (!astScheduleDimIsParallel(Build, Deps))
+    return false;
+
+  isl_union_map *RedDeps = D->getDependences(Dependences::TYPE_TC_RED);
+  if (!astScheduleDimIsParallel(Build, RedDeps))
+    IsReductionParallel = true;
+
+  return true;
+}
+
+// Mark a for node openmp parallel, if it is the outermost parallel for node.
+static void markOpenmpParallel(__isl_keep isl_ast_build *Build,
+                               struct AstBuildUserInfo *BuildInfo,
+                               struct IslAstUserPayload *NodeInfo) {
+  if (BuildInfo->InParallelFor)
+    return;
+
+  if (astScheduleDimIsParallel(Build, BuildInfo->Deps,
+                               NodeInfo->IsReductionParallel)) {
+    BuildInfo->InParallelFor = 1;
+    NodeInfo->IsOutermostParallel = 1;
+  }
+}
+
+// This method is executed before the construction of a for node. It creates
+// an isl_id that is used to annotate the subsequently generated ast for nodes.
+//
+// In this function we also run the following analyses:
+//
+// - Detection of openmp parallel loops
+//
+static __isl_give isl_id *astBuildBeforeFor(__isl_keep isl_ast_build *Build,
+                                            void *User) {
+  struct AstBuildUserInfo *BuildInfo = (struct AstBuildUserInfo *)User;
+  struct IslAstUserPayload *NodeInfo = allocateIslAstUser();
+  isl_id *Id = isl_id_alloc(isl_ast_build_get_ctx(Build), "", NodeInfo);
+  Id = isl_id_set_free_user(Id, freeIslAstUser);
+
+  markOpenmpParallel(Build, BuildInfo, NodeInfo);
+
+  return Id;
+}
+
+// Returns 0 when Node contains loops, otherwise returns -1. This search
+// function uses ISL's way to iterate over lists of isl_ast_nodes with
+// isl_ast_node_list_foreach. Please use the single argument wrapper function
+// that returns a bool instead of using this function directly.
+static int containsLoops(__isl_take isl_ast_node *Node, void *User) {
+  if (!Node)
+    return -1;
+
+  switch (isl_ast_node_get_type(Node)) {
+  case isl_ast_node_for:
+    isl_ast_node_free(Node);
+    return 0;
+  case isl_ast_node_block: {
+    isl_ast_node_list *List = isl_ast_node_block_get_children(Node);
+    int Res = isl_ast_node_list_foreach(List, &containsLoops, nullptr);
+    isl_ast_node_list_free(List);
+    isl_ast_node_free(Node);
+    return Res;
+  }
+  case isl_ast_node_if: {
+    int Res = -1;
+    if (0 == containsLoops(isl_ast_node_if_get_then(Node), nullptr) ||
+        (isl_ast_node_if_has_else(Node) &&
+         0 == containsLoops(isl_ast_node_if_get_else(Node), nullptr)))
+      Res = 0;
+    isl_ast_node_free(Node);
+    return Res;
+  }
+  case isl_ast_node_user:
+  default:
+    isl_ast_node_free(Node);
+    return -1;
+  }
+}
+
+// Returns true when Node contains loops.
+static bool containsLoops(__isl_take isl_ast_node *Node) {
+  return 0 == containsLoops(Node, nullptr);
+}
+
+// This method is executed after the construction of a for node.
+//
+// It performs the following actions:
+//
+// - Reset the 'InParallelFor' flag, as soon as we leave a for node,
+//   that is marked as openmp parallel.
+//
+static __isl_give isl_ast_node *
+astBuildAfterFor(__isl_take isl_ast_node *Node, __isl_keep isl_ast_build *Build,
+                 void *User) {
+  isl_id *Id = isl_ast_node_get_annotation(Node);
+  if (!Id)
+    return Node;
+  struct IslAstUserPayload *Info =
+      (struct IslAstUserPayload *)isl_id_get_user(Id);
+  struct AstBuildUserInfo *BuildInfo = (struct AstBuildUserInfo *)User;
+
+  if (Info) {
+    if (Info->IsOutermostParallel)
+      BuildInfo->InParallelFor = 0;
+    if (!containsLoops(isl_ast_node_for_get_body(Node)))
+      if (astScheduleDimIsParallel(Build, BuildInfo->Deps,
+                                   Info->IsReductionParallel))
+        Info->IsInnermostParallel = 1;
+    if (!Info->Context)
+      Info->Context = isl_ast_build_copy(Build);
+  }
+
+  isl_id_free(Id);
+  return Node;
+}
+
+static __isl_give isl_ast_node *AtEachDomain(__isl_take isl_ast_node *Node,
+                                             __isl_keep isl_ast_build *Context,
+                                             void *User) {
+  struct IslAstUserPayload *Info = nullptr;
+  isl_id *Id = isl_ast_node_get_annotation(Node);
+
+  if (Id)
+    Info = (struct IslAstUserPayload *)isl_id_get_user(Id);
+
+  if (!Info) {
+    // Allocate annotations once: parallel for detection might have already
+    // allocated the annotations for this node.
+    Info = allocateIslAstUser();
+    Id = isl_id_alloc(isl_ast_node_get_ctx(Node), nullptr, Info);
+    Id = isl_id_set_free_user(Id, &freeIslAstUser);
+  }
+
+  if (!Info->Context)
+    Info->Context = isl_ast_build_copy(Context);
+
+  return isl_ast_node_set_annotation(Node, Id);
+}
+
+void IslAst::buildRunCondition(__isl_keep isl_ast_build *Context) {
+  // The conditions that need to be checked at run-time for this scop are
+  // available as an isl_set in the AssumedContext. We generate code for this
+  // check as follows. First, we generate an isl_pw_aff that is 1, if a certain
+  // combination of parameter values fulfills the conditions in the assumed
+  // context, and that is 0 otherwise. We then translate this isl_pw_aff into
+  // an isl_ast_expr. At run-time this expression can be evaluated and the
+  // optimized scop can be executed conditionally according to the result of the
+  // run-time check.
+
+  isl_aff *Zero =
+      isl_aff_zero_on_domain(isl_local_space_from_space(S->getParamSpace()));
+  isl_aff *One =
+      isl_aff_zero_on_domain(isl_local_space_from_space(S->getParamSpace()));
+
+  One = isl_aff_add_constant_si(One, 1);
+
+  isl_pw_aff *PwZero = isl_pw_aff_from_aff(Zero);
+  isl_pw_aff *PwOne = isl_pw_aff_from_aff(One);
+
+  PwOne = isl_pw_aff_intersect_domain(PwOne, S->getAssumedContext());
+  PwZero = isl_pw_aff_intersect_domain(
+      PwZero, isl_set_complement(S->getAssumedContext()));
+
+  isl_pw_aff *Cond = isl_pw_aff_union_max(PwOne, PwZero);
+
+  RunCondition = isl_ast_build_expr_from_pw_aff(Context, Cond);
+}
+
+IslAst::IslAst(Scop *Scop, Dependences &D) : S(Scop) {
+  isl_ctx *Ctx = S->getIslCtx();
+  isl_options_set_ast_build_atomic_upper_bound(Ctx, true);
+  isl_ast_build *Context;
+  struct AstBuildUserInfo BuildInfo;
+
+  if (UseContext)
+    Context = isl_ast_build_from_context(S->getContext());
+  else
+    Context = isl_ast_build_from_context(isl_set_universe(S->getParamSpace()));
+
+  Context = isl_ast_build_set_at_each_domain(Context, AtEachDomain, nullptr);
+
+  isl_union_map *Schedule =
+      isl_union_map_intersect_domain(S->getSchedule(), S->getDomains());
+
+  Function *F = Scop->getRegion().getEntry()->getParent();
+  (void)F;
+
+  DEBUG(dbgs() << ":: isl ast :: " << F->getName()
+               << " :: " << Scop->getRegion().getNameStr() << "\n");
+
+  DEBUG(dbgs() << S->getContextStr() << "\n"; isl_union_map_dump(Schedule));
+
+  if (DetectParallel || PollyVectorizerChoice != VECTORIZER_NONE) {
+    BuildInfo.Deps = &D;
+    BuildInfo.InParallelFor = 0;
+
+    Context = isl_ast_build_set_before_each_for(Context, &astBuildBeforeFor,
+                                                &BuildInfo);
+    Context = isl_ast_build_set_after_each_for(Context, &astBuildAfterFor,
+                                               &BuildInfo);
+  }
+
+  buildRunCondition(Context);
+
+  Root = isl_ast_build_ast_from_schedule(Context, Schedule);
+
+  isl_ast_build_free(Context);
+
+  DEBUG(pprint(dbgs()));
+}
+
+IslAst::~IslAst() {
+  isl_ast_node_free(Root);
+  isl_ast_expr_free(RunCondition);
+}
+
+/// Print a C like representation of the program.
+void IslAst::pprint(llvm::raw_ostream &OS) {
+  isl_ast_node *Root;
+  isl_ast_print_options *Options;
+
+  Options = isl_ast_print_options_alloc(S->getIslCtx());
+  Options = isl_ast_print_options_set_print_for(Options, &printFor, nullptr);
+
+  isl_printer *P = isl_printer_to_str(S->getIslCtx());
+  P = isl_printer_set_output_format(P, ISL_FORMAT_C);
+
+  P = isl_printer_print_ast_expr(P, RunCondition);
+  char *result = isl_printer_get_str(P);
+  P = isl_printer_flush(P);
+
+  OS << "\nif (" << result << ")\n\n";
+  P = isl_printer_indent(P, 4);
+
+  Root = getAst();
+  P = isl_ast_node_print(Root, P, Options);
+  result = isl_printer_get_str(P);
+  OS << result << "\n";
+  OS << "else\n";
+  OS << "    {  /* original code */ }\n\n";
+  isl_printer_free(P);
+  isl_ast_node_free(Root);
+}
+
+__isl_give isl_ast_node *IslAst::getAst() { return isl_ast_node_copy(Root); }
+__isl_give isl_ast_expr *IslAst::getRunCondition() {
+  return isl_ast_expr_copy(RunCondition);
+}
+
+void IslAstInfo::pprint(llvm::raw_ostream &OS) { Ast->pprint(OS); }
+
+void IslAstInfo::releaseMemory() {
+  if (Ast) {
+    delete Ast;
+    Ast = 0;
+  }
+}
+
+bool IslAstInfo::runOnScop(Scop &Scop) {
+  if (Ast)
+    delete Ast;
+
+  S = &Scop;
+
+  Dependences &D = getAnalysis<Dependences>();
+
+  Ast = new IslAst(&Scop, D);
+
+  return false;
+}
+
+__isl_give isl_ast_node *IslAstInfo::getAst() { return Ast->getAst(); }
+__isl_give isl_ast_expr *IslAstInfo::getRunCondition() {
+  return Ast->getRunCondition();
+}
+
+void IslAstInfo::printScop(raw_ostream &OS) const {
+  Function *F = S->getRegion().getEntry()->getParent();
+
+  OS << F->getName() << "():\n";
+
+  Ast->pprint(OS);
+}
+
+IslAstUserPayload *IslAstInfo::getNodePayload(__isl_keep isl_ast_node *Node) {
+  isl_id *Id = isl_ast_node_get_annotation(Node);
+  if (!Id)
+    return nullptr;
+  IslAstUserPayload *Payload = (IslAstUserPayload *)isl_id_get_user(Id);
+  isl_id_free(Id);
+  return Payload;
+}
+
+bool IslAstInfo::isParallel(__isl_keep isl_ast_node *Node) {
+  return (isInnermostParallel(Node) || isOuterParallel(Node)) &&
+         !isReductionParallel(Node);
+}
+
+bool IslAstInfo::isInnermostParallel(__isl_keep isl_ast_node *Node) {
+  IslAstUserPayload *Payload = getNodePayload(Node);
+  return Payload && Payload->IsInnermostParallel &&
+         !Payload->IsReductionParallel;
+}
+
+bool IslAstInfo::isOuterParallel(__isl_keep isl_ast_node *Node) {
+  IslAstUserPayload *Payload = getNodePayload(Node);
+  return Payload && Payload->IsOutermostParallel &&
+         !Payload->IsReductionParallel;
+}
+
+bool IslAstInfo::isReductionParallel(__isl_keep isl_ast_node *Node) {
+  IslAstUserPayload *Payload = getNodePayload(Node);
+  return Payload && Payload->IsReductionParallel;
+}
+
+void IslAstInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+  // Get the Common analysis usage of ScopPasses.
+  ScopPass::getAnalysisUsage(AU);
+  AU.addRequired<ScopInfo>();
+  AU.addRequired<Dependences>();
+}
+
+char IslAstInfo::ID = 0;
+
+Pass *polly::createIslAstInfoPass() { return new IslAstInfo(); }
+
+INITIALIZE_PASS_BEGIN(IslAstInfo, "polly-ast",
+                      "Polly - Generate an AST of the SCoP (isl)", false,
+                      false);
+INITIALIZE_PASS_DEPENDENCY(ScopInfo);
+INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_END(IslAstInfo, "polly-ast",
+                    "Polly - Generate an AST from the SCoP (isl)", false, false)
diff --git a/rc1/lib/CodeGen/IslCodeGeneration.cpp b/rc1/lib/CodeGen/IslCodeGeneration.cpp
new file mode 100644
index 0000000..4eb39cc
--- /dev/null
+++ b/rc1/lib/CodeGen/IslCodeGeneration.cpp
@@ -0,0 +1,1216 @@
+//===------ IslCodeGeneration.cpp - Code generate the Scops using ISL. ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The IslCodeGeneration pass takes a Scop created by ScopInfo and translates it
+// back to LLVM-IR using the ISL code generator.
+//
+// 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. ISL is used to generate an abstract syntax tree that reflects
+// the updated execution order. This clast is used to create new LLVM-IR that is
+// computationally equivalent to the original control flow region, but executes
+// its code in the new execution order defined by the changed scattering.
+//
+//===----------------------------------------------------------------------===//
+#include "polly/Config/config.h"
+#include "polly/CodeGen/BlockGenerators.h"
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/CodeGen/IslAst.h"
+#include "polly/CodeGen/LoopGenerators.h"
+#include "polly/CodeGen/Utils.h"
+#include "polly/Dependences.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopInfo.h"
+#include "polly/Support/GICHelper.h"
+#include "polly/Support/ScopHelper.h"
+#include "polly/TempScopInfo.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+#include "isl/union_map.h"
+#include "isl/list.h"
+#include "isl/ast.h"
+#include "isl/ast_build.h"
+#include "isl/set.h"
+#include "isl/map.h"
+#include "isl/aff.h"
+
+#include <map>
+
+using namespace polly;
+using namespace llvm;
+
+#define DEBUG_TYPE "polly-codegen-isl"
+
+/// @brief Insert function calls that print certain LLVM values at run time.
+///
+/// This class inserts libc function calls to print certain LLVM values at
+/// run time.
+class RuntimeDebugBuilder {
+public:
+  RuntimeDebugBuilder(PollyIRBuilder &Builder) : Builder(Builder) {}
+
+  /// @brief Print a string to stdout.
+  ///
+  /// @param String The string to print.
+  void createStrPrinter(std::string String);
+
+  /// @brief Print an integer value to stdout.
+  ///
+  /// @param V The value to print.
+  void createIntPrinter(Value *V);
+
+private:
+  PollyIRBuilder &Builder;
+
+  /// @brief Add a call to the fflush function with no file pointer given.
+  ///
+  /// This call will flush all opened file pointers including stdout and stderr.
+  void createFlush();
+
+  /// @brief Get a reference to the 'printf' function.
+  ///
+  /// If the current module does not yet contain a reference to printf, we
+  /// insert a reference to it. Otherwise the existing reference is returned.
+  Function *getPrintF();
+};
+
+Function *RuntimeDebugBuilder::getPrintF() {
+  Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+  const char *Name = "printf";
+  Function *F = M->getFunction(Name);
+
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    FunctionType *Ty =
+        FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), true);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  return F;
+}
+
+void RuntimeDebugBuilder::createFlush() {
+  Module *M = Builder.GetInsertBlock()->getParent()->getParent();
+  const char *Name = "fflush";
+  Function *F = M->getFunction(Name);
+
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    FunctionType *Ty =
+        FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall(F, Constant::getNullValue(Builder.getInt8PtrTy()));
+}
+
+void RuntimeDebugBuilder::createStrPrinter(std::string String) {
+  Function *F = getPrintF();
+  Value *StringValue = Builder.CreateGlobalStringPtr(String);
+  Builder.CreateCall(F, StringValue);
+
+  createFlush();
+}
+
+void RuntimeDebugBuilder::createIntPrinter(Value *V) {
+  IntegerType *Ty = dyn_cast<IntegerType>(V->getType());
+  (void)Ty;
+  assert(Ty && Ty->getBitWidth() == 64 &&
+         "Cannot insert printer for this type.");
+
+  Function *F = getPrintF();
+  Value *String = Builder.CreateGlobalStringPtr("%ld");
+  Builder.CreateCall2(F, String, V);
+  createFlush();
+}
+
+/// @brief LLVM-IR generator for isl_ast_expr[essions]
+///
+/// This generator generates LLVM-IR that performs the computation described by
+/// an isl_ast_expr[ession].
+///
+/// Example:
+///
+///   An isl_ast_expr[ession] can look like this:
+///
+///     (N + M) + 10
+///
+///   The IslExprBuilder could create the following LLVM-IR:
+///
+///     %tmp1 = add nsw i64 %N
+///     %tmp2 = add nsw i64 %tmp1, %M
+///     %tmp3 = add nsw i64 %tmp2, 10
+///
+/// The implementation of this class is mostly a mapping from isl_ast_expr
+/// constructs to the corresponding LLVM-IR constructs.
+///
+/// The following decisions may need some explanation:
+///
+/// 1) Which data-type to choose
+///
+/// isl_ast_expr[essions] are untyped expressions that assume arbitrary
+/// precision integer computations. LLVM-IR instead has fixed size integers.
+/// When lowering to LLVM-IR we need to chose both the size of the data type and
+/// the sign of the operations we use.
+///
+/// At the moment, we hardcode i64 bit signed computations. Our experience has
+/// shown that 64 bit are generally large enough for the loop bounds that appear
+/// in the wild. Signed computations are needed, as loop bounds may become
+/// negative.
+///
+/// FIXME: Hardcoding sizes can cause issues:
+///
+///   a) Certain run-time checks that we may want to generate can involve the
+///      size of the data types the computation is performed on. When code
+///      generating these run-time checks to isl_ast_expr[essions], the
+///      resulting computation may require more than 64 bit.
+///
+///   b) On embedded systems and especially for high-level-synthesis 64 bit
+///      computations are very costly.
+///
+///   The right approach is to compute the minimal necessary bitwidth and
+///   signedness for each subexpression during in the isl AST generation and
+///   to use this information in our IslAstGenerator. Preliminary patches are
+///   available, but have not been committed yet.
+///
+/// 2) We always flag computations with 'nsw'
+///
+/// As isl_ast_expr[essions] assume arbitrary precision, no wrapping should
+/// ever occur in the generated LLVM-IR (assuming the data type chosen is large
+/// enough).
+class IslExprBuilder {
+public:
+  /// @brief Construct an IslExprBuilder.
+  ///
+  /// @param Builder The IRBuilder used to construct the isl_ast_expr[ession].
+  ///                The insert location of this IRBuilder defines WHERE the
+  ///                corresponding LLVM-IR is generated.
+  ///
+  /// @param IDToValue The isl_ast_expr[ession] may reference parameters or
+  ///                  variables (identified by an isl_id). The IDTOValue map
+  ///                  specifies the LLVM-IR Values that correspond to these
+  ///                  parameters and variables.
+  IslExprBuilder(PollyIRBuilder &Builder,
+                 std::map<isl_id *, Value *> &IDToValue)
+      : Builder(Builder), IDToValue(IDToValue) {}
+
+  /// @brief Create LLVM-IR for an isl_ast_expr[ession].
+  ///
+  /// @param Expr The ast expression for which we generate LLVM-IR.
+  ///
+  /// @return The llvm::Value* containing the result of the computation.
+  Value *create(__isl_take isl_ast_expr *Expr);
+
+  /// @brief Return the largest of two types.
+  ///
+  /// @param T1 The first type.
+  /// @param T2 The second type.
+  ///
+  /// @return The largest of the two types.
+  Type *getWidestType(Type *T1, Type *T2);
+
+  /// @brief Return the type with which this expression should be computed.
+  ///
+  /// The type needs to be large enough to hold all possible input and all
+  /// possible output values.
+  ///
+  /// @param Expr The expression for which to find the type.
+  /// @return The type with which the expression should be computed.
+  IntegerType *getType(__isl_keep isl_ast_expr *Expr);
+
+private:
+  PollyIRBuilder &Builder;
+  std::map<isl_id *, Value *> &IDToValue;
+
+  Value *createOp(__isl_take isl_ast_expr *Expr);
+  Value *createOpUnary(__isl_take isl_ast_expr *Expr);
+  Value *createOpBin(__isl_take isl_ast_expr *Expr);
+  Value *createOpNAry(__isl_take isl_ast_expr *Expr);
+  Value *createOpSelect(__isl_take isl_ast_expr *Expr);
+  Value *createOpICmp(__isl_take isl_ast_expr *Expr);
+  Value *createOpBoolean(__isl_take isl_ast_expr *Expr);
+  Value *createId(__isl_take isl_ast_expr *Expr);
+  Value *createInt(__isl_take isl_ast_expr *Expr);
+};
+
+Type *IslExprBuilder::getWidestType(Type *T1, Type *T2) {
+  assert(isa<IntegerType>(T1) && isa<IntegerType>(T2));
+
+  if (T1->getPrimitiveSizeInBits() < T2->getPrimitiveSizeInBits())
+    return T2;
+  else
+    return T1;
+}
+
+Value *IslExprBuilder::createOpUnary(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_minus &&
+         "Unsupported unary operation");
+
+  Value *V;
+  Type *MaxType = getType(Expr);
+
+  V = create(isl_ast_expr_get_op_arg(Expr, 0));
+  MaxType = getWidestType(MaxType, V->getType());
+
+  if (MaxType != V->getType())
+    V = Builder.CreateSExt(V, MaxType);
+
+  isl_ast_expr_free(Expr);
+  return Builder.CreateNSWNeg(V);
+}
+
+Value *IslExprBuilder::createOpNAry(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
+         "isl ast expression not of type isl_ast_op");
+  assert(isl_ast_expr_get_op_n_arg(Expr) >= 2 &&
+         "We need at least two operands in an n-ary operation");
+
+  Value *V;
+
+  V = create(isl_ast_expr_get_op_arg(Expr, 0));
+
+  for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr); ++i) {
+    Value *OpV;
+    OpV = create(isl_ast_expr_get_op_arg(Expr, i));
+
+    Type *Ty = getWidestType(V->getType(), OpV->getType());
+
+    if (Ty != OpV->getType())
+      OpV = Builder.CreateSExt(OpV, Ty);
+
+    if (Ty != V->getType())
+      V = Builder.CreateSExt(V, Ty);
+
+    switch (isl_ast_expr_get_op_type(Expr)) {
+    default:
+      llvm_unreachable("This is no n-ary isl ast expression");
+
+    case isl_ast_op_max: {
+      Value *Cmp = Builder.CreateICmpSGT(V, OpV);
+      V = Builder.CreateSelect(Cmp, V, OpV);
+      continue;
+    }
+    case isl_ast_op_min: {
+      Value *Cmp = Builder.CreateICmpSLT(V, OpV);
+      V = Builder.CreateSelect(Cmp, V, OpV);
+      continue;
+    }
+    }
+  }
+
+  // TODO: We can truncate the result, if it fits into a smaller type. This can
+  // help in cases where we have larger operands (e.g. i67) but the result is
+  // known to fit into i64. Without the truncation, the larger i67 type may
+  // force all subsequent operations to be performed on a non-native type.
+  isl_ast_expr_free(Expr);
+  return V;
+}
+
+Value *IslExprBuilder::createOpBin(__isl_take isl_ast_expr *Expr) {
+  Value *LHS, *RHS, *Res;
+  Type *MaxType;
+  isl_ast_op_type OpType;
+
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
+         "isl ast expression not of type isl_ast_op");
+  assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
+         "not a binary isl ast expression");
+
+  OpType = isl_ast_expr_get_op_type(Expr);
+
+  LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
+  RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
+
+  MaxType = LHS->getType();
+  MaxType = getWidestType(MaxType, RHS->getType());
+
+  // Take the result into account when calculating the widest type.
+  //
+  // For operations such as '+' the result may require a type larger than
+  // the type of the individual operands. For other operations such as '/', the
+  // result type cannot be larger than the type of the individual operand. isl
+  // does not calculate correct types for these operations and we consequently
+  // exclude those operations here.
+  switch (OpType) {
+  case isl_ast_op_pdiv_q:
+  case isl_ast_op_pdiv_r:
+  case isl_ast_op_div:
+  case isl_ast_op_fdiv_q:
+    // Do nothing
+    break;
+  case isl_ast_op_add:
+  case isl_ast_op_sub:
+  case isl_ast_op_mul:
+    MaxType = getWidestType(MaxType, getType(Expr));
+    break;
+  default:
+    llvm_unreachable("This is no binary isl ast expression");
+  }
+
+  if (MaxType != RHS->getType())
+    RHS = Builder.CreateSExt(RHS, MaxType);
+
+  if (MaxType != LHS->getType())
+    LHS = Builder.CreateSExt(LHS, MaxType);
+
+  switch (OpType) {
+  default:
+    llvm_unreachable("This is no binary isl ast expression");
+  case isl_ast_op_add:
+    Res = Builder.CreateNSWAdd(LHS, RHS);
+    break;
+  case isl_ast_op_sub:
+    Res = Builder.CreateNSWSub(LHS, RHS);
+    break;
+  case isl_ast_op_mul:
+    Res = Builder.CreateNSWMul(LHS, RHS);
+    break;
+  case isl_ast_op_div:
+  case isl_ast_op_pdiv_q: // Dividend is non-negative
+    Res = Builder.CreateSDiv(LHS, RHS);
+    break;
+  case isl_ast_op_fdiv_q: { // Round towards -infty
+    // TODO: Review code and check that this calculation does not yield
+    //       incorrect overflow in some bordercases.
+    //
+    // floord(n,d) ((n < 0) ? (n - d + 1) : n) / d
+    Value *One = ConstantInt::get(MaxType, 1);
+    Value *Zero = ConstantInt::get(MaxType, 0);
+    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);
+    Res = Builder.CreateSDiv(Dividend, RHS);
+    break;
+  }
+  case isl_ast_op_pdiv_r: // Dividend is non-negative
+    Res = Builder.CreateSRem(LHS, RHS);
+    break;
+  }
+
+  // TODO: We can truncate the result, if it fits into a smaller type. This can
+  // help in cases where we have larger operands (e.g. i67) but the result is
+  // known to fit into i64. Without the truncation, the larger i67 type may
+  // force all subsequent operations to be performed on a non-native type.
+  isl_ast_expr_free(Expr);
+  return Res;
+}
+
+Value *IslExprBuilder::createOpSelect(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_select &&
+         "Unsupported unary isl ast expression");
+  Value *LHS, *RHS, *Cond;
+  Type *MaxType = getType(Expr);
+
+  Cond = create(isl_ast_expr_get_op_arg(Expr, 0));
+
+  LHS = create(isl_ast_expr_get_op_arg(Expr, 1));
+  RHS = create(isl_ast_expr_get_op_arg(Expr, 2));
+
+  MaxType = getWidestType(MaxType, LHS->getType());
+  MaxType = getWidestType(MaxType, RHS->getType());
+
+  if (MaxType != RHS->getType())
+    RHS = Builder.CreateSExt(RHS, MaxType);
+
+  if (MaxType != LHS->getType())
+    LHS = Builder.CreateSExt(LHS, MaxType);
+
+  // TODO: Do we want to truncate the result?
+  isl_ast_expr_free(Expr);
+  return Builder.CreateSelect(Cond, LHS, RHS);
+}
+
+Value *IslExprBuilder::createOpICmp(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
+         "Expected an isl_ast_expr_op expression");
+
+  Value *LHS, *RHS, *Res;
+
+  LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
+  RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
+
+  Type *MaxType = LHS->getType();
+  MaxType = getWidestType(MaxType, RHS->getType());
+
+  if (MaxType != RHS->getType())
+    RHS = Builder.CreateSExt(RHS, MaxType);
+
+  if (MaxType != LHS->getType())
+    LHS = Builder.CreateSExt(LHS, MaxType);
+
+  switch (isl_ast_expr_get_op_type(Expr)) {
+  default:
+    llvm_unreachable("Unsupported ICmp isl ast expression");
+  case isl_ast_op_eq:
+    Res = Builder.CreateICmpEQ(LHS, RHS);
+    break;
+  case isl_ast_op_le:
+    Res = Builder.CreateICmpSLE(LHS, RHS);
+    break;
+  case isl_ast_op_lt:
+    Res = Builder.CreateICmpSLT(LHS, RHS);
+    break;
+  case isl_ast_op_ge:
+    Res = Builder.CreateICmpSGE(LHS, RHS);
+    break;
+  case isl_ast_op_gt:
+    Res = Builder.CreateICmpSGT(LHS, RHS);
+    break;
+  }
+
+  isl_ast_expr_free(Expr);
+  return Res;
+}
+
+Value *IslExprBuilder::createOpBoolean(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
+         "Expected an isl_ast_expr_op expression");
+
+  Value *LHS, *RHS, *Res;
+  isl_ast_op_type OpType;
+
+  OpType = isl_ast_expr_get_op_type(Expr);
+
+  assert((OpType == isl_ast_op_and || OpType == isl_ast_op_or) &&
+         "Unsupported isl_ast_op_type");
+
+  LHS = create(isl_ast_expr_get_op_arg(Expr, 0));
+  RHS = create(isl_ast_expr_get_op_arg(Expr, 1));
+
+  // Even though the isl pretty printer prints the expressions as 'exp && exp'
+  // or 'exp || exp', we actually code generate the bitwise expressions
+  // 'exp & exp' or 'exp | exp'. This forces the evaluation of both branches,
+  // but it is, due to the use of i1 types, otherwise equivalent. The reason
+  // to go for bitwise operations is, that we assume the reduced control flow
+  // will outweight the overhead introduced by evaluating unneeded expressions.
+  // The isl code generation currently does not take advantage of the fact that
+  // the expression after an '||' or '&&' is in some cases not evaluated.
+  // Evaluating it anyways does not cause any undefined behaviour.
+  //
+  // TODO: Document in isl itself, that the unconditionally evaluating the
+  // second part of '||' or '&&' expressions is safe.
+  assert(LHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
+  assert(RHS->getType() == Builder.getInt1Ty() && "Expected i1 type");
+
+  switch (OpType) {
+  default:
+    llvm_unreachable("Unsupported boolean expression");
+  case isl_ast_op_and:
+    Res = Builder.CreateAnd(LHS, RHS);
+    break;
+  case isl_ast_op_or:
+    Res = Builder.CreateOr(LHS, RHS);
+    break;
+  }
+
+  isl_ast_expr_free(Expr);
+  return Res;
+}
+
+Value *IslExprBuilder::createOp(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
+         "Expression not of type isl_ast_expr_op");
+  switch (isl_ast_expr_get_op_type(Expr)) {
+  case isl_ast_op_error:
+  case isl_ast_op_cond:
+  case isl_ast_op_and_then:
+  case isl_ast_op_or_else:
+  case isl_ast_op_call:
+  case isl_ast_op_member:
+  case isl_ast_op_access:
+    llvm_unreachable("Unsupported isl ast expression");
+  case isl_ast_op_max:
+  case isl_ast_op_min:
+    return createOpNAry(Expr);
+  case isl_ast_op_add:
+  case isl_ast_op_sub:
+  case isl_ast_op_mul:
+  case isl_ast_op_div:
+  case isl_ast_op_fdiv_q: // Round towards -infty
+  case isl_ast_op_pdiv_q: // Dividend is non-negative
+  case isl_ast_op_pdiv_r: // Dividend is non-negative
+    return createOpBin(Expr);
+  case isl_ast_op_minus:
+    return createOpUnary(Expr);
+  case isl_ast_op_select:
+    return createOpSelect(Expr);
+  case isl_ast_op_and:
+  case isl_ast_op_or:
+    return createOpBoolean(Expr);
+  case isl_ast_op_eq:
+  case isl_ast_op_le:
+  case isl_ast_op_lt:
+  case isl_ast_op_ge:
+  case isl_ast_op_gt:
+    return createOpICmp(Expr);
+  }
+
+  llvm_unreachable("Unsupported isl_ast_expr_op kind.");
+}
+
+Value *IslExprBuilder::createId(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_id &&
+         "Expression not of type isl_ast_expr_ident");
+
+  isl_id *Id;
+  Value *V;
+
+  Id = isl_ast_expr_get_id(Expr);
+
+  assert(IDToValue.count(Id) && "Identifier not found");
+
+  V = IDToValue[Id];
+
+  isl_id_free(Id);
+  isl_ast_expr_free(Expr);
+
+  return V;
+}
+
+IntegerType *IslExprBuilder::getType(__isl_keep isl_ast_expr *Expr) {
+  // XXX: We assume i64 is large enough. This is often true, but in general
+  //      incorrect. Also, on 32bit architectures, it would be beneficial to
+  //      use a smaller type. We can and should directly derive this information
+  //      during code generation.
+  return IntegerType::get(Builder.getContext(), 64);
+}
+
+Value *IslExprBuilder::createInt(__isl_take isl_ast_expr *Expr) {
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_int &&
+         "Expression not of type isl_ast_expr_int");
+  isl_val *Val;
+  Value *V;
+  APInt APValue;
+  IntegerType *T;
+
+  Val = isl_ast_expr_get_val(Expr);
+  APValue = APIntFromVal(Val);
+  T = getType(Expr);
+  APValue = APValue.sextOrSelf(T->getBitWidth());
+  V = ConstantInt::get(T, APValue);
+
+  isl_ast_expr_free(Expr);
+  return V;
+}
+
+Value *IslExprBuilder::create(__isl_take isl_ast_expr *Expr) {
+  switch (isl_ast_expr_get_type(Expr)) {
+  case isl_ast_expr_error:
+    llvm_unreachable("Code generation error");
+  case isl_ast_expr_op:
+    return createOp(Expr);
+  case isl_ast_expr_id:
+    return createId(Expr);
+  case isl_ast_expr_int:
+    return createInt(Expr);
+  }
+
+  llvm_unreachable("Unexpected enum value");
+}
+
+class IslNodeBuilder {
+public:
+  IslNodeBuilder(PollyIRBuilder &Builder, LoopAnnotator &Annotator, Pass *P)
+      : Builder(Builder), Annotator(Annotator), ExprBuilder(Builder, IDToValue),
+        P(P) {}
+
+  void addParameters(__isl_take isl_set *Context);
+  void create(__isl_take isl_ast_node *Node);
+  IslExprBuilder &getExprBuilder() { return ExprBuilder; }
+
+private:
+  PollyIRBuilder &Builder;
+  LoopAnnotator &Annotator;
+  IslExprBuilder ExprBuilder;
+  Pass *P;
+
+  // This maps an isl_id* to the Value* it has in the generated program. For now
+  // on, the only isl_ids that are stored here are the newly calculated loop
+  // ivs.
+  std::map<isl_id *, Value *> IDToValue;
+
+  // Extract the upper bound of this loop
+  //
+  // The isl code generation can generate arbitrary expressions to check if the
+  // upper bound of a loop is reached, but it provides an option to enforce
+  // 'atomic' upper bounds. An 'atomic upper bound is always of the form
+  // iv <= expr, where expr is an (arbitrary) expression not containing iv.
+  //
+  // This function extracts 'atomic' upper bounds. Polly, in general, requires
+  // atomic upper bounds for the following reasons:
+  //
+  // 1. An atomic upper bound is loop invariant
+  //
+  //    It must not be calculated at each loop iteration and can often even be
+  //    hoisted out further by the loop invariant code motion.
+  //
+  // 2. OpenMP needs a loop invarient upper bound to calculate the number
+  //    of loop iterations.
+  //
+  // 3. With the existing code, upper bounds have been easier to implement.
+  __isl_give isl_ast_expr *getUpperBound(__isl_keep isl_ast_node *For,
+                                         CmpInst::Predicate &Predicate);
+
+  unsigned getNumberOfIterations(__isl_keep isl_ast_node *For);
+
+  void createFor(__isl_take isl_ast_node *For);
+  void createForVector(__isl_take isl_ast_node *For, int VectorWidth);
+  void createForSequential(__isl_take isl_ast_node *For);
+
+  /// Generate LLVM-IR that computes the values of the original induction
+  /// variables in function of the newly generated loop induction variables.
+  ///
+  /// Example:
+  ///
+  ///   // Original
+  ///   for i
+  ///     for j
+  ///       S(i)
+  ///
+  ///   Schedule: [i,j] -> [i+j, j]
+  ///
+  ///   // New
+  ///   for c0
+  ///     for c1
+  ///       S(c0 - c1, c1)
+  ///
+  /// Assuming the original code consists of two loops which are
+  /// transformed according to a schedule [i,j] -> [c0=i+j,c1=j]. The resulting
+  /// ast models the original statement as a call expression where each argument
+  /// is an expression that computes the old induction variables from the new
+  /// ones, ordered such that the first argument computes the value of induction
+  /// variable that was outermost in the original code.
+  ///
+  /// @param Expr The call expression that represents the statement.
+  /// @param Stmt The statement that is called.
+  /// @param VMap The value map into which the mapping from the old induction
+  ///             variable to the new one is inserted. This mapping is used
+  ///             for the classical code generation (not scev-based) and
+  ///             gives an explicit mapping from an original, materialized
+  ///             induction variable. It consequently can only be expressed
+  ///             if there was an explicit induction variable.
+  /// @param LTS  The loop to SCEV map in which the mapping from the original
+  ///             loop to a SCEV representing the new loop iv is added. This
+  ///             mapping does not require an explicit induction variable.
+  ///             Instead, we think in terms of an implicit induction variable
+  ///             that counts the number of times a loop is executed. For each
+  ///             original loop this count, expressed in function of the new
+  ///             induction variables, is added to the LTS map.
+  void createSubstitutions(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
+                           ValueMapT &VMap, LoopToScevMapT &LTS);
+  void createSubstitutionsVector(__isl_take isl_ast_expr *Expr, ScopStmt *Stmt,
+                                 VectorValueMapT &VMap,
+                                 std::vector<LoopToScevMapT> &VLTS,
+                                 std::vector<Value *> &IVS,
+                                 __isl_take isl_id *IteratorID);
+  void createIf(__isl_take isl_ast_node *If);
+  void createUserVector(__isl_take isl_ast_node *User,
+                        std::vector<Value *> &IVS,
+                        __isl_take isl_id *IteratorID,
+                        __isl_take isl_union_map *Schedule);
+  void createUser(__isl_take isl_ast_node *User);
+  void createBlock(__isl_take isl_ast_node *Block);
+};
+
+__isl_give isl_ast_expr *
+IslNodeBuilder::getUpperBound(__isl_keep isl_ast_node *For,
+                              ICmpInst::Predicate &Predicate) {
+  isl_id *UBID, *IteratorID;
+  isl_ast_expr *Cond, *Iterator, *UB, *Arg0;
+  isl_ast_op_type Type;
+
+  Cond = isl_ast_node_for_get_cond(For);
+  Iterator = isl_ast_node_for_get_iterator(For);
+  Type = isl_ast_expr_get_op_type(Cond);
+
+  assert(isl_ast_expr_get_type(Cond) == isl_ast_expr_op &&
+         "conditional expression is not an atomic upper bound");
+
+  switch (Type) {
+  case isl_ast_op_le:
+    Predicate = ICmpInst::ICMP_SLE;
+    break;
+  case isl_ast_op_lt:
+    Predicate = ICmpInst::ICMP_SLT;
+    break;
+  default:
+    llvm_unreachable("Unexpected comparision type in loop conditon");
+  }
+
+  Arg0 = isl_ast_expr_get_op_arg(Cond, 0);
+
+  assert(isl_ast_expr_get_type(Arg0) == isl_ast_expr_id &&
+         "conditional expression is not an atomic upper bound");
+
+  UBID = isl_ast_expr_get_id(Arg0);
+
+  assert(isl_ast_expr_get_type(Iterator) == isl_ast_expr_id &&
+         "Could not get the iterator");
+
+  IteratorID = isl_ast_expr_get_id(Iterator);
+
+  assert(UBID == IteratorID &&
+         "conditional expression is not an atomic upper bound");
+
+  UB = isl_ast_expr_get_op_arg(Cond, 1);
+
+  isl_ast_expr_free(Cond);
+  isl_ast_expr_free(Iterator);
+  isl_ast_expr_free(Arg0);
+  isl_id_free(IteratorID);
+  isl_id_free(UBID);
+
+  return UB;
+}
+
+unsigned IslNodeBuilder::getNumberOfIterations(__isl_keep isl_ast_node *For) {
+  isl_id *Annotation = isl_ast_node_get_annotation(For);
+  if (!Annotation)
+    return -1;
+
+  struct IslAstUserPayload *Info =
+      (struct IslAstUserPayload *)isl_id_get_user(Annotation);
+  if (!Info) {
+    isl_id_free(Annotation);
+    return -1;
+  }
+
+  isl_union_map *Schedule = isl_ast_build_get_schedule(Info->Context);
+  isl_set *LoopDomain = isl_set_from_union_set(isl_union_map_range(Schedule));
+  isl_id_free(Annotation);
+  int NumberOfIterations = polly::getNumberOfIterations(LoopDomain);
+  if (NumberOfIterations == -1)
+    return -1;
+  return NumberOfIterations + 1;
+}
+
+void IslNodeBuilder::createUserVector(__isl_take isl_ast_node *User,
+                                      std::vector<Value *> &IVS,
+                                      __isl_take isl_id *IteratorID,
+                                      __isl_take isl_union_map *Schedule) {
+  isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
+  isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
+  isl_id *Id = isl_ast_expr_get_id(StmtExpr);
+  isl_ast_expr_free(StmtExpr);
+  ScopStmt *Stmt = (ScopStmt *)isl_id_get_user(Id);
+  VectorValueMapT VectorMap(IVS.size());
+  std::vector<LoopToScevMapT> VLTS(IVS.size());
+
+  isl_union_set *Domain = isl_union_set_from_set(Stmt->getDomain());
+  Schedule = isl_union_map_intersect_domain(Schedule, Domain);
+  isl_map *S = isl_map_from_union_map(Schedule);
+
+  createSubstitutionsVector(Expr, Stmt, VectorMap, VLTS, IVS, IteratorID);
+  VectorBlockGenerator::generate(Builder, *Stmt, VectorMap, VLTS, S, P);
+
+  isl_map_free(S);
+  isl_id_free(Id);
+  isl_ast_node_free(User);
+}
+
+void IslNodeBuilder::createForVector(__isl_take isl_ast_node *For,
+                                     int VectorWidth) {
+  isl_ast_node *Body = isl_ast_node_for_get_body(For);
+  isl_ast_expr *Init = isl_ast_node_for_get_init(For);
+  isl_ast_expr *Inc = isl_ast_node_for_get_inc(For);
+  isl_ast_expr *Iterator = isl_ast_node_for_get_iterator(For);
+  isl_id *IteratorID = isl_ast_expr_get_id(Iterator);
+
+  Value *ValueLB = ExprBuilder.create(Init);
+  Value *ValueInc = ExprBuilder.create(Inc);
+
+  Type *MaxType = ExprBuilder.getType(Iterator);
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
+
+  if (MaxType != ValueLB->getType())
+    ValueLB = Builder.CreateSExt(ValueLB, MaxType);
+  if (MaxType != ValueInc->getType())
+    ValueInc = Builder.CreateSExt(ValueInc, MaxType);
+
+  std::vector<Value *> IVS(VectorWidth);
+  IVS[0] = ValueLB;
+
+  for (int i = 1; i < VectorWidth; i++)
+    IVS[i] = Builder.CreateAdd(IVS[i - 1], ValueInc, "p_vector_iv");
+
+  isl_id *Annotation = isl_ast_node_get_annotation(For);
+  assert(Annotation && "For statement is not annotated");
+
+  struct IslAstUserPayload *Info =
+      (struct IslAstUserPayload *)isl_id_get_user(Annotation);
+  assert(Info && "For statement annotation does not contain info");
+
+  isl_union_map *Schedule = isl_ast_build_get_schedule(Info->Context);
+  assert(Schedule && "For statement annotation does not contain its schedule");
+
+  IDToValue[IteratorID] = ValueLB;
+
+  switch (isl_ast_node_get_type(Body)) {
+  case isl_ast_node_user:
+    createUserVector(Body, IVS, isl_id_copy(IteratorID),
+                     isl_union_map_copy(Schedule));
+    break;
+  case isl_ast_node_block: {
+    isl_ast_node_list *List = isl_ast_node_block_get_children(Body);
+
+    for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
+      createUserVector(isl_ast_node_list_get_ast_node(List, i), IVS,
+                       isl_id_copy(IteratorID), isl_union_map_copy(Schedule));
+
+    isl_ast_node_free(Body);
+    isl_ast_node_list_free(List);
+    break;
+  }
+  default:
+    isl_ast_node_dump(Body);
+    llvm_unreachable("Unhandled isl_ast_node in vectorizer");
+  }
+
+  IDToValue.erase(IteratorID);
+  isl_id_free(IteratorID);
+  isl_id_free(Annotation);
+  isl_union_map_free(Schedule);
+
+  isl_ast_node_free(For);
+  isl_ast_expr_free(Iterator);
+}
+
+void IslNodeBuilder::createForSequential(__isl_take isl_ast_node *For) {
+  isl_ast_node *Body;
+  isl_ast_expr *Init, *Inc, *Iterator, *UB;
+  isl_id *IteratorID;
+  Value *ValueLB, *ValueUB, *ValueInc;
+  Type *MaxType;
+  BasicBlock *ExitBlock;
+  Value *IV;
+  CmpInst::Predicate Predicate;
+  bool Parallel;
+
+  Parallel = IslAstInfo::isInnermostParallel(For);
+
+  Body = isl_ast_node_for_get_body(For);
+
+  // isl_ast_node_for_is_degenerate(For)
+  //
+  // TODO: For degenerated loops we could generate a plain assignment.
+  //       However, for now we just reuse the logic for normal loops, which will
+  //       create a loop with a single iteration.
+
+  Init = isl_ast_node_for_get_init(For);
+  Inc = isl_ast_node_for_get_inc(For);
+  Iterator = isl_ast_node_for_get_iterator(For);
+  IteratorID = isl_ast_expr_get_id(Iterator);
+  UB = getUpperBound(For, Predicate);
+
+  ValueLB = ExprBuilder.create(Init);
+  ValueUB = ExprBuilder.create(UB);
+  ValueInc = ExprBuilder.create(Inc);
+
+  MaxType = ExprBuilder.getType(Iterator);
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueLB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueUB->getType());
+  MaxType = ExprBuilder.getWidestType(MaxType, ValueInc->getType());
+
+  if (MaxType != ValueLB->getType())
+    ValueLB = Builder.CreateSExt(ValueLB, MaxType);
+  if (MaxType != ValueUB->getType())
+    ValueUB = Builder.CreateSExt(ValueUB, MaxType);
+  if (MaxType != ValueInc->getType())
+    ValueInc = Builder.CreateSExt(ValueInc, MaxType);
+
+  IV = createLoop(ValueLB, ValueUB, ValueInc, Builder, P, ExitBlock, Predicate,
+                  &Annotator, Parallel);
+  IDToValue[IteratorID] = IV;
+
+  create(Body);
+
+  Annotator.End();
+
+  IDToValue.erase(IteratorID);
+
+  Builder.SetInsertPoint(ExitBlock->begin());
+
+  isl_ast_node_free(For);
+  isl_ast_expr_free(Iterator);
+  isl_id_free(IteratorID);
+}
+
+void IslNodeBuilder::createFor(__isl_take isl_ast_node *For) {
+  bool Vector = PollyVectorizerChoice != VECTORIZER_NONE;
+
+  if (Vector && IslAstInfo::isInnermostParallel(For)) {
+    int VectorWidth = getNumberOfIterations(For);
+    if (1 < VectorWidth && VectorWidth <= 16) {
+      createForVector(For, VectorWidth);
+      return;
+    }
+  }
+  createForSequential(For);
+}
+
+void IslNodeBuilder::createIf(__isl_take isl_ast_node *If) {
+  isl_ast_expr *Cond = isl_ast_node_if_get_cond(If);
+
+  Function *F = Builder.GetInsertBlock()->getParent();
+  LLVMContext &Context = F->getContext();
+
+  BasicBlock *CondBB =
+      SplitBlock(Builder.GetInsertBlock(), Builder.GetInsertPoint(), P);
+  CondBB->setName("polly.cond");
+  BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
+  MergeBB->setName("polly.merge");
+  BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
+  BasicBlock *ElseBB = BasicBlock::Create(Context, "polly.else", F);
+
+  DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  DT.addNewBlock(ThenBB, CondBB);
+  DT.addNewBlock(ElseBB, CondBB);
+  DT.changeImmediateDominator(MergeBB, CondBB);
+
+  LoopInfo &LI = P->getAnalysis<LoopInfo>();
+  Loop *L = LI.getLoopFor(CondBB);
+  if (L) {
+    L->addBasicBlockToLoop(ThenBB, LI.getBase());
+    L->addBasicBlockToLoop(ElseBB, LI.getBase());
+  }
+
+  CondBB->getTerminator()->eraseFromParent();
+
+  Builder.SetInsertPoint(CondBB);
+  Value *Predicate = ExprBuilder.create(Cond);
+  Builder.CreateCondBr(Predicate, ThenBB, ElseBB);
+  Builder.SetInsertPoint(ThenBB);
+  Builder.CreateBr(MergeBB);
+  Builder.SetInsertPoint(ElseBB);
+  Builder.CreateBr(MergeBB);
+  Builder.SetInsertPoint(ThenBB->begin());
+
+  create(isl_ast_node_if_get_then(If));
+
+  Builder.SetInsertPoint(ElseBB->begin());
+
+  if (isl_ast_node_if_has_else(If))
+    create(isl_ast_node_if_get_else(If));
+
+  Builder.SetInsertPoint(MergeBB->begin());
+
+  isl_ast_node_free(If);
+}
+
+void IslNodeBuilder::createSubstitutions(isl_ast_expr *Expr, ScopStmt *Stmt,
+                                         ValueMapT &VMap, LoopToScevMapT &LTS) {
+  assert(isl_ast_expr_get_type(Expr) == isl_ast_expr_op &&
+         "Expression of type 'op' expected");
+  assert(isl_ast_expr_get_op_type(Expr) == isl_ast_op_call &&
+         "Opertation of type 'call' expected");
+  for (int i = 0; i < isl_ast_expr_get_op_n_arg(Expr) - 1; ++i) {
+    isl_ast_expr *SubExpr;
+    Value *V;
+
+    SubExpr = isl_ast_expr_get_op_arg(Expr, i + 1);
+    V = ExprBuilder.create(SubExpr);
+    ScalarEvolution *SE = Stmt->getParent()->getSE();
+    LTS[Stmt->getLoopForDimension(i)] = SE->getUnknown(V);
+
+    // CreateIntCast can introduce trunc expressions. This is correct, as the
+    // result will always fit into the type of the original induction variable
+    // (because we calculate a value of the original induction variable).
+    const Value *OldIV = Stmt->getInductionVariableForDimension(i);
+    if (OldIV) {
+      V = Builder.CreateIntCast(V, OldIV->getType(), true);
+      VMap[OldIV] = V;
+    }
+  }
+
+  isl_ast_expr_free(Expr);
+}
+
+void IslNodeBuilder::createSubstitutionsVector(
+    __isl_take isl_ast_expr *Expr, ScopStmt *Stmt, VectorValueMapT &VMap,
+    std::vector<LoopToScevMapT> &VLTS, std::vector<Value *> &IVS,
+    __isl_take isl_id *IteratorID) {
+  int i = 0;
+
+  Value *OldValue = IDToValue[IteratorID];
+  for (Value *IV : IVS) {
+    IDToValue[IteratorID] = IV;
+    createSubstitutions(isl_ast_expr_copy(Expr), Stmt, VMap[i], VLTS[i]);
+    i++;
+  }
+
+  IDToValue[IteratorID] = OldValue;
+  isl_id_free(IteratorID);
+  isl_ast_expr_free(Expr);
+}
+
+void IslNodeBuilder::createUser(__isl_take isl_ast_node *User) {
+  ValueMapT VMap;
+  LoopToScevMapT LTS;
+  isl_id *Id;
+  ScopStmt *Stmt;
+
+  isl_ast_expr *Expr = isl_ast_node_user_get_expr(User);
+  isl_ast_expr *StmtExpr = isl_ast_expr_get_op_arg(Expr, 0);
+  Id = isl_ast_expr_get_id(StmtExpr);
+  isl_ast_expr_free(StmtExpr);
+
+  Stmt = (ScopStmt *)isl_id_get_user(Id);
+  createSubstitutions(Expr, Stmt, VMap, LTS);
+  BlockGenerator::generate(Builder, *Stmt, VMap, LTS, P);
+
+  isl_ast_node_free(User);
+  isl_id_free(Id);
+}
+
+void IslNodeBuilder::createBlock(__isl_take isl_ast_node *Block) {
+  isl_ast_node_list *List = isl_ast_node_block_get_children(Block);
+
+  for (int i = 0; i < isl_ast_node_list_n_ast_node(List); ++i)
+    create(isl_ast_node_list_get_ast_node(List, i));
+
+  isl_ast_node_free(Block);
+  isl_ast_node_list_free(List);
+}
+
+void IslNodeBuilder::create(__isl_take isl_ast_node *Node) {
+  switch (isl_ast_node_get_type(Node)) {
+  case isl_ast_node_error:
+    llvm_unreachable("code  generation error");
+  case isl_ast_node_for:
+    createFor(Node);
+    return;
+  case isl_ast_node_if:
+    createIf(Node);
+    return;
+  case isl_ast_node_user:
+    createUser(Node);
+    return;
+  case isl_ast_node_block:
+    createBlock(Node);
+    return;
+  }
+
+  llvm_unreachable("Unknown isl_ast_node type");
+}
+
+void IslNodeBuilder::addParameters(__isl_take isl_set *Context) {
+  SCEVExpander Rewriter(P->getAnalysis<ScalarEvolution>(), "polly");
+
+  for (unsigned i = 0; i < isl_set_dim(Context, isl_dim_param); ++i) {
+    isl_id *Id;
+    const SCEV *Scev;
+    IntegerType *T;
+    Instruction *InsertLocation;
+
+    Id = isl_set_get_dim_id(Context, isl_dim_param, i);
+    Scev = (const SCEV *)isl_id_get_user(Id);
+    T = dyn_cast<IntegerType>(Scev->getType());
+    InsertLocation = --(Builder.GetInsertBlock()->end());
+    Value *V = Rewriter.expandCodeFor(Scev, T, InsertLocation);
+    IDToValue[Id] = V;
+
+    isl_id_free(Id);
+  }
+
+  isl_set_free(Context);
+}
+
+namespace {
+class IslCodeGeneration : public ScopPass {
+public:
+  static char ID;
+
+  IslCodeGeneration() : ScopPass(ID) {}
+
+  bool runOnScop(Scop &S) {
+    IslAstInfo &AstInfo = getAnalysis<IslAstInfo>();
+
+    assert(!S.getRegion().isTopLevelRegion() &&
+           "Top level regions are not supported");
+
+    simplifyRegion(&S, this);
+
+    BasicBlock *StartBlock = executeScopConditionally(S, this);
+    isl_ast_node *Ast = AstInfo.getAst();
+    LoopAnnotator Annotator;
+    PollyIRBuilder Builder(StartBlock->getContext(), llvm::ConstantFolder(),
+                           polly::IRInserter(Annotator));
+    Builder.SetInsertPoint(StartBlock->begin());
+
+    IslNodeBuilder NodeBuilder(Builder, Annotator, this);
+
+    Builder.SetInsertPoint(StartBlock->getSinglePredecessor()->begin());
+    NodeBuilder.addParameters(S.getContext());
+    // Build condition that evaluates at run-time if all assumptions taken
+    // for the scop hold. If we detect some assumptions do not hold, the
+    // original code is executed.
+    Value *V = NodeBuilder.getExprBuilder().create(AstInfo.getRunCondition());
+    Value *Zero = ConstantInt::get(V->getType(), 0);
+    V = Builder.CreateICmp(CmpInst::ICMP_NE, Zero, V);
+    BasicBlock *PrevBB = StartBlock->getUniquePredecessor();
+    BranchInst *Branch = dyn_cast<BranchInst>(PrevBB->getTerminator());
+    Branch->setCondition(V);
+    Builder.SetInsertPoint(StartBlock->begin());
+
+    NodeBuilder.create(Ast);
+    return true;
+  }
+
+  virtual void printScop(raw_ostream &OS) const {}
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.addRequired<DominatorTreeWrapperPass>();
+    AU.addRequired<IslAstInfo>();
+    AU.addRequired<RegionInfoPass>();
+    AU.addRequired<ScalarEvolution>();
+    AU.addRequired<ScopDetection>();
+    AU.addRequired<ScopInfo>();
+    AU.addRequired<LoopInfo>();
+
+    AU.addPreserved<Dependences>();
+
+    AU.addPreserved<LoopInfo>();
+    AU.addPreserved<DominatorTreeWrapperPass>();
+    AU.addPreserved<IslAstInfo>();
+    AU.addPreserved<ScopDetection>();
+    AU.addPreserved<ScalarEvolution>();
+
+    // FIXME: We do not yet add regions for the newly generated code to the
+    //        region tree.
+    AU.addPreserved<RegionInfoPass>();
+    AU.addPreserved<TempScopInfo>();
+    AU.addPreserved<ScopInfo>();
+    AU.addPreservedID(IndependentBlocksID);
+  }
+};
+}
+
+char IslCodeGeneration::ID = 1;
+
+Pass *polly::createIslCodeGenerationPass() { return new IslCodeGeneration(); }
+
+INITIALIZE_PASS_BEGIN(IslCodeGeneration, "polly-codegen-isl",
+                      "Polly - Create LLVM-IR from SCoPs", false, false);
+INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
+INITIALIZE_PASS_DEPENDENCY(LoopInfo);
+INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
+INITIALIZE_PASS_DEPENDENCY(ScopDetection);
+INITIALIZE_PASS_END(IslCodeGeneration, "polly-codegen-isl",
+                    "Polly - Create LLVM-IR from SCoPs", false, false)
diff --git a/rc1/lib/CodeGen/LoopGenerators.cpp b/rc1/lib/CodeGen/LoopGenerators.cpp
new file mode 100644
index 0000000..432960d
--- /dev/null
+++ b/rc1/lib/CodeGen/LoopGenerators.cpp
@@ -0,0 +1,373 @@
+//===------ LoopGenerators.cpp -  IR helper to create loops ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions to create scalar and OpenMP parallel loops
+// as LLVM-IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/ScopDetection.h"
+#include "polly/CodeGen/LoopGenerators.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+using namespace llvm;
+using namespace polly;
+
+// We generate a loop of the following structure
+//
+//              BeforeBB
+//                 |
+//                 v
+//              GuardBB
+//              /      |
+//     __  PreHeaderBB  |
+//    /  \    /         |
+// latch  HeaderBB      |
+//    \  /    \         /
+//     <       \       /
+//              \     /
+//              ExitBB
+//
+// GuardBB checks if the loop is executed at least once. If this is the case
+// we branch to PreHeaderBB and subsequently to the HeaderBB, which contains the
+// loop iv 'polly.indvar', the incremented loop iv 'polly.indvar_next' as well
+// as the condition to check if we execute another iteration of the loop. After
+// the loop has finished, we branch to ExitBB.
+//
+// TODO: We currently always create the GuardBB. If we can prove the loop is
+//       always executed at least once, we can get rid of this branch.
+Value *polly::createLoop(Value *LB, Value *UB, Value *Stride,
+                         PollyIRBuilder &Builder, Pass *P, BasicBlock *&ExitBB,
+                         ICmpInst::Predicate Predicate,
+                         LoopAnnotator *Annotator, bool Parallel) {
+  DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  LoopInfo &LI = P->getAnalysis<LoopInfo>();
+  Function *F = Builder.GetInsertBlock()->getParent();
+  LLVMContext &Context = F->getContext();
+
+  assert(LB->getType() == UB->getType() && "Types of loop bounds do not match");
+  IntegerType *LoopIVType = dyn_cast<IntegerType>(UB->getType());
+  assert(LoopIVType && "UB is not integer?");
+
+  BasicBlock *BeforeBB = Builder.GetInsertBlock();
+  BasicBlock *GuardBB = BasicBlock::Create(Context, "polly.loop_if", F);
+  BasicBlock *HeaderBB = BasicBlock::Create(Context, "polly.loop_header", F);
+  BasicBlock *PreHeaderBB =
+      BasicBlock::Create(Context, "polly.loop_preheader", F);
+
+  if (Annotator) {
+    Annotator->Begin(HeaderBB);
+    if (Parallel)
+      Annotator->SetCurrentParallel();
+  }
+
+  // Update LoopInfo
+  Loop *OuterLoop = LI.getLoopFor(BeforeBB);
+  Loop *NewLoop = new Loop();
+
+  if (OuterLoop) {
+    OuterLoop->addChildLoop(NewLoop);
+  } else {
+    LI.addTopLevelLoop(NewLoop);
+  }
+
+  if (OuterLoop) {
+    OuterLoop->addBasicBlockToLoop(GuardBB, LI.getBase());
+    OuterLoop->addBasicBlockToLoop(PreHeaderBB, LI.getBase());
+  }
+
+  NewLoop->addBasicBlockToLoop(HeaderBB, LI.getBase());
+
+  // ExitBB
+  ExitBB = SplitBlock(BeforeBB, Builder.GetInsertPoint()++, P);
+  ExitBB->setName("polly.loop_exit");
+
+  // BeforeBB
+  BeforeBB->getTerminator()->setSuccessor(0, GuardBB);
+
+  // GuardBB
+  DT.addNewBlock(GuardBB, BeforeBB);
+  Builder.SetInsertPoint(GuardBB);
+  Value *LoopGuard;
+  LoopGuard = Builder.CreateICmp(Predicate, LB, UB);
+  LoopGuard->setName("polly.loop_guard");
+  Builder.CreateCondBr(LoopGuard, PreHeaderBB, ExitBB);
+
+  // PreHeaderBB
+  DT.addNewBlock(PreHeaderBB, GuardBB);
+  Builder.SetInsertPoint(PreHeaderBB);
+  Builder.CreateBr(HeaderBB);
+
+  // HeaderBB
+  DT.addNewBlock(HeaderBB, PreHeaderBB);
+  Builder.SetInsertPoint(HeaderBB);
+  PHINode *IV = Builder.CreatePHI(LoopIVType, 2, "polly.indvar");
+  IV->addIncoming(LB, PreHeaderBB);
+  Stride = Builder.CreateZExtOrBitCast(Stride, LoopIVType);
+  Value *IncrementedIV = Builder.CreateNSWAdd(IV, Stride, "polly.indvar_next");
+  Value *LoopCondition;
+  UB = Builder.CreateSub(UB, Stride, "polly.adjust_ub");
+  LoopCondition = Builder.CreateICmp(Predicate, IV, UB);
+  LoopCondition->setName("polly.loop_cond");
+  Builder.CreateCondBr(LoopCondition, HeaderBB, ExitBB);
+  IV->addIncoming(IncrementedIV, HeaderBB);
+  DT.changeImmediateDominator(ExitBB, GuardBB);
+
+  // The loop body should be added here.
+  Builder.SetInsertPoint(HeaderBB->getFirstNonPHI());
+  return IV;
+}
+
+void OMPGenerator::createCallParallelLoopStart(
+    Value *SubFunction, Value *SubfunctionParam, Value *NumberOfThreads,
+    Value *LowerBound, Value *UpperBound, Value *Stride) {
+  Module *M = getModule();
+  const char *Name = "GOMP_parallel_loop_runtime_start";
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    Type *LongTy = getIntPtrTy();
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+
+    Type *Params[] = {PointerType::getUnqual(FunctionType::get(
+                          Builder.getVoidTy(), Builder.getInt8PtrTy(), false)),
+                      Builder.getInt8PtrTy(), Builder.getInt32Ty(), LongTy,
+                      LongTy, LongTy};
+
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Params, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Value *Args[] = {SubFunction, SubfunctionParam, NumberOfThreads,
+                   LowerBound,  UpperBound,       Stride};
+
+  Builder.CreateCall(F, Args);
+}
+
+Value *OMPGenerator::createCallLoopNext(Value *LowerBoundPtr,
+                                        Value *UpperBoundPtr) {
+  Module *M = getModule();
+  const char *Name = "GOMP_loop_runtime_next";
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    Type *LongPtrTy = PointerType::getUnqual(getIntPtrTy());
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+
+    Type *Params[] = {LongPtrTy, LongPtrTy};
+
+    FunctionType *Ty = FunctionType::get(Builder.getInt8Ty(), Params, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Value *Args[] = {LowerBoundPtr, UpperBoundPtr};
+
+  Value *Return = Builder.CreateCall(F, Args);
+  Return = Builder.CreateICmpNE(
+      Return, Builder.CreateZExt(Builder.getFalse(), Return->getType()));
+  return Return;
+}
+
+void OMPGenerator::createCallParallelEnd() {
+  const char *Name = "GOMP_parallel_end";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall(F);
+}
+
+void OMPGenerator::createCallLoopEndNowait() {
+  const char *Name = "GOMP_loop_end_nowait";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall(F);
+}
+
+IntegerType *OMPGenerator::getIntPtrTy() {
+  return P->getAnalysis<DataLayoutPass>().getDataLayout().getIntPtrType(
+      Builder.getContext());
+}
+
+Module *OMPGenerator::getModule() {
+  return Builder.GetInsertBlock()->getParent()->getParent();
+}
+
+Function *OMPGenerator::createSubfunctionDefinition() {
+  Module *M = getModule();
+  Function *F = Builder.GetInsertBlock()->getParent();
+  std::vector<Type *> Arguments(1, Builder.getInt8PtrTy());
+  FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
+  Function *FN = Function::Create(FT, Function::InternalLinkage,
+                                  F->getName() + ".omp_subfn", M);
+  // Do not run any polly pass on the new function.
+  FN->addFnAttr(PollySkipFnAttr);
+
+  Function::arg_iterator AI = FN->arg_begin();
+  AI->setName("omp.userContext");
+
+  return FN;
+}
+
+Value *OMPGenerator::loadValuesIntoStruct(SetVector<Value *> &Values) {
+  std::vector<Type *> Members;
+
+  for (Value *V : Values)
+    Members.push_back(V->getType());
+
+  StructType *Ty = StructType::get(Builder.getContext(), Members);
+  Value *Struct = Builder.CreateAlloca(Ty, 0, "omp.userContext");
+
+  for (unsigned i = 0; i < Values.size(); i++) {
+    Value *Address = Builder.CreateStructGEP(Struct, i);
+    Builder.CreateStore(Values[i], Address);
+  }
+
+  return Struct;
+}
+
+void OMPGenerator::extractValuesFromStruct(SetVector<Value *> OldValues,
+                                           Value *Struct,
+                                           ValueToValueMapTy &Map) {
+  for (unsigned i = 0; i < OldValues.size(); i++) {
+    Value *Address = Builder.CreateStructGEP(Struct, i);
+    Value *NewValue = Builder.CreateLoad(Address);
+    Map.insert(std::make_pair(OldValues[i], NewValue));
+  }
+}
+
+Value *OMPGenerator::createSubfunction(Value *Stride, Value *StructData,
+                                       SetVector<Value *> Data,
+                                       ValueToValueMapTy &Map,
+                                       Function **SubFunction) {
+  Function *FN = createSubfunctionDefinition();
+
+  BasicBlock *PrevBB, *HeaderBB, *ExitBB, *CheckNextBB, *LoadIVBoundsBB,
+      *AfterBB;
+  Value *LowerBoundPtr, *UpperBoundPtr, *UserContext, *Ret1, *HasNextSchedule,
+      *LowerBound, *UpperBound, *IV;
+  Type *IntPtrTy = getIntPtrTy();
+  LLVMContext &Context = FN->getContext();
+
+  // Store the previous basic block.
+  PrevBB = Builder.GetInsertBlock();
+
+  // Create basic blocks.
+  HeaderBB = BasicBlock::Create(Context, "omp.setup", FN);
+  ExitBB = BasicBlock::Create(Context, "omp.exit", FN);
+  CheckNextBB = BasicBlock::Create(Context, "omp.checkNext", FN);
+  LoadIVBoundsBB = BasicBlock::Create(Context, "omp.loadIVBounds", FN);
+
+  DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  DT.addNewBlock(HeaderBB, PrevBB);
+  DT.addNewBlock(ExitBB, HeaderBB);
+  DT.addNewBlock(CheckNextBB, HeaderBB);
+  DT.addNewBlock(LoadIVBoundsBB, HeaderBB);
+
+  // Fill up basic block HeaderBB.
+  Builder.SetInsertPoint(HeaderBB);
+  LowerBoundPtr = Builder.CreateAlloca(IntPtrTy, 0, "omp.lowerBoundPtr");
+  UpperBoundPtr = Builder.CreateAlloca(IntPtrTy, 0, "omp.upperBoundPtr");
+  UserContext = Builder.CreateBitCast(FN->arg_begin(), StructData->getType(),
+                                      "omp.userContext");
+
+  extractValuesFromStruct(Data, UserContext, Map);
+  Builder.CreateBr(CheckNextBB);
+
+  // Add code to check if another set of iterations will be executed.
+  Builder.SetInsertPoint(CheckNextBB);
+  Ret1 = createCallLoopNext(LowerBoundPtr, UpperBoundPtr);
+  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);
+  LowerBound = Builder.CreateLoad(LowerBoundPtr, "omp.lowerBound");
+  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");
+
+  Builder.CreateBr(CheckNextBB);
+  Builder.SetInsertPoint(--Builder.GetInsertPoint());
+  IV = createLoop(LowerBound, UpperBound, Stride, Builder, P, AfterBB,
+                  ICmpInst::ICMP_SLE);
+
+  BasicBlock::iterator LoopBody = Builder.GetInsertPoint();
+  Builder.SetInsertPoint(AfterBB->begin());
+
+  // Add code to terminate this openmp subfunction.
+  Builder.SetInsertPoint(ExitBB);
+  createCallLoopEndNowait();
+  Builder.CreateRetVoid();
+
+  Builder.SetInsertPoint(LoopBody);
+  *SubFunction = FN;
+
+  return IV;
+}
+
+Value *OMPGenerator::createParallelLoop(Value *LowerBound, Value *UpperBound,
+                                        Value *Stride,
+                                        SetVector<Value *> &Values,
+                                        ValueToValueMapTy &Map,
+                                        BasicBlock::iterator *LoopBody) {
+  Value *Struct, *IV, *SubfunctionParam, *NumberOfThreads;
+  Function *SubFunction;
+
+  Struct = loadValuesIntoStruct(Values);
+
+  BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
+  IV = createSubfunction(Stride, Struct, Values, Map, &SubFunction);
+  *LoopBody = Builder.GetInsertPoint();
+  Builder.SetInsertPoint(PrevInsertPoint);
+
+  // Create call for GOMP_parallel_loop_runtime_start.
+  SubfunctionParam =
+      Builder.CreateBitCast(Struct, Builder.getInt8PtrTy(), "omp_data");
+
+  NumberOfThreads = Builder.getInt32(0);
+
+  // 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(getIntPtrTy(), 1));
+
+  createCallParallelLoopStart(SubFunction, SubfunctionParam, NumberOfThreads,
+                              LowerBound, UpperBound, Stride);
+  Builder.CreateCall(SubFunction, SubfunctionParam);
+  createCallParallelEnd();
+
+  return IV;
+}
diff --git a/rc1/lib/CodeGen/PTXGenerator.cpp b/rc1/lib/CodeGen/PTXGenerator.cpp
new file mode 100644
index 0000000..16da662
--- /dev/null
+++ b/rc1/lib/CodeGen/PTXGenerator.cpp
@@ -0,0 +1,712 @@
+//===------ PTXGenerator.cpp -  IR helper to create loops -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions to create GPU parallel codes as LLVM-IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/CodeGen/PTXGenerator.h"
+
+#ifdef GPU_CODEGEN
+#include "polly/ScopDetection.h"
+#include "polly/ScopInfo.h"
+
+#include "llvm/PassManager.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Target/TargetLibraryInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+
+using namespace llvm;
+using namespace polly;
+
+PTXGenerator::PTXGenerator(PollyIRBuilder &Builder, Pass *P,
+                           const std::string &Triple)
+    : Builder(Builder), P(P), GPUTriple(Triple), GridWidth(1), GridHeight(1),
+      BlockWidth(1), BlockHeight(1), OutputBytes(0) {
+  InitializeGPUDataTypes();
+}
+
+Module *PTXGenerator::getModule() {
+  return Builder.GetInsertBlock()->getParent()->getParent();
+}
+
+Function *PTXGenerator::createSubfunctionDefinition(int NumArgs) {
+  assert(NumArgs == 1 && "we support only one array access now.");
+
+  Module *M = getModule();
+  Function *F = Builder.GetInsertBlock()->getParent();
+  std::vector<Type *> Arguments;
+  for (int i = 0; i < NumArgs; i++)
+    Arguments.push_back(Builder.getInt8PtrTy());
+  FunctionType *FT = FunctionType::get(Builder.getVoidTy(), Arguments, false);
+  Function *FN = Function::Create(FT, Function::InternalLinkage,
+                                  F->getName() + "_ptx_subfn", M);
+  FN->setCallingConv(CallingConv::PTX_Kernel);
+
+  // Do not run any optimization pass on the new function.
+  P->getAnalysis<polly::ScopDetection>().markFunctionAsInvalid(FN);
+
+  for (Function::arg_iterator AI = FN->arg_begin(); AI != FN->arg_end(); ++AI)
+    AI->setName("ptx.Array");
+
+  return FN;
+}
+
+void PTXGenerator::createSubfunction(SetVector<Value *> &UsedValues,
+                                     SetVector<Value *> &OriginalIVS,
+                                     PTXGenerator::ValueToValueMapTy &VMap,
+                                     Function **SubFunction) {
+  Function *FN = createSubfunctionDefinition(UsedValues.size());
+  Module *M = getModule();
+  LLVMContext &Context = FN->getContext();
+  IntegerType *Ty = Builder.getInt64Ty();
+
+  // Store the previous basic block.
+  BasicBlock *PrevBB = Builder.GetInsertBlock();
+
+  // Create basic blocks.
+  BasicBlock *HeaderBB = BasicBlock::Create(Context, "ptx.setup", FN);
+  BasicBlock *ExitBB = BasicBlock::Create(Context, "ptx.exit", FN);
+  BasicBlock *BodyBB = BasicBlock::Create(Context, "ptx.loop_body", FN);
+
+  DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  DT.addNewBlock(HeaderBB, PrevBB);
+  DT.addNewBlock(ExitBB, HeaderBB);
+  DT.addNewBlock(BodyBB, HeaderBB);
+
+  Builder.SetInsertPoint(HeaderBB);
+
+  // Insert VMap items with maps of array base address on the host to base
+  // address on the device.
+  Function::arg_iterator AI = FN->arg_begin();
+  for (unsigned j = 0; j < UsedValues.size(); j++) {
+    Value *BaseAddr = UsedValues[j];
+    Type *ArrayTy = BaseAddr->getType();
+    Value *Param = Builder.CreateBitCast(AI, ArrayTy);
+    VMap.insert(std::make_pair(BaseAddr, Param));
+    AI++;
+  }
+
+  // FIXME: These intrinsics should be inserted on-demand. However, we insert
+  // them all currently for simplicity.
+  Function *GetNctaidX =
+      Intrinsic::getDeclaration(M, Intrinsic::ptx_read_nctaid_x);
+  Function *GetNctaidY =
+      Intrinsic::getDeclaration(M, Intrinsic::ptx_read_nctaid_y);
+  Function *GetCtaidX =
+      Intrinsic::getDeclaration(M, Intrinsic::ptx_read_ctaid_x);
+  Function *GetCtaidY =
+      Intrinsic::getDeclaration(M, Intrinsic::ptx_read_ctaid_y);
+  Function *GetNtidX = Intrinsic::getDeclaration(M, Intrinsic::ptx_read_ntid_x);
+  Function *GetNtidY = Intrinsic::getDeclaration(M, Intrinsic::ptx_read_ntid_y);
+  Function *GetTidX = Intrinsic::getDeclaration(M, Intrinsic::ptx_read_tid_x);
+  Function *GetTidY = Intrinsic::getDeclaration(M, Intrinsic::ptx_read_tid_y);
+
+  Value *GridWidth = Builder.CreateCall(GetNctaidX);
+  GridWidth = Builder.CreateIntCast(GridWidth, Ty, false);
+  Value *GridHeight = Builder.CreateCall(GetNctaidY);
+  GridHeight = Builder.CreateIntCast(GridHeight, Ty, false);
+  Value *BlockWidth = Builder.CreateCall(GetNtidX);
+  BlockWidth = Builder.CreateIntCast(BlockWidth, Ty, false);
+  Value *BlockHeight = Builder.CreateCall(GetNtidY);
+  BlockHeight = Builder.CreateIntCast(BlockHeight, Ty, false);
+  Value *BIDx = Builder.CreateCall(GetCtaidX);
+  BIDx = Builder.CreateIntCast(BIDx, Ty, false);
+  Value *BIDy = Builder.CreateCall(GetCtaidY);
+  BIDy = Builder.CreateIntCast(BIDy, Ty, false);
+  Value *TIDx = Builder.CreateCall(GetTidX);
+  TIDx = Builder.CreateIntCast(TIDx, Ty, false);
+  Value *TIDy = Builder.CreateCall(GetTidY);
+  TIDy = Builder.CreateIntCast(TIDy, Ty, false);
+
+  Builder.CreateBr(BodyBB);
+  Builder.SetInsertPoint(BodyBB);
+
+  unsigned NumDims = OriginalIVS.size();
+  std::vector<Value *> Substitutions;
+  Value *BlockID, *ThreadID;
+  switch (NumDims) {
+  case 1: {
+    Value *BlockSize =
+        Builder.CreateMul(BlockWidth, BlockHeight, "p_gpu_blocksize");
+    BlockID = Builder.CreateMul(BIDy, GridWidth, "p_gpu_index_i");
+    BlockID = Builder.CreateAdd(BlockID, BIDx);
+    BlockID = Builder.CreateMul(BlockID, BlockSize);
+    ThreadID = Builder.CreateMul(TIDy, BlockWidth, "p_gpu_index_j");
+    ThreadID = Builder.CreateAdd(ThreadID, TIDx);
+    ThreadID = Builder.CreateAdd(ThreadID, BlockID);
+    Substitutions.push_back(ThreadID);
+    break;
+  }
+  case 2: {
+    BlockID = Builder.CreateMul(BIDy, GridWidth, "p_gpu_index_i");
+    BlockID = Builder.CreateAdd(BlockID, BIDx);
+    Substitutions.push_back(BlockID);
+    ThreadID = Builder.CreateMul(TIDy, BlockWidth, "p_gpu_index_j");
+    ThreadID = Builder.CreateAdd(ThreadID, TIDx);
+    Substitutions.push_back(ThreadID);
+    break;
+  }
+  case 3: {
+    BlockID = Builder.CreateMul(BIDy, GridWidth, "p_gpu_index_i");
+    BlockID = Builder.CreateAdd(BlockID, BIDx);
+    Substitutions.push_back(BlockID);
+    Substitutions.push_back(TIDy);
+    Substitutions.push_back(TIDx);
+    break;
+  }
+  case 4: {
+    Substitutions.push_back(BIDy);
+    Substitutions.push_back(BIDx);
+    Substitutions.push_back(TIDy);
+    Substitutions.push_back(TIDx);
+    break;
+  }
+  default:
+    assert(true &&
+           "We cannot transform parallel loops whose depth is larger than 4.");
+    return;
+  }
+
+  assert(OriginalIVS.size() == Substitutions.size() &&
+         "The size of IVS should be equal to the size of substitutions.");
+  for (unsigned i = 0; i < OriginalIVS.size(); ++i) {
+    VMap.insert(std::make_pair(OriginalIVS[i], Substitutions[i]));
+  }
+
+  Builder.CreateBr(ExitBB);
+  Builder.SetInsertPoint(--Builder.GetInsertPoint());
+  BasicBlock::iterator LoopBody = Builder.GetInsertPoint();
+
+  // Add the termination of the ptx-device subfunction.
+  Builder.SetInsertPoint(ExitBB);
+  Builder.CreateRetVoid();
+
+  Builder.SetInsertPoint(LoopBody);
+  *SubFunction = FN;
+}
+
+void PTXGenerator::startGeneration(SetVector<Value *> &UsedValues,
+                                   SetVector<Value *> &OriginalIVS,
+                                   ValueToValueMapTy &VMap,
+                                   BasicBlock::iterator *LoopBody) {
+  Function *SubFunction;
+  BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
+  createSubfunction(UsedValues, OriginalIVS, VMap, &SubFunction);
+  *LoopBody = Builder.GetInsertPoint();
+  Builder.SetInsertPoint(PrevInsertPoint);
+}
+
+IntegerType *PTXGenerator::getInt64Type() { return Builder.getInt64Ty(); }
+
+PointerType *PTXGenerator::getI8PtrType() {
+  return PointerType::getUnqual(Builder.getInt8Ty());
+}
+
+PointerType *PTXGenerator::getPtrI8PtrType() {
+  return PointerType::getUnqual(getI8PtrType());
+}
+
+PointerType *PTXGenerator::getFloatPtrType() {
+  return llvm::Type::getFloatPtrTy(getModule()->getContext());
+}
+
+PointerType *PTXGenerator::getGPUContextPtrType() {
+  return PointerType::getUnqual(ContextTy);
+}
+
+PointerType *PTXGenerator::getGPUModulePtrType() {
+  return PointerType::getUnqual(ModuleTy);
+}
+
+PointerType *PTXGenerator::getGPUDevicePtrType() {
+  return PointerType::getUnqual(DeviceTy);
+}
+
+PointerType *PTXGenerator::getPtrGPUDevicePtrType() {
+  return PointerType::getUnqual(DevDataTy);
+}
+
+PointerType *PTXGenerator::getGPUFunctionPtrType() {
+  return PointerType::getUnqual(KernelTy);
+}
+
+PointerType *PTXGenerator::getGPUEventPtrType() {
+  return PointerType::getUnqual(EventTy);
+}
+
+void PTXGenerator::InitializeGPUDataTypes() {
+  LLVMContext &Context = getModule()->getContext();
+
+  ContextTy = StructType::create(Context, "struct.PollyGPUContextT");
+  ModuleTy = StructType::create(Context, "struct.PollyGPUModuleT");
+  KernelTy = StructType::create(Context, "struct.PollyGPUFunctionT");
+  DeviceTy = StructType::create(Context, "struct.PollyGPUDeviceT");
+  DevDataTy = StructType::create(Context, "struct.PollyGPUDevicePtrT");
+  EventTy = StructType::create(Context, "struct.PollyGPUEventT");
+}
+
+void PTXGenerator::createCallInitDevice(Value *Context, Value *Device) {
+  const char *Name = "polly_initDevice";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(PointerType::getUnqual(getGPUContextPtrType()));
+    Args.push_back(PointerType::getUnqual(getGPUDevicePtrType()));
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall2(F, Context, Device);
+}
+
+void PTXGenerator::createCallGetPTXModule(Value *Buffer, Value *Module) {
+  const char *Name = "polly_getPTXModule";
+  llvm::Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getI8PtrType());
+    Args.push_back(PointerType::getUnqual(getGPUModulePtrType()));
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall2(F, Buffer, Module);
+}
+
+void PTXGenerator::createCallGetPTXKernelEntry(Value *Entry, Value *Module,
+                                               Value *Kernel) {
+  const char *Name = "polly_getPTXKernelEntry";
+  llvm::Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getI8PtrType());
+    Args.push_back(getGPUModulePtrType());
+    Args.push_back(PointerType::getUnqual(getGPUFunctionPtrType()));
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall3(F, Entry, Module, Kernel);
+}
+
+void PTXGenerator::createCallAllocateMemoryForHostAndDevice(Value *HostData,
+                                                            Value *DeviceData,
+                                                            Value *Size) {
+  const char *Name = "polly_allocateMemoryForHostAndDevice";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getPtrI8PtrType());
+    Args.push_back(PointerType::getUnqual(getPtrGPUDevicePtrType()));
+    Args.push_back(getInt64Type());
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall3(F, HostData, DeviceData, Size);
+}
+
+void PTXGenerator::createCallCopyFromHostToDevice(Value *DeviceData,
+                                                  Value *HostData,
+                                                  Value *Size) {
+  const char *Name = "polly_copyFromHostToDevice";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getPtrGPUDevicePtrType());
+    Args.push_back(getI8PtrType());
+    Args.push_back(getInt64Type());
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall3(F, DeviceData, HostData, Size);
+}
+
+void PTXGenerator::createCallCopyFromDeviceToHost(Value *HostData,
+                                                  Value *DeviceData,
+                                                  Value *Size) {
+  const char *Name = "polly_copyFromDeviceToHost";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getI8PtrType());
+    Args.push_back(getPtrGPUDevicePtrType());
+    Args.push_back(getInt64Type());
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall3(F, HostData, DeviceData, Size);
+}
+
+void PTXGenerator::createCallSetKernelParameters(Value *Kernel,
+                                                 Value *BlockWidth,
+                                                 Value *BlockHeight,
+                                                 Value *DeviceData) {
+  const char *Name = "polly_setKernelParameters";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getGPUFunctionPtrType());
+    Args.push_back(getInt64Type());
+    Args.push_back(getInt64Type());
+    Args.push_back(getPtrGPUDevicePtrType());
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall4(F, Kernel, BlockWidth, BlockHeight, DeviceData);
+}
+
+void PTXGenerator::createCallLaunchKernel(Value *Kernel, Value *GridWidth,
+                                          Value *GridHeight) {
+  const char *Name = "polly_launchKernel";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getGPUFunctionPtrType());
+    Args.push_back(getInt64Type());
+    Args.push_back(getInt64Type());
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall3(F, Kernel, GridWidth, GridHeight);
+}
+
+void PTXGenerator::createCallStartTimerByCudaEvent(Value *StartEvent,
+                                                   Value *StopEvent) {
+  const char *Name = "polly_startTimerByCudaEvent";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(PointerType::getUnqual(getGPUEventPtrType()));
+    Args.push_back(PointerType::getUnqual(getGPUEventPtrType()));
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall2(F, StartEvent, StopEvent);
+}
+
+void PTXGenerator::createCallStopTimerByCudaEvent(Value *StartEvent,
+                                                  Value *StopEvent,
+                                                  Value *Timer) {
+  const char *Name = "polly_stopTimerByCudaEvent";
+  Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getGPUEventPtrType());
+    Args.push_back(getGPUEventPtrType());
+    Args.push_back(getFloatPtrType());
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall3(F, StartEvent, StopEvent, Timer);
+}
+
+void PTXGenerator::createCallCleanupGPGPUResources(Value *HostData,
+                                                   Value *DeviceData,
+                                                   Value *Module,
+                                                   Value *Context,
+                                                   Value *Kernel) {
+  const char *Name = "polly_cleanupGPGPUResources";
+  llvm::Module *M = getModule();
+  Function *F = M->getFunction(Name);
+
+  // If F is not available, declare it.
+  if (!F) {
+    GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
+    std::vector<Type *> Args;
+    Args.push_back(getI8PtrType());
+    Args.push_back(getPtrGPUDevicePtrType());
+    Args.push_back(getGPUModulePtrType());
+    Args.push_back(getGPUContextPtrType());
+    Args.push_back(getGPUFunctionPtrType());
+    FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), Args, false);
+    F = Function::Create(Ty, Linkage, Name, M);
+  }
+
+  Builder.CreateCall5(F, HostData, DeviceData, Module, Context, Kernel);
+}
+
+Value *PTXGenerator::getCUDAGridWidth() {
+  return ConstantInt::get(getInt64Type(), GridWidth);
+}
+
+Value *PTXGenerator::getCUDAGridHeight() {
+  return ConstantInt::get(getInt64Type(), GridHeight);
+}
+
+Value *PTXGenerator::getCUDABlockWidth() {
+  return ConstantInt::get(getInt64Type(), BlockWidth);
+}
+
+Value *PTXGenerator::getCUDABlockHeight() {
+  return ConstantInt::get(getInt64Type(), BlockHeight);
+}
+
+Value *PTXGenerator::getOutputArraySizeInBytes() {
+  return ConstantInt::get(getInt64Type(), OutputBytes);
+}
+
+static Module *extractPTXFunctionsFromModule(const Module *M,
+                                             const StringRef &Triple) {
+  llvm::ValueToValueMapTy VMap;
+  Module *New = new Module("TempGPUModule", M->getContext());
+  New->setTargetTriple(Triple::normalize(Triple));
+
+  // Loop over the functions in the module, making external functions as before
+  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
+    if (!I->isDeclaration() &&
+        (I->getCallingConv() == CallingConv::PTX_Device ||
+         I->getCallingConv() == CallingConv::PTX_Kernel)) {
+      Function *NF =
+          Function::Create(cast<FunctionType>(I->getType()->getElementType()),
+                           I->getLinkage(), I->getName(), New);
+      NF->copyAttributesFrom(I);
+      VMap[I] = NF;
+
+      Function::arg_iterator DestI = NF->arg_begin();
+      for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();
+           ++J) {
+        DestI->setName(J->getName());
+        VMap[J] = DestI++;
+      }
+      SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
+      CloneFunctionInto(NF, I, VMap, /*ModuleLevelChanges=*/true, Returns);
+    }
+  }
+
+  return New;
+}
+
+static bool createASMAsString(Module *New, const StringRef &Triple,
+                              const StringRef &MCPU, const StringRef &Features,
+                              std::string &ASM) {
+  llvm::Triple TheTriple(Triple::normalize(Triple));
+  std::string ErrMsg;
+  const Target *TheTarget =
+      TargetRegistry::lookupTarget(TheTriple.getTriple(), ErrMsg);
+  if (!TheTarget) {
+    errs() << ErrMsg << "\n";
+    return false;
+  }
+
+  TargetOptions Options;
+  std::unique_ptr<TargetMachine> target(TheTarget->createTargetMachine(
+      TheTriple.getTriple(), MCPU, Features, Options));
+  assert(target.get() && "Could not allocate target machine!");
+  TargetMachine &Target = *target.get();
+
+  // Build up all of the passes that we want to do to the module.
+  PassManager PM;
+
+  TargetLibraryInfo *TLI = new TargetLibraryInfo(TheTriple);
+  PM.add(TLI);
+
+  PM.add(new DataLayoutPass(*Target.getDataLayout()));
+  Target.addAnalysisPasses(PM);
+
+  {
+    raw_string_ostream NameROS(ASM);
+    formatted_raw_ostream FOS(NameROS);
+
+    // Ask the target to add backend passes as necessary.
+    int UseVerifier = true;
+    if (Target.addPassesToEmitFile(PM, FOS, TargetMachine::CGFT_AssemblyFile,
+                                   UseVerifier)) {
+      errs() << "The target does not support generation of this file type!\n";
+      return false;
+    }
+
+    PM.run(*New);
+    FOS.flush();
+  }
+
+  return true;
+}
+
+Value *PTXGenerator::createPTXKernelFunction(Function *SubFunction) {
+  Module *M = getModule();
+  Module *GPUModule = extractPTXFunctionsFromModule(M, GPUTriple);
+  std::string LLVMKernelStr;
+  if (!createASMAsString(GPUModule, GPUTriple, "sm_20" /*MCPU*/,
+                         "" /*Features*/, LLVMKernelStr)) {
+    errs() << "Generate ptx string failed!\n";
+    return NULL;
+  }
+
+  Value *LLVMKernel =
+      Builder.CreateGlobalStringPtr(LLVMKernelStr, "llvm_kernel");
+
+  delete GPUModule;
+  return LLVMKernel;
+}
+
+Value *PTXGenerator::getPTXKernelEntryName(Function *SubFunction) {
+  StringRef Entry = SubFunction->getName();
+  return Builder.CreateGlobalStringPtr(Entry, "ptx_entry");
+}
+
+void PTXGenerator::eraseUnusedFunctions(Function *SubFunction) {
+  Module *M = getModule();
+  SubFunction->eraseFromParent();
+
+  if (Function *FuncPTXReadNCtaidX = M->getFunction("llvm.ptx.read.nctaid.x")) {
+    FuncPTXReadNCtaidX->eraseFromParent();
+  }
+
+  if (Function *FuncPTXReadNCtaidY = M->getFunction("llvm.ptx.read.nctaid.y")) {
+    FuncPTXReadNCtaidY->eraseFromParent();
+  }
+
+  if (Function *FuncPTXReadCtaidX = M->getFunction("llvm.ptx.read.ctaid.x")) {
+    FuncPTXReadCtaidX->eraseFromParent();
+  }
+
+  if (Function *FuncPTXReadCtaidY = M->getFunction("llvm.ptx.read.ctaid.y")) {
+    FuncPTXReadCtaidY->eraseFromParent();
+  }
+
+  if (Function *FuncPTXReadNTidX = M->getFunction("llvm.ptx.read.ntid.x")) {
+    FuncPTXReadNTidX->eraseFromParent();
+  }
+
+  if (Function *FuncPTXReadNTidY = M->getFunction("llvm.ptx.read.ntid.y")) {
+    FuncPTXReadNTidY->eraseFromParent();
+  }
+
+  if (Function *FuncPTXReadTidX = M->getFunction("llvm.ptx.read.tid.x")) {
+    FuncPTXReadTidX->eraseFromParent();
+  }
+
+  if (Function *FuncPTXReadTidY = M->getFunction("llvm.ptx.read.tid.y")) {
+    FuncPTXReadTidY->eraseFromParent();
+  }
+}
+
+void PTXGenerator::finishGeneration(Function *F) {
+  // Define data used by the GPURuntime library.
+  AllocaInst *PtrCUContext =
+      Builder.CreateAlloca(getGPUContextPtrType(), 0, "phcontext");
+  AllocaInst *PtrCUDevice =
+      Builder.CreateAlloca(getGPUDevicePtrType(), 0, "phdevice");
+  AllocaInst *PtrCUModule =
+      Builder.CreateAlloca(getGPUModulePtrType(), 0, "phmodule");
+  AllocaInst *PtrCUKernel =
+      Builder.CreateAlloca(getGPUFunctionPtrType(), 0, "phkernel");
+  AllocaInst *PtrCUStartEvent =
+      Builder.CreateAlloca(getGPUEventPtrType(), 0, "pstart_timer");
+  AllocaInst *PtrCUStopEvent =
+      Builder.CreateAlloca(getGPUEventPtrType(), 0, "pstop_timer");
+  AllocaInst *PtrDevData =
+      Builder.CreateAlloca(getPtrGPUDevicePtrType(), 0, "pdevice_data");
+  AllocaInst *PtrHostData =
+      Builder.CreateAlloca(getI8PtrType(), 0, "phost_data");
+  Type *FloatTy = llvm::Type::getFloatTy(getModule()->getContext());
+  AllocaInst *PtrElapsedTimes = Builder.CreateAlloca(FloatTy, 0, "ptimer");
+
+  // Initialize the GPU device.
+  createCallInitDevice(PtrCUContext, PtrCUDevice);
+
+  // Create the GPU kernel module and entry function.
+  Value *PTXString = createPTXKernelFunction(F);
+  Value *PTXEntry = getPTXKernelEntryName(F);
+  createCallGetPTXModule(PTXString, PtrCUModule);
+  LoadInst *CUModule = Builder.CreateLoad(PtrCUModule, "cumodule");
+  createCallGetPTXKernelEntry(PTXEntry, CUModule, PtrCUKernel);
+
+  // Allocate device memory and its corresponding host memory.
+  createCallAllocateMemoryForHostAndDevice(PtrHostData, PtrDevData,
+                                           getOutputArraySizeInBytes());
+
+  // Get the pointer to the device memory and set the GPU execution parameters.
+  LoadInst *DData = Builder.CreateLoad(PtrDevData, "device_data");
+  LoadInst *CUKernel = Builder.CreateLoad(PtrCUKernel, "cukernel");
+  createCallSetKernelParameters(CUKernel, getCUDABlockWidth(),
+                                getCUDABlockHeight(), DData);
+
+  // Create the start and end timer and record the start time.
+  createCallStartTimerByCudaEvent(PtrCUStartEvent, PtrCUStopEvent);
+
+  // Launch the GPU kernel.
+  createCallLaunchKernel(CUKernel, getCUDAGridWidth(), getCUDAGridHeight());
+
+  // Copy the results back from the GPU to the host.
+  LoadInst *HData = Builder.CreateLoad(PtrHostData, "host_data");
+  createCallCopyFromDeviceToHost(HData, DData, getOutputArraySizeInBytes());
+
+  // Record the end time.
+  LoadInst *CUStartEvent = Builder.CreateLoad(PtrCUStartEvent, "start_timer");
+  LoadInst *CUStopEvent = Builder.CreateLoad(PtrCUStopEvent, "stop_timer");
+  createCallStopTimerByCudaEvent(CUStartEvent, CUStopEvent, PtrElapsedTimes);
+
+  // Cleanup all the resources used.
+  LoadInst *CUContext = Builder.CreateLoad(PtrCUContext, "cucontext");
+  createCallCleanupGPGPUResources(HData, DData, CUModule, CUContext, CUKernel);
+
+  // Erase the ptx kernel and device subfunctions and ptx intrinsics from
+  // current module.
+  eraseUnusedFunctions(F);
+}
+#endif /* GPU_CODEGEN */
diff --git a/rc1/lib/CodeGen/Utils.cpp b/rc1/lib/CodeGen/Utils.cpp
new file mode 100644
index 0000000..36722d3
--- /dev/null
+++ b/rc1/lib/CodeGen/Utils.cpp
@@ -0,0 +1,88 @@
+//===--- Utils.cpp - Utility functions for the code generation --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains utility functions for the code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/CodeGen/Utils.h"
+#include "polly/CodeGen/IRBuilder.h"
+#include "polly/ScopInfo.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+using namespace llvm;
+
+BasicBlock *polly::executeScopConditionally(Scop &S, Pass *PassInfo) {
+  BasicBlock *StartBlock, *SplitBlock, *NewBlock;
+  Region &R = S.getRegion();
+  PollyIRBuilder Builder(R.getEntry());
+  DominatorTree &DT =
+      PassInfo->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  RegionInfo &RI = PassInfo->getAnalysis<RegionInfoPass>().getRegionInfo();
+  LoopInfo &LI = PassInfo->getAnalysis<LoopInfo>();
+
+  // Split the entry edge of the region and generate a new basic block on this
+  // edge. This function also updates ScopInfo and RegionInfo.
+  NewBlock = SplitEdge(R.getEnteringBlock(), R.getEntry(), PassInfo);
+  if (DT.dominates(R.getEntry(), NewBlock)) {
+    BasicBlock *OldBlock = R.getEntry();
+    std::string OldName = OldBlock->getName();
+
+    // Update ScopInfo.
+    for (ScopStmt *Stmt : S)
+      if (Stmt->getBasicBlock() == OldBlock) {
+        Stmt->setBasicBlock(NewBlock);
+        break;
+      }
+
+    // Update RegionInfo.
+    SplitBlock = OldBlock;
+    OldBlock->setName("polly.split");
+    NewBlock->setName(OldName);
+    R.replaceEntryRecursive(NewBlock);
+    RI.setRegionFor(NewBlock, &R);
+  } else {
+    RI.setRegionFor(NewBlock, R.getParent());
+    SplitBlock = NewBlock;
+  }
+
+  SplitBlock->setName("polly.split_new_and_old");
+  Function *F = SplitBlock->getParent();
+  StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
+  SplitBlock->getTerminator()->eraseFromParent();
+  Builder.SetInsertPoint(SplitBlock);
+  Builder.CreateCondBr(Builder.getTrue(), StartBlock, R.getEntry());
+  if (Loop *L = LI.getLoopFor(SplitBlock))
+    L->addBasicBlockToLoop(StartBlock, LI.getBase());
+  DT.addNewBlock(StartBlock, SplitBlock);
+  Builder.SetInsertPoint(StartBlock);
+
+  BasicBlock *MergeBlock;
+
+  if (R.getExit()->getSinglePredecessor())
+    // No splitEdge required.  A block with a single predecessor cannot have
+    // PHI nodes that would complicate life.
+    MergeBlock = R.getExit();
+  else {
+    MergeBlock = SplitEdge(R.getExitingBlock(), R.getExit(), PassInfo);
+    // SplitEdge will never split R.getExit(), as R.getExit() has more than
+    // one predecessor. Hence, mergeBlock is always a newly generated block.
+    R.replaceExitRecursive(MergeBlock);
+    RI.setRegionFor(MergeBlock, &R);
+  }
+
+  Builder.CreateBr(MergeBlock);
+  MergeBlock->setName("polly.merge_new_and_old");
+
+  if (DT.dominates(SplitBlock, MergeBlock))
+    DT.changeImmediateDominator(MergeBlock, SplitBlock);
+  return StartBlock;
+}
diff --git a/rc1/lib/Exchange/JSONExporter.cpp b/rc1/lib/Exchange/JSONExporter.cpp
new file mode 100644
index 0000000..506c017
--- /dev/null
+++ b/rc1/lib/Exchange/JSONExporter.cpp
@@ -0,0 +1,348 @@
+//===-- 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/Options.h"
+#include "polly/ScopInfo.h"
+#include "polly/ScopPass.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ToolOutputFile.h"
+
+#include "json/reader.h"
+#include "json/writer.h"
+
+#include "isl/set.h"
+#include "isl/map.h"
+#include "isl/constraint.h"
+#include "isl/printer.h"
+
+#include <memory>
+#include <string>
+#include <system_error>
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-import-jscop"
+
+STATISTIC(NewAccessMapFound, "Number of updated access functions");
+
+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("."), cl::cat(PollyCategory));
+
+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(""), cl::cat(PollyCategory));
+
+struct JSONExporter : public ScopPass {
+  static char ID;
+  Scop *S;
+  explicit JSONExporter() : ScopPass(ID) {}
+
+  std::string getFileName(Scop *S) const;
+  Json::Value getJSON(Scop &scop) const;
+  virtual bool runOnScop(Scop &S);
+  void printScop(raw_ostream &OS) const;
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+
+struct JSONImporter : public ScopPass {
+  static char ID;
+  Scop *S;
+  std::vector<std::string> newAccessStrings;
+  explicit JSONImporter() : ScopPass(ID) {}
+
+  std::string getFileName(Scop *S) const;
+  virtual bool runOnScop(Scop &S);
+  void printScop(raw_ostream &OS) const;
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+}
+
+char JSONExporter::ID = 0;
+std::string JSONExporter::getFileName(Scop *S) const {
+  std::string FunctionName = S->getRegion().getEntry()->getParent()->getName();
+  std::string FileName = FunctionName + "___" + S->getNameStr() + ".jscop";
+  return FileName;
+}
+
+void JSONExporter::printScop(raw_ostream &OS) const { S->print(OS); }
+
+Json::Value JSONExporter::getJSON(Scop &scop) const {
+  Json::Value root;
+
+  root["name"] = S->getRegion().getNameStr();
+  root["context"] = S->getContextStr();
+  root["statements"];
+
+  for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+    ScopStmt *Stmt = *SI;
+
+    Json::Value statement;
+
+    statement["name"] = Stmt->getBaseName();
+    statement["domain"] = Stmt->getDomainStr();
+    statement["schedule"] = Stmt->getScatteringStr();
+    statement["accesses"];
+
+    for (MemoryAccess *MA : *Stmt) {
+      Json::Value access;
+
+      access["kind"] = MA->isRead() ? "read" : "write";
+      access["relation"] = MA->getAccessRelationStr();
+
+      statement["accesses"].append(access);
+    }
+
+    root["statements"].append(statement);
+  }
+
+  return root;
+}
+
+bool JSONExporter::runOnScop(Scop &scop) {
+  S = &scop;
+  Region &R = S->getRegion();
+
+  std::string FileName = ImportDir + "/" + getFileName(S);
+
+  Json::Value jscop = getJSON(scop);
+  Json::StyledWriter writer;
+  std::string fileContent = writer.write(jscop);
+
+  // Write to file.
+  std::string ErrInfo;
+  tool_output_file F(FileName.c_str(), ErrInfo, llvm::sys::fs::F_Text);
+
+  std::string FunctionName = R.getEntry()->getParent()->getName();
+  errs() << "Writing JScop '" << R.getNameStr() << "' in function '"
+         << FunctionName << "' to '" << FileName << "'.\n";
+
+  if (ErrInfo.empty()) {
+    F.os() << fileContent;
+    F.os().close();
+    if (!F.os().has_error()) {
+      errs() << "\n";
+      F.keep();
+      return false;
+    }
+  }
+
+  errs() << "  error opening file for writing!\n";
+  F.os().clear_error();
+
+  return false;
+}
+
+void JSONExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.setPreservesAll();
+  AU.addRequired<ScopInfo>();
+}
+
+Pass *polly::createJSONExporterPass() { return new JSONExporter(); }
+
+char JSONImporter::ID = 0;
+std::string JSONImporter::getFileName(Scop *S) const {
+  std::string FunctionName = S->getRegion().getEntry()->getParent()->getName();
+  std::string FileName = FunctionName + "___" + S->getNameStr() + ".jscop";
+
+  if (ImportPostfix != "")
+    FileName += "." + ImportPostfix;
+
+  return FileName;
+}
+
+void JSONImporter::printScop(raw_ostream &OS) const {
+  S->print(OS);
+  for (std::vector<std::string>::const_iterator I = newAccessStrings.begin(),
+                                                E = newAccessStrings.end();
+       I != E; I++)
+    OS << "New access function '" << *I << "'detected in JSCOP file\n";
+}
+
+typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
+
+bool JSONImporter::runOnScop(Scop &scop) {
+  S = &scop;
+  Region &R = S->getRegion();
+  Dependences *D = &getAnalysis<Dependences>();
+
+  std::string FileName = ImportDir + "/" + getFileName(S);
+
+  std::string FunctionName = R.getEntry()->getParent()->getName();
+  errs() << "Reading JScop '" << R.getNameStr() << "' in function '"
+         << FunctionName << "' from '" << FileName << "'.\n";
+  ErrorOr<std::unique_ptr<MemoryBuffer>> result =
+      MemoryBuffer::getFile(FileName);
+  std::error_code ec = result.getError();
+
+  if (ec) {
+    errs() << "File could not be read: " << ec.message() << "\n";
+    return false;
+  }
+
+  Json::Reader reader;
+  Json::Value jscop;
+
+  bool parsingSuccessful = reader.parse(result.get()->getBufferStart(), jscop);
+
+  if (!parsingSuccessful) {
+    errs() << "JSCoP file could not be parsed\n";
+    return false;
+  }
+
+  isl_set *OldContext = S->getContext();
+  isl_set *NewContext =
+      isl_set_read_from_str(S->getIslCtx(), jscop["context"].asCString());
+
+  for (unsigned i = 0; i < isl_set_dim(OldContext, isl_dim_param); i++) {
+    isl_id *id = isl_set_get_dim_id(OldContext, isl_dim_param, i);
+    NewContext = isl_set_set_dim_id(NewContext, isl_dim_param, i, id);
+  }
+
+  isl_set_free(OldContext);
+  S->setContext(NewContext);
+
+  StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy());
+
+  int index = 0;
+
+  for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+    Json::Value schedule = jscop["statements"][index]["schedule"];
+    isl_map *m = isl_map_read_from_str(S->getIslCtx(), schedule.asCString());
+    isl_space *Space = (*SI)->getDomainSpace();
+
+    // Copy the old tuple id. This is necessary to retain the user pointer,
+    // that stores the reference to the ScopStmt this scattering belongs to.
+    m = isl_map_set_tuple_id(m, isl_dim_in,
+                             isl_space_get_tuple_id(Space, isl_dim_set));
+    isl_space_free(Space);
+    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";
+    for (StatementToIslMapTy::iterator SI = NewScattering.begin(),
+                                       SE = NewScattering.end();
+         SI != SE; ++SI)
+      isl_map_free(SI->second);
+    return false;
+  }
+
+  for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+    ScopStmt *Stmt = *SI;
+
+    if (NewScattering.find(Stmt) != NewScattering.end())
+      Stmt->setScattering(NewScattering[Stmt]);
+  }
+
+  int statementIdx = 0;
+  for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+    ScopStmt *Stmt = *SI;
+
+    int memoryAccessIdx = 0;
+    for (MemoryAccess *MA : *Stmt) {
+      Json::Value accesses = jscop["statements"][statementIdx]["accesses"]
+                                  [memoryAccessIdx]["relation"];
+      isl_map *newAccessMap =
+          isl_map_read_from_str(S->getIslCtx(), accesses.asCString());
+      isl_map *currentAccessMap = MA->getAccessRelation();
+
+      if (isl_map_dim(newAccessMap, isl_dim_param) !=
+          isl_map_dim(currentAccessMap, isl_dim_param)) {
+        errs() << "JScop file changes the number of parameter dimensions\n";
+        isl_map_free(currentAccessMap);
+        isl_map_free(newAccessMap);
+        return false;
+      }
+
+      // We need to copy the isl_ids for the parameter dimensions to the new
+      // map. Without doing this the current map would have different
+      // ids then the new one, even though both are named identically.
+      for (unsigned i = 0; i < isl_map_dim(currentAccessMap, isl_dim_param);
+           i++) {
+        isl_id *id = isl_map_get_dim_id(currentAccessMap, isl_dim_param, i);
+        newAccessMap = isl_map_set_dim_id(newAccessMap, isl_dim_param, i, id);
+      }
+
+      // Copy the old tuple id. This is necessary to retain the user pointer,
+      // that stores the reference to the ScopStmt this access belongs to.
+      isl_id *Id = isl_map_get_tuple_id(currentAccessMap, isl_dim_in);
+      newAccessMap = isl_map_set_tuple_id(newAccessMap, isl_dim_in, Id);
+
+      if (!isl_map_has_equal_space(currentAccessMap, newAccessMap)) {
+        errs() << "JScop file contains access function with incompatible "
+               << "dimensions\n";
+        isl_map_free(currentAccessMap);
+        isl_map_free(newAccessMap);
+        return false;
+      }
+      if (isl_map_dim(newAccessMap, isl_dim_out) != 1) {
+        errs() << "New access map in JScop file should be single dimensional\n";
+        isl_map_free(currentAccessMap);
+        isl_map_free(newAccessMap);
+        return false;
+      }
+      if (!isl_map_is_equal(newAccessMap, currentAccessMap)) {
+        // Statistics.
+        ++NewAccessMapFound;
+        newAccessStrings.push_back(accesses.asCString());
+        MA->setNewAccessRelation(newAccessMap);
+      } else {
+        isl_map_free(newAccessMap);
+      }
+      isl_map_free(currentAccessMap);
+      memoryAccessIdx++;
+    }
+    statementIdx++;
+  }
+
+  return false;
+}
+
+void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const {
+  ScopPass::getAnalysisUsage(AU);
+  AU.addRequired<Dependences>();
+}
+Pass *polly::createJSONImporterPass() { return new JSONImporter(); }
+
+INITIALIZE_PASS_BEGIN(JSONExporter, "polly-export-jscop",
+                      "Polly - Export Scops as JSON"
+                      " (Writes a .jscop file for each Scop)",
+                      false, false);
+INITIALIZE_PASS_DEPENDENCY(Dependences)
+INITIALIZE_PASS_END(JSONExporter, "polly-export-jscop",
+                    "Polly - Export Scops as JSON"
+                    " (Writes a .jscop file for each Scop)",
+                    false, false)
+
+INITIALIZE_PASS_BEGIN(JSONImporter, "polly-import-jscop",
+                      "Polly - Import Scops from JSON"
+                      " (Reads a .jscop file for each Scop)",
+                      false, false);
+INITIALIZE_PASS_DEPENDENCY(Dependences)
+INITIALIZE_PASS_END(JSONImporter, "polly-import-jscop",
+                    "Polly - Import Scops from JSON"
+                    " (Reads a .jscop file for each Scop)",
+                    false, false)
diff --git a/rc1/lib/Exchange/ScopLib.cpp b/rc1/lib/Exchange/ScopLib.cpp
new file mode 100644
index 0000000..d773f86
--- /dev/null
+++ b/rc1/lib/Exchange/ScopLib.cpp
@@ -0,0 +1,767 @@
+//===- 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 "stdio.h"
+#include "isl/set.h"
+#include "isl/map.h"
+#include "isl/constraint.h"
+#include "isl/val_gmp.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 (ScopStmt *Stmt : *PollyScop)
+    for (MemoryAccess *MA : *Stmt) {
+      const Value *BaseAddr = MA->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->getName();
+        scoplib->arrays[i] = (char *)malloc(sizeof(char *) * (name.size() + 1));
+        strcpy(scoplib->arrays[i], name.c_str());
+      }
+}
+
+void ScopLib::initializeScattering() {}
+
+scoplib_statement_p ScopLib::initializeStatement(ScopStmt *stmt) {
+  scoplib_statement_p Stmt = scoplib_statement_malloc();
+
+  // Domain & Schedule
+  Stmt->domain = scoplib_matrix_list_malloc();
+  Stmt->domain->elt = domainToMatrix(stmt->getDomain());
+  Stmt->schedule = scatteringToMatrix(stmt->getScattering());
+
+  // Statement name
+  std::string entryName;
+  raw_string_ostream OS(entryName);
+  stmt->getBasicBlock()->printAsOperand(OS, false);
+  entryName = OS.str();
+  Stmt->body = (char *)malloc(sizeof(char) * (entryName.size() + 1));
+  strcpy(Stmt->body, entryName.c_str());
+
+  // Iterator names
+  Stmt->nb_iterators = stmt->getNumIterators();
+  Stmt->iterators = (char **)malloc(sizeof(char *) * Stmt->nb_iterators);
+
+  for (int i = 0; i < Stmt->nb_iterators; ++i) {
+    Stmt->iterators[i] = (char *)malloc(sizeof(char *) * 20);
+    sprintf(Stmt->iterators[i], "i_%d", i);
+  }
+
+  // Memory Accesses
+  Stmt->read = createAccessMatrix(stmt, true);
+  Stmt->write = createAccessMatrix(stmt, false);
+
+  return Stmt;
+}
+
+void ScopLib::initializeStatements() {
+  for (Scop::reverse_iterator SI = PollyScop->rbegin(), SE = PollyScop->rend();
+       SI != SE; ++SI) {
+    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 = nullptr;
+
+  if (stmt->write)
+    scoplib_matrix_free(stmt->write);
+  stmt->write = nullptr;
+
+  scoplib_matrix_list_p current = stmt->domain;
+  while (current) {
+    scoplib_matrix_list_p next = current->next;
+    current->next = nullptr;
+    scoplib_matrix_free(current->elt);
+    current->elt = nullptr;
+    scoplib_matrix_list_free(current);
+    current = next;
+  }
+  stmt->domain = nullptr;
+
+  if (stmt->schedule)
+    scoplib_matrix_free(stmt->schedule);
+  stmt->schedule = nullptr;
+
+  for (int i = 0; i < stmt->nb_iterators; ++i)
+    free(stmt->iterators[i]);
+
+  free(stmt->iterators);
+  stmt->iterators = nullptr;
+  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_val *v;
+
+  // Assign variables
+  for (int i = 0; i < nb_vars; ++i) {
+    v = isl_constraint_get_coefficient_val(c, isl_dim_set, i);
+    SCOPVAL_init(vec->p[i + 1]);
+    isl_val_get_num_gmp(v, vec->p[i + 1]);
+    isl_val_free(v);
+  }
+
+  // Assign parameters
+  for (int i = 0; i < nb_params; ++i) {
+    v = isl_constraint_get_coefficient_val(c, isl_dim_param, i);
+    SCOPVAL_init(vec->p[nb_vars + i + 1]);
+    isl_val_get_num_gmp(v, vec->p[nb_vars + i + 1]);
+    isl_val_free(v);
+  }
+
+  // Assign constant
+  v = isl_constraint_get_constant_val(c);
+  SCOPVAL_init(vec->p[nb_params + nb_vars + 1]);
+  isl_val_get_num_gmp(v, vec->p[nb_params + nb_vars + 1]);
+
+  scoplib_matrix_insert_vector(m, vec, m->NbRows);
+
+  scoplib_vector_free(vec);
+  isl_constraint_free(c);
+  isl_val_free(v);
+
+  return 0;
+}
+
+/// Add an isl basic set to a ScopLib matrix_list
+///
+/// @param bset The basic set to add
+/// @param user The matrix list we should add the basic set to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in ScopLib. So union of
+/// polyhedron are not yet supported
+int ScopLib::domainToMatrix_basic_set(isl_basic_set *bset, void *user) {
+  scoplib_matrix_p m = (scoplib_matrix_p)user;
+  assert(!m->NbRows && "Union of polyhedron not yet supported");
+
+  isl_basic_set_foreach_constraint(bset, &domainToMatrix_constraint, user);
+  isl_basic_set_free(bset);
+  return 0;
+}
+
+/// Translate a isl_set to a ScopLib matrix.
+///
+/// @param PS The set to be translated
+/// @return A ScopLib Matrix
+scoplib_matrix_p ScopLib::domainToMatrix(__isl_take isl_set *set) {
+  set = isl_set_compute_divs(set);
+  set = isl_set_align_divs(set);
+
+  // Initialize the matrix.
+  unsigned NbRows, NbColumns;
+  NbRows = 0;
+  NbColumns = isl_set_n_dim(set) + isl_set_n_param(set) + 2;
+  scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns);
+
+  // Copy the content into the matrix.
+  isl_set_foreach_basic_set(set, &domainToMatrix_basic_set, matrix);
+
+  isl_set_free(set);
+
+  return matrix;
+}
+
+/// Add an isl constraint to an ScopLib matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int ScopLib::scatteringToMatrix_constraint(isl_constraint *c, void *user) {
+  scoplib_matrix_p m = (scoplib_matrix_p)user;
+
+  int nb_params = isl_constraint_dim(c, isl_dim_param);
+  int nb_in = isl_constraint_dim(c, isl_dim_in);
+  int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+  assert(!nb_div && "Existentially quantified variables not yet supported");
+
+  scoplib_vector_p vec = scoplib_vector_malloc(nb_params + nb_in + 2);
+
+  // Assign type
+  if (isl_constraint_is_equality(c))
+    scoplib_vector_tag_equality(vec);
+  else
+    scoplib_vector_tag_inequality(vec);
+
+  isl_val *v;
+
+  // Assign variables
+  for (int i = 0; i < nb_in; ++i) {
+    v = isl_constraint_get_coefficient_val(c, isl_dim_in, i);
+    SCOPVAL_init(vec->p[i + 1]);
+    isl_val_get_num_gmp(v, vec->p[i + 1]);
+    isl_val_free(v);
+  }
+
+  // Assign parameters
+  for (int i = 0; i < nb_params; ++i) {
+    v = isl_constraint_get_coefficient_val(c, isl_dim_param, i);
+    SCOPVAL_init(vec->p[nb_in + i + 1]);
+    isl_val_get_num_gmp(v, vec->p[nb_in + i + 1]);
+    isl_val_free(v);
+  }
+
+  // Assign constant
+  v = isl_constraint_get_constant_val(c);
+  SCOPVAL_init(vec->p[nb_in + nb_params + 1]);
+  isl_val_get_num_gmp(v, vec->p[nb_in + nb_params + 1]);
+
+  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);
+
+  scoplib_vector_free(null);
+  scoplib_vector_free(vec);
+  isl_constraint_free(c);
+  isl_val_free(v);
+
+  return 0;
+}
+
+/// Add an isl basic map to a ScopLib matrix_list
+///
+/// @param bmap The basic map to add
+/// @param user The matrix list we should add the basic map to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in ScopLib. So union of
+/// polyhedron are not yet supported
+int ScopLib::scatteringToMatrix_basic_map(isl_basic_map *bmap, void *user) {
+  scoplib_matrix_p m = (scoplib_matrix_p)user;
+  assert(!m->NbRows && "Union of polyhedron not yet supported");
+
+  isl_basic_map_foreach_constraint(bmap, &scatteringToMatrix_constraint, user);
+  isl_basic_map_free(bmap);
+  return 0;
+}
+
+/// Translate a isl_map to a ScopLib matrix.
+///
+/// @param map The map to be translated
+/// @return A ScopLib Matrix
+scoplib_matrix_p ScopLib::scatteringToMatrix(__isl_take isl_map *map) {
+  map = isl_map_compute_divs(map);
+  map = isl_map_align_divs(map);
+
+  // Initialize the matrix.
+  unsigned NbRows, NbColumns;
+  NbRows = 0;
+  NbColumns = isl_map_n_in(map) + isl_map_n_param(map) + 2;
+  scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns);
+
+  // Copy the content into the matrix.
+  isl_map_foreach_basic_map(map, &scatteringToMatrix_basic_map, matrix);
+
+  // Only keep the relevant rows.
+  scoplib_matrix_p reduced =
+      scoplib_matrix_ncopy(matrix, isl_map_n_in(map) * 2 + 1);
+
+  scoplib_matrix_free(matrix);
+  isl_map_free(map);
+
+  return reduced;
+}
+
+/// Add an isl constraint to an ScopLib matrix.
+///
+/// @param user The matrix
+/// @param c The constraint
+int ScopLib::accessToMatrix_constraint(isl_constraint *c, void *user) {
+  scoplib_matrix_p m = (scoplib_matrix_p)user;
+
+  int nb_params = isl_constraint_dim(c, isl_dim_param);
+  int nb_in = isl_constraint_dim(c, isl_dim_in);
+  int nb_div = isl_constraint_dim(c, isl_dim_div);
+
+  assert(!nb_div && "Existentially quantified variables not yet supported");
+
+  scoplib_vector_p vec = scoplib_vector_malloc(nb_params + nb_in + 2);
+
+  isl_val *v;
+
+  // The access dimension has to be one.
+  v = isl_constraint_get_coefficient_val(c, isl_dim_out, 0);
+  assert((isl_val_is_one(v) || isl_val_is_negone(v)) &&
+         "Access relations not supported in scoplib");
+  bool inverse = isl_val_is_one(v);
+  isl_val_free(v);
+
+  // Assign variables
+  for (int i = 0; i < nb_in; ++i) {
+    v = isl_constraint_get_coefficient_val(c, isl_dim_in, i);
+
+    if (inverse)
+      v = isl_val_neg(v);
+
+    SCOPVAL_init(vec->p[i + 1]);
+    isl_val_get_num_gmp(v, vec->p[i + 1]);
+    isl_val_free(v);
+  }
+
+  // Assign parameters
+  for (int i = 0; i < nb_params; ++i) {
+    v = isl_constraint_get_coefficient_val(c, isl_dim_param, i);
+
+    if (inverse)
+      v = isl_val_neg(v);
+
+    SCOPVAL_init(vec->p[nb_in + i + 1]);
+    isl_val_get_num_gmp(v, vec->p[nb_in + i + 1]);
+    isl_val_free(v);
+  }
+
+  // Assign constant
+  v = isl_constraint_get_constant_val(c);
+
+  if (inverse)
+    v = isl_val_neg(v);
+
+  SCOPVAL_init(vec->p[nb_in + nb_params + 1]);
+  isl_val_get_num_gmp(v, vec->p[nb_in + nb_params + 1]);
+
+  scoplib_matrix_insert_vector(m, vec, m->NbRows);
+
+  scoplib_vector_free(vec);
+  isl_constraint_free(c);
+  isl_val_free(v);
+
+  return 0;
+}
+
+/// Add an isl basic map to a ScopLib matrix_list
+///
+/// @param bmap The basic map to add
+/// @param user The matrix list we should add the basic map to
+///
+/// XXX: At the moment this function expects just a matrix, as support
+/// for matrix lists is currently not available in ScopLib. So union of
+/// polyhedron are not yet supported
+int ScopLib::accessToMatrix_basic_map(isl_basic_map *bmap, void *user) {
+  isl_basic_map_foreach_constraint(bmap, &accessToMatrix_constraint, user);
+  isl_basic_map_free(bmap);
+  return 0;
+}
+
+/// Create the memory access matrix for scoplib
+///
+/// @param S The polly statement the access matrix is created for.
+/// @param isRead Are we looking for read or write accesses?
+/// @param ArrayMap A map translating from the memory references to the scoplib
+/// indeces
+///
+/// @return The memory access matrix, as it is required by scoplib.
+scoplib_matrix_p ScopLib::createAccessMatrix(ScopStmt *S, bool isRead) {
+  unsigned NbColumns = S->getNumIterators() + S->getNumParams() + 2;
+  scoplib_matrix_p m = scoplib_matrix_malloc(0, NbColumns);
+
+  for (MemoryAccess *MA : *S)
+    if (MA->isRead() == isRead) {
+      // Extract the access function.
+      isl_map *AccessRelation = MA->getAccessRelation();
+      isl_map_foreach_basic_map(AccessRelation, &accessToMatrix_basic_map, m);
+      isl_map_free(AccessRelation);
+
+      // Set the index of the memory access base element.
+      std::map<const Value *, int>::iterator BA =
+          ArrayMap.find(MA->getBaseAddr());
+      SCOPVAL_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 = nullptr;
+  scoplib->nb_arrays = 0;
+
+  // Free parameters
+  for (int i = 0; i < scoplib->nb_parameters; ++i)
+    free(scoplib->parameters[i]);
+
+  free(scoplib->parameters);
+  scoplib->parameters = nullptr;
+  scoplib->nb_parameters = 0;
+
+  scoplib_statement_p stmt = scoplib->statement;
+
+  // Free Statements
+  while (stmt) {
+    scoplib_statement_p TempStmt = stmt->next;
+    stmt->next = nullptr;
+    freeStatement(stmt);
+    stmt = TempStmt;
+  }
+
+  scoplib->statement = nullptr;
+
+  scoplib_scop_free(scoplib);
+}
+/// @brief Create an isl constraint from a row of ScopLib integers.
+///
+/// @param row An array of isl/ScopLib integers.
+/// @param Space An isl space object, describing how to spilt the dimensions.
+///
+/// @return An isl constraint representing this integer array.
+isl_constraint *constraintFromMatrixRow(mpz_t *row,
+                                        __isl_take isl_space *Space) {
+  isl_constraint *c;
+  isl_ctx *ctx;
+
+  ctx = isl_space_get_ctx(Space);
+  unsigned NbIn = isl_space_dim(Space, isl_dim_in);
+  unsigned NbParam = isl_space_dim(Space, isl_dim_param);
+
+  if (SCOPVAL_zero_p(row[0]))
+    c = isl_equality_alloc(isl_local_space_from_space(Space));
+  else
+    c = isl_inequality_alloc(isl_local_space_from_space(Space));
+
+  unsigned current_column = 1;
+
+  isl_val *v;
+
+  for (unsigned j = 0; j < NbIn; ++j) {
+    v = isl_val_int_from_gmp(ctx, row[current_column++]);
+    c = isl_constraint_set_coefficient_val(c, isl_dim_in, j, v);
+  }
+
+  for (unsigned j = 0; j < NbParam; ++j) {
+    v = isl_val_int_from_gmp(ctx, row[current_column++]);
+    c = isl_constraint_set_coefficient_val(c, isl_dim_param, j, v);
+  }
+
+  v = isl_val_int_from_gmp(ctx, row[current_column]);
+  c = isl_constraint_set_constant_val(c, v);
+
+  return c;
+}
+
+/// @brief Create an isl map from a ScopLib matrix.
+///
+/// @param m The ScopLib matrix to translate.
+/// @param Space The dimensions that are contained in the ScopLib matrix.
+///
+/// @return An isl map representing m.
+isl_map *mapFromMatrix(scoplib_matrix_p m, __isl_take isl_space *Space,
+                       unsigned scatteringDims) {
+  isl_basic_map *bmap = isl_basic_map_universe(isl_space_copy(Space));
+
+  for (unsigned i = 0; i < m->NbRows; ++i) {
+    isl_constraint *c;
+    c = constraintFromMatrixRow(m->p[i], isl_space_copy(Space));
+    c = isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1);
+    bmap = isl_basic_map_add_constraint(bmap, c);
+  }
+
+  for (unsigned i = m->NbRows; i < scatteringDims; i++) {
+    isl_constraint *c;
+    c = isl_equality_alloc(isl_local_space_from_space(isl_space_copy(Space)));
+    c = isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
+    bmap = isl_basic_map_add_constraint(bmap, c);
+  }
+
+  isl_space_free(Space);
+
+  return isl_map_from_basic_map(bmap);
+}
+/// @brief Create an isl constraint from a row of ScopLib integers.
+///
+/// @param row An array of isl/ScopLib integers.
+/// @param Space An isl space object, describing how to spilt the dimensions.
+///
+/// @return An isl constraint representing this integer array.
+isl_constraint *constraintFromMatrixRowFull(mpz_t *row,
+                                            __isl_take isl_space *Space) {
+  isl_constraint *c;
+  isl_ctx *ctx = isl_space_get_ctx(Space);
+
+  unsigned NbOut = isl_space_dim(Space, isl_dim_out);
+  unsigned NbIn = isl_space_dim(Space, isl_dim_in);
+  unsigned NbParam = isl_space_dim(Space, isl_dim_param);
+
+  isl_local_space *LSpace = isl_local_space_from_space(Space);
+
+  if (SCOPVAL_zero_p(row[0]))
+    c = isl_equality_alloc(LSpace);
+  else
+    c = isl_inequality_alloc(LSpace);
+
+  unsigned current_column = 1;
+
+  isl_val *v;
+
+  for (unsigned j = 0; j < NbOut; ++j) {
+    v = isl_val_int_from_gmp(ctx, row[current_column++]);
+    c = isl_constraint_set_coefficient_val(c, isl_dim_out, j, v);
+  }
+
+  for (unsigned j = 0; j < NbIn; ++j) {
+    v = isl_val_int_from_gmp(ctx, row[current_column++]);
+    c = isl_constraint_set_coefficient_val(c, isl_dim_in, j, v);
+  }
+
+  for (unsigned j = 0; j < NbParam; ++j) {
+    v = isl_val_int_from_gmp(ctx, row[current_column++]);
+    c = isl_constraint_set_coefficient_val(c, isl_dim_param, j, v);
+  }
+
+  v = isl_val_int_from_gmp(ctx, row[current_column]);
+  c = isl_constraint_set_constant_val(c, v);
+
+  return c;
+}
+
+/// @brief Create an isl map from a ScopLib matrix.
+///
+/// @param m The ScopLib matrix to translate.
+/// @param Space The dimensions that are contained in the ScopLib matrix.
+///
+/// @return An isl map representing m.
+isl_map *mapFromMatrix(scoplib_matrix_p m, __isl_take isl_space *Space) {
+  isl_basic_map *bmap = isl_basic_map_universe(isl_space_copy(Space));
+
+  for (unsigned i = 0; i < m->NbRows; ++i) {
+    isl_constraint *c;
+
+    c = constraintFromMatrixRowFull(m->p[i], isl_space_copy(Space));
+    bmap = isl_basic_map_add_constraint(bmap, c);
+  }
+
+  isl_space_free(Space);
+
+  return isl_map_from_basic_map(bmap);
+}
+
+/// @brief Create a new scattering for PollyStmt.
+///
+/// @param m The matrix describing the new scattering.
+/// @param PollyStmt The statement to create the scattering for.
+///
+/// @return An isl_map describing the scattering.
+isl_map *scatteringForStmt(scoplib_matrix_p m, ScopStmt *PollyStmt,
+                           int scatteringDims) {
+  unsigned NbParam = PollyStmt->getNumParams();
+  unsigned NbIterators = PollyStmt->getNumIterators();
+  unsigned NbScattering;
+
+  if (scatteringDims == -1)
+    NbScattering = m->NbColumns - 2 - NbParam - NbIterators;
+  else
+    NbScattering = scatteringDims;
+
+  isl_ctx *ctx = PollyStmt->getParent()->getIslCtx();
+  isl_space *Space = isl_dim_alloc(ctx, NbParam, NbIterators, NbScattering);
+
+  isl_space *ParamSpace = PollyStmt->getParent()->getParamSpace();
+
+  // We need to copy the isl_ids for the parameter dimensions to the new
+  // map. Without doing this the current map would have different
+  // ids then the new one, even though both are named identically.
+  for (unsigned i = 0; i < isl_space_dim(Space, isl_dim_param); i++) {
+    isl_id *id = isl_space_get_dim_id(ParamSpace, isl_dim_param, i);
+    Space = isl_space_set_dim_id(Space, isl_dim_param, i, id);
+  }
+
+  isl_space_free(ParamSpace);
+
+  Space = isl_space_set_tuple_name(Space, isl_dim_out, "scattering");
+  Space = isl_space_set_tuple_id(Space, isl_dim_in, PollyStmt->getDomainId());
+
+  if (scatteringDims == -1)
+    return mapFromMatrix(m, Space);
+
+  return mapFromMatrix(m, Space, scatteringDims);
+}
+
+unsigned maxScattering(scoplib_statement_p stmt) {
+  unsigned max = 0;
+
+  while (stmt) {
+    max = std::max(max, stmt->schedule->NbRows);
+    stmt = stmt->next;
+  }
+
+  return max;
+}
+
+typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
+
+void freeStmtToIslMap(StatementToIslMapTy *Map) {
+  for (StatementToIslMapTy::iterator MI = Map->begin(), ME = Map->end();
+       MI != ME; ++MI)
+    isl_map_free(MI->second);
+
+  delete (Map);
+}
+
+/// @brief Read the new scattering from the scoplib description.
+///
+/// @S      The Scop to update
+/// @OScop  The ScopLib data structure describing the new scattering.
+/// @return A map that contains for each Statement the new scattering.
+StatementToIslMapTy *readScattering(Scop *S, scoplib_scop_p OScop) {
+  StatementToIslMapTy &NewScattering = *(new StatementToIslMapTy());
+
+  scoplib_statement_p stmt = OScop->statement;
+
+  // Check if we have dimensions for each scattering or if each row
+  // represents a scattering dimension.
+  int numScatteringDims = -1;
+  ScopStmt *pollyStmt = *S->begin();
+
+  if (stmt->schedule->NbColumns ==
+      2 + pollyStmt->getNumParams() + pollyStmt->getNumIterators()) {
+    numScatteringDims = maxScattering(stmt);
+  }
+
+  for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) {
+    if (!stmt) {
+      errs() << "Not enough statements available in ScopLib file\n";
+      freeStmtToIslMap(&NewScattering);
+      return nullptr;
+    }
+
+    NewScattering[*SI] =
+        scatteringForStmt(stmt->schedule, *SI, numScatteringDims);
+    stmt = stmt->next;
+  }
+
+  if (stmt) {
+    errs() << "Too many statements in ScopLib file\n";
+    freeStmtToIslMap(&NewScattering);
+    return nullptr;
+  }
+
+  return &NewScattering;
+}
+
+/// @brief Update the scattering in a Scop using the scoplib description of
+/// the scattering.
+bool ScopLib::updateScattering() {
+  if (!scoplib)
+    return false;
+
+  StatementToIslMapTy *NewScattering = readScattering(PollyScop, scoplib);
+
+  if (!NewScattering)
+    return false;
+
+  if (!D->isValidScattering(NewScattering)) {
+    freeStmtToIslMap(NewScattering);
+    errs() << "ScopLib file contains a scattering that changes the "
+           << "dependences. Use -disable-polly-legality to continue anyways\n";
+    return false;
+  }
+
+  for (Scop::iterator SI = PollyScop->begin(), SE = PollyScop->end(); SI != SE;
+       ++SI) {
+    ScopStmt *Stmt = *SI;
+
+    if (NewScattering->find(Stmt) != NewScattering->end())
+      Stmt->setScattering(isl_map_copy((*NewScattering)[Stmt]));
+  }
+
+  freeStmtToIslMap(NewScattering);
+  return true;
+}
+}
+
+#endif
diff --git a/rc1/lib/Exchange/ScopLibExporter.cpp b/rc1/lib/Exchange/ScopLibExporter.cpp
new file mode 100644
index 0000000..529a3f8
--- /dev/null
+++ b/rc1/lib/Exchange/ScopLibExporter.cpp
@@ -0,0 +1,93 @@
+//===-- 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/Options.h"
+#include "polly/ScopInfo.h"
+#include "polly/ScopPass.h"
+#include "polly/ScopLib.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("."), cl::cat(PollyCategory));
+
+class ScopLibExporter : public ScopPass {
+  Scop *S;
+
+  std::string getFileName(Scop *S) const;
+
+public:
+  static char ID;
+  explicit ScopLibExporter() : ScopPass(ID) {}
+
+  virtual bool runOnScop(Scop &scop);
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+}
+
+char ScopLibExporter::ID = 0;
+
+std::string ScopLibExporter::getFileName(Scop *S) const {
+  std::string FunctionName = S->getRegion().getEntry()->getParent()->getName();
+  std::string FileName = FunctionName + "___" + S->getNameStr() + ".scoplib";
+  return FileName;
+}
+
+bool ScopLibExporter::runOnScop(Scop &scop) {
+  S = &scop;
+  Region *R = &S->getRegion();
+
+  std::string FileName = ExportDir + "/" + getFileName(S);
+  FILE *F = fopen(FileName.c_str(), "w");
+
+  if (!F) {
+    errs() << "Cannot open file: " << FileName << "\n";
+    errs() << "Skipping export.\n";
+    return false;
+  }
+
+  ScopLib scoplib(S);
+  scoplib.print(F);
+  fclose(F);
+
+  std::string FunctionName = R->getEntry()->getParent()->getName();
+  errs() << "Writing Scop '" << R->getNameStr() << "' in function '"
+         << FunctionName << "' to '" << FileName << "'.\n";
+
+  return false;
+}
+
+void ScopLibExporter::getAnalysisUsage(AnalysisUsage &AU) const {
+  ScopPass::getAnalysisUsage(AU);
+}
+
+static RegisterPass<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
diff --git a/rc1/lib/Exchange/ScopLibImporter.cpp b/rc1/lib/Exchange/ScopLibImporter.cpp
new file mode 100644
index 0000000..4c8bcf7
--- /dev/null
+++ b/rc1/lib/Exchange/ScopLibImporter.cpp
@@ -0,0 +1,116 @@
+//===-- 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/Dependences.h"
+#include "polly/Options.h"
+#include "polly/ScopInfo.h"
+#include "polly/ScopLib.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("."), cl::cat(PollyCategory));
+
+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(""), cl::cat(PollyCategory));
+
+struct ScopLibImporter : public RegionPass {
+  static char ID;
+  Scop *S;
+  Dependences *D;
+  explicit ScopLibImporter() : RegionPass(ID) {}
+
+  bool updateScattering(Scop *S, scoplib_scop_p OScop);
+  std::string getFileName(Scop *S) const;
+  virtual bool runOnRegion(Region *R, RGPassManager &RGM);
+  virtual void print(raw_ostream &OS, const Module *) const;
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+}
+
+char ScopLibImporter::ID = 0;
+
+namespace {
+std::string ScopLibImporter::getFileName(Scop *S) const {
+  std::string FunctionName = S->getRegion().getEntry()->getParent()->getName();
+  std::string FileName = FunctionName + "___" + S->getNameStr() + ".scoplib";
+  return FileName;
+}
+
+void ScopLibImporter::print(raw_ostream &OS, const Module *) const {}
+
+bool ScopLibImporter::runOnRegion(Region *R, RGPassManager &RGM) {
+  S = getAnalysis<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()->getName();
+  errs() << "Reading Scop '" << R->getNameStr() << "' in function '"
+         << FunctionName << "' from '" << FileName << "'.\n";
+
+  ScopLib scoplib(S, F, D);
+  bool UpdateSuccessfull = scoplib.updateScattering();
+  fclose(F);
+
+  if (!UpdateSuccessfull) {
+    errs() << "Update failed"
+           << "\n";
+  }
+
+  return false;
+}
+
+void ScopLibImporter::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.setPreservesAll();
+  AU.addRequired<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
diff --git a/rc1/lib/JSON/LICENSE.txt b/rc1/lib/JSON/LICENSE.txt
new file mode 100644
index 0000000..1c37b11
--- /dev/null
+++ b/rc1/lib/JSON/LICENSE.txt
@@ -0,0 +1 @@
+The json-cpp library and this documentation are in Public Domain.
diff --git a/rc1/lib/JSON/include/json/autolink.h b/rc1/lib/JSON/include/json/autolink.h
new file mode 100644
index 0000000..37c9258
--- /dev/null
+++ b/rc1/lib/JSON/include/json/autolink.h
@@ -0,0 +1,19 @@
+#ifndef JSON_AUTOLINK_H_INCLUDED
+# define JSON_AUTOLINK_H_INCLUDED
+
+# include "config.h"
+
+# ifdef JSON_IN_CPPTL
+#  include <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
diff --git a/rc1/lib/JSON/include/json/config.h b/rc1/lib/JSON/include/json/config.h
new file mode 100644
index 0000000..b6dde91
--- /dev/null
+++ b/rc1/lib/JSON/include/json/config.h
@@ -0,0 +1,43 @@
+#ifndef JSON_CONFIG_H_INCLUDED
+# define JSON_CONFIG_H_INCLUDED
+
+/// If defined, indicates that json library is embedded in CppTL library.
+//# define JSON_IN_CPPTL 1
+
+/// If defined, indicates that json may leverage CppTL library
+//#  define JSON_USE_CPPTL 1
+/// If defined, indicates that cpptl vector based map should be used instead of std::map
+/// as Value container.
+//#  define JSON_USE_CPPTL_SMALLMAP 1
+/// If defined, indicates that Json specific container should be used
+/// (hash table & simple deque container with customizable allocator).
+/// THIS FEATURE IS STILL EXPERIMENTAL!
+//#  define JSON_VALUE_USE_INTERNAL_MAP 1
+/// Force usage of standard new/malloc based allocator instead of memory pool based allocator.
+/// The memory pools allocator used optimization (initializing Value and ValueInternalLink
+/// as if it was a POD) that may cause some validation tool to report errors.
+/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined.
+//#  define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1
+
+/// If defined, indicates that Json use exception to report invalid type manipulation
+/// instead of C assert macro.
+# define JSON_USE_EXCEPTION 0
+
+# ifdef JSON_IN_CPPTL
+#  include <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
diff --git a/rc1/lib/JSON/include/json/features.h b/rc1/lib/JSON/include/json/features.h
new file mode 100644
index 0000000..5a9adec
--- /dev/null
+++ b/rc1/lib/JSON/include/json/features.h
@@ -0,0 +1,42 @@
+#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
+# define CPPTL_JSON_FEATURES_H_INCLUDED
+
+# include "forwards.h"
+
+namespace Json {
+
+   /** \brief Configuration passed to reader and writer.
+    * This configuration object can be used to force the Reader or Writer
+    * to behave in a standard conforming way.
+    */
+   class JSON_API Features
+   {
+   public:
+      /** \brief A configuration that allows all features and assumes all strings are UTF-8.
+       * - C & C++ comments are allowed
+       * - Root object can be any JSON value
+       * - Assumes Value strings are encoded in UTF-8
+       */
+      static Features all();
+
+      /** \brief A configuration that is strictly compatible with the JSON specification.
+       * - Comments are forbidden.
+       * - Root object must be either an array or an object value.
+       * - Assumes Value strings are encoded in UTF-8
+       */
+      static Features strictMode();
+
+      /** \brief Initialize the configuration like JsonConfig::allFeatures;
+       */
+      Features();
+
+      /// \c true if comments are allowed. Default: \c true.
+      bool allowComments_;
+
+      /// \c true if root must be either an array or an object value. Default: \c false.
+      bool strictRoot_;
+   };
+
+} // namespace Json
+
+#endif // CPPTL_JSON_FEATURES_H_INCLUDED
diff --git a/rc1/lib/JSON/include/json/forwards.h b/rc1/lib/JSON/include/json/forwards.h
new file mode 100644
index 0000000..d0ce830
--- /dev/null
+++ b/rc1/lib/JSON/include/json/forwards.h
@@ -0,0 +1,39 @@
+#ifndef JSON_FORWARDS_H_INCLUDED
+# define JSON_FORWARDS_H_INCLUDED
+
+# include "config.h"
+
+namespace Json {
+
+   // writer.h
+   class FastWriter;
+   class StyledWriter;
+
+   // reader.h
+   class Reader;
+
+   // features.h
+   class Features;
+
+   // value.h
+   typedef int Int;
+   typedef unsigned int UInt;
+   class StaticString;
+   class Path;
+   class PathArgument;
+   class Value;
+   class ValueIteratorBase;
+   class ValueIterator;
+   class ValueConstIterator;
+#ifdef JSON_VALUE_USE_INTERNAL_MAP
+   class ValueAllocator;
+   class ValueMapAllocator;
+   class ValueInternalLink;
+   class ValueInternalArray;
+   class ValueInternalMap;
+#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP
+
+} // namespace Json
+
+
+#endif // JSON_FORWARDS_H_INCLUDED
diff --git a/rc1/lib/JSON/include/json/json.h b/rc1/lib/JSON/include/json/json.h
new file mode 100644
index 0000000..c71ed65
--- /dev/null
+++ b/rc1/lib/JSON/include/json/json.h
@@ -0,0 +1,10 @@
+#ifndef JSON_JSON_H_INCLUDED
+# define JSON_JSON_H_INCLUDED
+
+# include "autolink.h"
+# include "value.h"
+# include "reader.h"
+# include "writer.h"
+# include "features.h"
+
+#endif // JSON_JSON_H_INCLUDED
diff --git a/rc1/lib/JSON/include/json/reader.h b/rc1/lib/JSON/include/json/reader.h
new file mode 100644
index 0000000..0fea022
--- /dev/null
+++ b/rc1/lib/JSON/include/json/reader.h
@@ -0,0 +1,195 @@
+#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 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 &current, 
+                                   Location end, 
+                                   unsigned int &unicode );
+      bool decodeUnicodeEscapeSequence( Token &token, 
+                                        Location &current, 
+                                        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 &currentValue();
+      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
diff --git a/rc1/lib/JSON/include/json/value.h b/rc1/lib/JSON/include/json/value.h
new file mode 100644
index 0000000..58bfd88
--- /dev/null
+++ b/rc1/lib/JSON/include/json/value.h
@@ -0,0 +1,1069 @@
+#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 &current );
+#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 &current );
+#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 &current );
+#else
+      ValueIterator( const ValueInternalArray::IteratorState &state );
+      ValueIterator( const ValueInternalMap::IteratorState &state );
+#endif
+   public:
+
+      SelfType &operator =( const SelfType &other );
+
+      SelfType operator++( int )
+      {
+         SelfType temp( *this );
+         ++*this;
+         return temp;
+      }
+
+      SelfType operator--( int )
+      {
+         SelfType temp( *this );
+         --*this;
+         return temp;
+      }
+
+      SelfType &operator--()
+      {
+         decrement();
+         return *this;
+      }
+
+      SelfType &operator++()
+      {
+         increment();
+         return *this;
+      }
+
+      reference operator *() const
+      {
+         return deref();
+      }
+   };
+
+
+} // namespace Json
+
+
+#endif // CPPTL_JSON_H_INCLUDED
diff --git a/rc1/lib/JSON/include/json/writer.h b/rc1/lib/JSON/include/json/writer.h
new file mode 100644
index 0000000..8b86eaf
--- /dev/null
+++ b/rc1/lib/JSON/include/json/writer.h
@@ -0,0 +1,173 @@
+#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.
+    *
+    * \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
diff --git a/rc1/lib/JSON/json_batchallocator.h b/rc1/lib/JSON/json_batchallocator.h
new file mode 100644
index 0000000..87ea5ed
--- /dev/null
+++ b/rc1/lib/JSON/json_batchallocator.h
@@ -0,0 +1,125 @@
+#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
+
diff --git a/rc1/lib/JSON/json_internalarray.inl b/rc1/lib/JSON/json_internalarray.inl
new file mode 100644
index 0000000..9b985d2
--- /dev/null
+++ b/rc1/lib/JSON/json_internalarray.inl
@@ -0,0 +1,448 @@
+// included by json_value.cpp
+// everything is within Json namespace
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalArray
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueArrayAllocator::~ValueArrayAllocator()
+{
+}
+
+// //////////////////////////////////////////////////////////////////
+// class DefaultValueArrayAllocator
+// //////////////////////////////////////////////////////////////////
+#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+class DefaultValueArrayAllocator : public ValueArrayAllocator
+{
+public: // overridden from ValueArrayAllocator
+   virtual ~DefaultValueArrayAllocator()
+   {
+   }
+
+   virtual ValueInternalArray *newArray()
+   {
+      return new ValueInternalArray();
+   }
+
+   virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other )
+   {
+      return new ValueInternalArray( other );
+   }
+
+   virtual void destructArray( ValueInternalArray *array )
+   {
+      delete array;
+   }
+
+   virtual void reallocateArrayPageIndex( Value **&indexes, 
+                                          ValueInternalArray::PageIndex &indexCount,
+                                          ValueInternalArray::PageIndex minNewIndexCount )
+   {
+      ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1;
+      if ( minNewIndexCount > newIndexCount )
+         newIndexCount = minNewIndexCount;
+      void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount );
+      if ( !newIndexes )
+         throw std::bad_alloc();
+      indexCount = newIndexCount;
+      indexes = static_cast<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;
+}
diff --git a/rc1/lib/JSON/json_internalmap.inl b/rc1/lib/JSON/json_internalmap.inl
new file mode 100644
index 0000000..1977148
--- /dev/null
+++ b/rc1/lib/JSON/json_internalmap.inl
@@ -0,0 +1,607 @@
+// included by json_value.cpp
+// everything is within Json namespace
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueInternalMap
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+/** \internal MUST be safely initialized using memset( this, 0, sizeof(ValueInternalLink) );
+   * This optimization is used by the fast allocator.
+   */
+ValueInternalLink::ValueInternalLink()
+   : previous_( 0 )
+   , next_( 0 )
+{
+}
+
+ValueInternalLink::~ValueInternalLink()
+{ 
+   for ( int index =0; index < itemPerLink; ++index )
+   {
+      if ( !items_[index].isItemAvailable() )
+      {
+         if ( !items_[index].isMemberNameStatic() )
+            free( keys_[index] );
+      }
+      else
+         break;
+   }
+}
+
+
+
+ValueMapAllocator::~ValueMapAllocator()
+{
+}
+
+#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR
+class DefaultValueMapAllocator : public ValueMapAllocator
+{
+public: // overridden from ValueMapAllocator
+   virtual ValueInternalMap *newMap()
+   {
+      return new ValueInternalMap();
+   }
+
+   virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
+   {
+      return new ValueInternalMap( other );
+   }
+
+   virtual void destructMap( ValueInternalMap *map )
+   {
+      delete map;
+   }
+
+   virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
+   {
+      return new ValueInternalLink[size];
+   }
+
+   virtual void releaseMapBuckets( ValueInternalLink *links )
+   {
+      delete [] links;
+   }
+
+   virtual ValueInternalLink *allocateMapLink()
+   {
+      return new ValueInternalLink();
+   }
+
+   virtual void releaseMapLink( ValueInternalLink *link )
+   {
+      delete link;
+   }
+};
+#else
+/// @todo make this thread-safe (lock when accessign batch allocator)
+class DefaultValueMapAllocator : public ValueMapAllocator
+{
+public: // overridden from ValueMapAllocator
+   virtual ValueInternalMap *newMap()
+   {
+      ValueInternalMap *map = mapsAllocator_.allocate();
+      new (map) ValueInternalMap(); // placement new
+      return map;
+   }
+
+   virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other )
+   {
+      ValueInternalMap *map = mapsAllocator_.allocate();
+      new (map) ValueInternalMap( other ); // placement new
+      return map;
+   }
+
+   virtual void destructMap( ValueInternalMap *map )
+   {
+      if ( map )
+      {
+         map->~ValueInternalMap();
+         mapsAllocator_.release( map );
+      }
+   }
+
+   virtual ValueInternalLink *allocateMapBuckets( unsigned int size )
+   {
+      return new ValueInternalLink[size];
+   }
+
+   virtual void releaseMapBuckets( ValueInternalLink *links )
+   {
+      delete [] links;
+   }
+
+   virtual ValueInternalLink *allocateMapLink()
+   {
+      ValueInternalLink *link = linksAllocator_.allocate();
+      memset( link, 0, sizeof(ValueInternalLink) );
+      return link;
+   }
+
+   virtual void releaseMapLink( ValueInternalLink *link )
+   {
+      link->~ValueInternalLink();
+      linksAllocator_.release( link );
+   }
+private:
+   BatchAllocator<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 &current->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 = &current->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;
+}
diff --git a/rc1/lib/JSON/json_reader.cpp b/rc1/lib/JSON/json_reader.cpp
new file mode 100644
index 0000000..680c2b6
--- /dev/null
+++ b/rc1/lib/JSON/json_reader.cpp
@@ -0,0 +1,890 @@
+#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_ = &currentValue();
+   }
+
+   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 &current, 
+                                     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 &current, 
+                                     Location end, 
+                                     unsigned int &unicode )
+{
+   if ( end - current < 4 )
+      return addError( "Bad unicode escape sequence in string: four digits expected.", token, current );
+   unicode = 0;
+   for ( int index =0; index < 4; ++index )
+   {
+      Char c = *current++;
+      unicode *= 16;
+      if ( c >= '0'  &&  c <= '9' )
+         unicode += c - '0';
+      else if ( c >= 'a'  &&  c <= 'f' )
+         unicode += c - 'a' + 10;
+      else if ( c >= 'A'  &&  c <= 'F' )
+         unicode += c - 'A' + 10;
+      else
+         return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current );
+   }
+   return true;
+}
+
+
+bool 
+Reader::addError( const std::string &message, 
+                  Token &token,
+                  Location extra )
+{
+   ErrorInfo info;
+   info.token_ = token;
+   info.message_ = message;
+   info.extra_ = extra;
+   errors_.push_back( info );
+   return false;
+}
+
+
+bool 
+Reader::recoverFromError( TokenType skipUntilToken )
+{
+   int errorCount = int(errors_.size());
+   Token skip;
+   while ( true )
+   {
+      if ( !readToken(skip) )
+         errors_.resize( errorCount ); // discard errors caused by recovery
+      if ( skip.type_ == skipUntilToken  ||  skip.type_ == tokenEndOfStream )
+         break;
+   }
+   errors_.resize( errorCount );
+   return false;
+}
+
+
+bool 
+Reader::addErrorAndRecover( const std::string &message, 
+                            Token &token,
+                            TokenType skipUntilToken )
+{
+   addError( message, token );
+   return recoverFromError( skipUntilToken );
+}
+
+
+Value &
+Reader::currentValue()
+{
+   return *(nodes_.top());
+}
+
+
+Reader::Char 
+Reader::getNextChar()
+{
+   if ( current_ == end_ )
+      return 0;
+   return *current_++;
+}
+
+
+void 
+Reader::getLocationLineAndColumn( Location location,
+                                  int &line,
+                                  int &column ) const
+{
+   Location current = begin_;
+   Location lastLineStart = current;
+   line = 0;
+   while ( current < location  &&  current != end_ )
+   {
+      Char c = *current++;
+      if ( c == '\r' )
+      {
+         if ( *current == '\n' )
+            ++current;
+         lastLineStart = current;
+         ++line;
+      }
+      else if ( c == '\n' )
+      {
+         lastLineStart = current;
+         ++line;
+      }
+   }
+   // column & line start at 1
+   column = int(location - lastLineStart) + 1;
+   ++line;
+}
+
+
+std::string
+Reader::getLocationLineAndColumn( Location location ) const
+{
+   int line, column;
+   getLocationLineAndColumn( location, line, column );
+   char buffer[18+16+16+1];
+   sprintf( buffer, "Line %d, Column %d", line, column );
+   return buffer;
+}
+
+
+std::string 
+Reader::getFormatedErrorMessages() const
+{
+   std::string formattedMessage;
+   for ( Errors::const_iterator itError = errors_.begin();
+         itError != errors_.end();
+         ++itError )
+   {
+      const ErrorInfo &error = *itError;
+      formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n";
+      formattedMessage += "  " + error.message_ + "\n";
+      if ( error.extra_ )
+         formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n";
+   }
+   return formattedMessage;
+}
+
+
+std::istream& operator>>( std::istream &sin, Value &root )
+{
+    Json::Reader reader;
+    bool ok = reader.parse(sin, root, true);
+    //JSON_ASSERT( ok );
+#if JSON_USE_EXCEPTION
+    if (!ok) throw std::runtime_error(reader.getFormatedErrorMessages());
+#else
+    assert(ok && "Bad Format!");
+    (void) ok;
+#endif
+    return sin;
+}
+
+
+} // namespace Json
diff --git a/rc1/lib/JSON/json_value.cpp b/rc1/lib/JSON/json_value.cpp
new file mode 100644
index 0000000..691e418
--- /dev/null
+++ b/rc1/lib/JSON/json_value.cpp
@@ -0,0 +1,1732 @@
+#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
+
+// Disable warnings.  We do not fix these warnings, as this is a file imported
+// into Polly and we do not want to diverge from the original source.
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wcovered-switch-default"
+#endif
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Woverflow"
+#endif
+
+#define JSON_ASSERT_UNREACHABLE assert( false )
+#define JSON_ASSERT( condition ) assert( condition );  // @todo <= change this into an exception throw
+// Do not use throw when exception is disable.
+#if JSON_USE_EXCEPTION
+#	define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message );
+#else
+#	define JSON_ASSERT_MESSAGE( condition, message ) JSON_ASSERT( condition ) // @todo <= provide the message
+#endif
+
+namespace Json {
+
+const Value Value::null;
+const Int Value::minInt = Int( ~(UInt(-1)/2) );
+const Int Value::maxInt = Int( UInt(-1)/2 );
+const UInt Value::maxUInt = UInt(-1);
+
+// A "safe" implementation of strdup. Allow null pointer to be passed.
+// Also avoid warning on msvc80.
+//
+//inline char *safeStringDup( const char *czstring )
+//{
+//   if ( czstring )
+//   {
+//      const size_t length = (unsigned int)( strlen(czstring) + 1 );
+//      char *newString = static_cast<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
diff --git a/rc1/lib/JSON/json_valueiterator.inl b/rc1/lib/JSON/json_valueiterator.inl
new file mode 100644
index 0000000..736e260
--- /dev/null
+++ b/rc1/lib/JSON/json_valueiterator.inl
@@ -0,0 +1,292 @@
+// included by json_value.cpp
+// everything is within Json namespace
+
+
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// class ValueIteratorBase
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+// //////////////////////////////////////////////////////////////////
+
+ValueIteratorBase::ValueIteratorBase()
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+   : current_()
+   , isNull_( true )
+{
+}
+#else
+   : isArray_( true )
+   , isNull_( true )
+{
+   iterator_.array_ = ValueInternalArray::IteratorState();
+}
+#endif
+
+
+#ifndef JSON_VALUE_USE_INTERNAL_MAP
+ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator &current )
+   : 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 &current )
+   : 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 &current )
+   : ValueIteratorBase( current )
+{
+}
+#else
+ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state )
+   : ValueIteratorBase( state )
+{
+}
+
+ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state )
+   : ValueIteratorBase( state )
+{
+}
+#endif
+
+ValueIterator::ValueIterator( const ValueConstIterator &other )
+   : ValueIteratorBase( other )
+{
+}
+
+ValueIterator::ValueIterator( const ValueIterator &other )
+   : ValueIteratorBase( other )
+{
+}
+
+ValueIterator &
+ValueIterator::operator =( const SelfType &other )
+{
+   copy( other );
+   return *this;
+}
diff --git a/rc1/lib/JSON/json_writer.cpp b/rc1/lib/JSON/json_writer.cpp
new file mode 100644
index 0000000..bf475c3
--- /dev/null
+++ b/rc1/lib/JSON/json_writer.cpp
@@ -0,0 +1,829 @@
+#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 *&current )
+{
+   *--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") == nullptr && !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+nullptr
+   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_(nullptr)
+   , 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_ = nullptr; // Forget the stream, for safety.
+}
+
+
+void 
+StyledStreamWriter::writeValue( const Value &value )
+{
+   switch ( value.type() )
+   {
+   case nullValue:
+      pushValue( "null" );
+      break;
+   case intValue:
+      pushValue( valueToString( value.asInt() ) );
+      break;
+   case uintValue:
+      pushValue( valueToString( value.asUInt() ) );
+      break;
+   case realValue:
+      pushValue( valueToString( value.asDouble() ) );
+      break;
+   case stringValue:
+      pushValue( valueToQuotedString( value.asCString() ) );
+      break;
+   case booleanValue:
+      pushValue( valueToString( value.asBool() ) );
+      break;
+   case arrayValue:
+      writeArrayValue( value);
+      break;
+   case objectValue:
+      {
+         Value::Members members( value.getMemberNames() );
+         if ( members.empty() )
+            pushValue( "{}" );
+         else
+         {
+            writeWithIndent( "{" );
+            indent();
+            Value::Members::iterator it = members.begin();
+            while ( true )
+            {
+               const std::string &name = *it;
+               const Value &childValue = value[name];
+               writeCommentBeforeValue( childValue );
+               writeWithIndent( valueToQuotedString( name.c_str() ) );
+               *document_ << " : ";
+               writeValue( childValue );
+               if ( ++it == members.end() )
+               {
+                  writeCommentAfterValueOnSameLine( childValue );
+                  break;
+               }
+               *document_ << ",";
+               writeCommentAfterValueOnSameLine( childValue );
+            }
+            unindent();
+            writeWithIndent( "}" );
+         }
+      }
+      break;
+   }
+}
+
+
+void 
+StyledStreamWriter::writeArrayValue( const Value &value )
+{
+   unsigned size = value.size();
+   if ( size == 0 )
+      pushValue( "[]" );
+   else
+   {
+      bool isArrayMultiLine = isMultineArray( value );
+      if ( isArrayMultiLine )
+      {
+         writeWithIndent( "[" );
+         indent();
+         bool hasChildValue = !childValues_.empty();
+         unsigned index =0;
+         while ( true )
+         {
+            const Value &childValue = value[index];
+            writeCommentBeforeValue( childValue );
+            if ( hasChildValue )
+               writeWithIndent( childValues_[index] );
+            else
+            {
+	       writeIndent();
+               writeValue( childValue );
+            }
+            if ( ++index == size )
+            {
+               writeCommentAfterValueOnSameLine( childValue );
+               break;
+            }
+            *document_ << ",";
+            writeCommentAfterValueOnSameLine( childValue );
+         }
+         unindent();
+         writeWithIndent( "]" );
+      }
+      else // output on a single line
+      {
+         assert( childValues_.size() == size );
+         *document_ << "[ ";
+         for ( unsigned index =0; index < size; ++index )
+         {
+            if ( index > 0 )
+               *document_ << ", ";
+            *document_ << childValues_[index];
+         }
+         *document_ << " ]";
+      }
+   }
+}
+
+
+bool 
+StyledStreamWriter::isMultineArray( const Value &value )
+{
+   int size = value.size();
+   bool isMultiLine = size*3 >= rightMargin_ ;
+   childValues_.clear();
+   for ( int index =0; index < size  &&  !isMultiLine; ++index )
+   {
+      const Value &childValue = value[index];
+      isMultiLine = isMultiLine  ||
+                     ( (childValue.isArray()  ||  childValue.isObject())  &&  
+                        childValue.size() > 0 );
+   }
+   if ( !isMultiLine ) // check if line length > max line length
+   {
+      childValues_.reserve( size );
+      addChildValues_ = true;
+      int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]'
+      for ( int index =0; index < size  &&  !isMultiLine; ++index )
+      {
+         writeValue( value[index] );
+         lineLength += int( childValues_[index].length() );
+         isMultiLine = isMultiLine  &&  hasCommentForValue( value[index] );
+      }
+      addChildValues_ = false;
+      isMultiLine = isMultiLine  ||  lineLength >= rightMargin_;
+   }
+   return isMultiLine;
+}
+
+
+void 
+StyledStreamWriter::pushValue( const std::string &value )
+{
+   if ( addChildValues_ )
+      childValues_.push_back( value );
+   else
+      *document_ << value;
+}
+
+
+void 
+StyledStreamWriter::writeIndent()
+{
+  /*
+    Some comments in this method would have been nice. ;-)
+
+   if ( !document_.empty() )
+   {
+      char last = document_[document_.length()-1];
+      if ( last == ' ' )     // already indented
+         return;
+      if ( last != '\n' )    // Comments may add new-line
+         *document_ << '\n';
+   }
+  */
+   *document_ << '\n' << indentString_;
+}
+
+
+void 
+StyledStreamWriter::writeWithIndent( const std::string &value )
+{
+   writeIndent();
+   *document_ << value;
+}
+
+
+void 
+StyledStreamWriter::indent()
+{
+   indentString_ += indentation_;
+}
+
+
+void 
+StyledStreamWriter::unindent()
+{
+   assert( indentString_.size() >= indentation_.size() );
+   indentString_.resize( indentString_.size() - indentation_.size() );
+}
+
+
+void 
+StyledStreamWriter::writeCommentBeforeValue( const Value &root )
+{
+   if ( !root.hasComment( commentBefore ) )
+      return;
+   *document_ << normalizeEOL( root.getComment( commentBefore ) );
+   *document_ << "\n";
+}
+
+
+void 
+StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root )
+{
+   if ( root.hasComment( commentAfterOnSameLine ) )
+      *document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) );
+
+   if ( root.hasComment( commentAfter ) )
+   {
+      *document_ << "\n";
+      *document_ << normalizeEOL( root.getComment( commentAfter ) );
+      *document_ << "\n";
+   }
+}
+
+
+bool 
+StyledStreamWriter::hasCommentForValue( const Value &value )
+{
+   return value.hasComment( commentBefore )
+          ||  value.hasComment( commentAfterOnSameLine )
+          ||  value.hasComment( commentAfter );
+}
+
+
+std::string 
+StyledStreamWriter::normalizeEOL( const std::string &text )
+{
+   std::string normalized;
+   normalized.reserve( text.length() );
+   const char *begin = text.c_str();
+   const char *end = begin + text.length();
+   const char *current = begin;
+   while ( current != end )
+   {
+      char c = *current++;
+      if ( c == '\r' ) // mac or dos EOL
+      {
+         if ( *current == '\n' ) // convert dos EOL
+            ++current;
+         normalized += '\n';
+      }
+      else // handle unix EOL & other char
+         normalized += c;
+   }
+   return normalized;
+}
+
+
+std::ostream& operator<<( std::ostream &sout, const Value &root )
+{
+   Json::StyledStreamWriter writer;
+   writer.write(sout, root);
+   return sout;
+}
+
+
+} // namespace Json
diff --git a/rc1/lib/JSON/sconscript b/rc1/lib/JSON/sconscript
new file mode 100644
index 0000000..6e7c6c8
--- /dev/null
+++ b/rc1/lib/JSON/sconscript
@@ -0,0 +1,8 @@
+Import( 'env buildLibrary' )
+
+buildLibrary( env, Split( """
+    json_reader.cpp 
+    json_value.cpp 
+    json_writer.cpp
+     """ ),
+    'json' )
diff --git a/rc1/lib/Makefile b/rc1/lib/Makefile
new file mode 100644
index 0000000..20e544f
--- /dev/null
+++ b/rc1/lib/Makefile
@@ -0,0 +1,81 @@
+##===- polly/lib/Makefile -----------------------*- Makefile -*-===##
+
+#
+# Indicate where we are relative to the top of the source tree.
+#
+LEVEL :=..
+
+LIBRARYNAME=LLVMPolly
+LOADABLE_MODULE = 1
+
+# TODO: Export symbols for RTTI or EH?
+
+CPP.Flags += $(POLLY_INC)
+LD.Flags += $(POLLY_LD) $(POLLY_LIB)
+
+LIBS += $(POLLY_LD) $(POLLY_LIB)
+
+include $(LEVEL)/Makefile.config
+
+# Enable optional source files
+ifeq ($(CLOOG_FOUND), yes)
+CLOOG_FILES= CodeGen/Cloog.cpp \
+	     CodeGen/CodeGeneration.cpp
+endif
+
+ifeq ($(GPU_CODEGEN), yes)
+GPGPU_CODEGEN_FILES= CodeGen/PTXGenerator.cpp
+endif
+
+ifeq ($(PLUTO_FOUND), yes)
+POLLY_PLUTO_FILES= Transform/Pluto.cpp
+endif
+
+ifeq ($(SCOPLIB_FOUND), yes)
+POLLY_SCOPLIB_FILES= Exchange/ScopLib.cpp \
+                     Exchange/ScopLibExporter.cpp \
+                     Exchange/ScopLibImporter.cpp \
+		     Transform/Pocc.cpp
+endif
+
+ISL_CODEGEN_FILES= CodeGen/IslAst.cpp \
+                   CodeGen/IslCodeGeneration.cpp
+
+POLLY_JSON_FILES= JSON/json_reader.cpp \
+		  JSON/json_value.cpp \
+		  JSON/json_writer.cpp
+
+SOURCES= Polly.cpp \
+	 Support/GICHelper.cpp \
+	 Support/SCEVValidator.cpp \
+	 Support/RegisterPasses.cpp \
+	 Support/ScopHelper.cpp \
+	 Analysis/Dependences.cpp \
+	 Analysis/ScopDetection.cpp \
+	 Analysis/ScopDetectionDiagnostic.cpp \
+	 Analysis/ScopInfo.cpp \
+	 Analysis/ScopGraphPrinter.cpp \
+	 Analysis/ScopPass.cpp \
+	 Analysis/TempScopInfo.cpp \
+	 CodeGen/BlockGenerators.cpp \
+	 CodeGen/LoopGenerators.cpp \
+	 CodeGen/IRBuilder.cpp \
+	 CodeGen/Utils.cpp \
+	 Exchange/JSONExporter.cpp \
+	 Transform/Canonicalization.cpp \
+	 Transform/CodePreparation.cpp \
+	 Transform/DeadCodeElimination.cpp \
+	 Transform/IndependentBlocks.cpp \
+	 Transform/IndVarSimplify.cpp \
+	 Transform/ScheduleOptimizer.cpp \
+	 ${GPGPU_FILES} \
+	 ${ISL_CODEGEN_FILES} \
+         ${CLOOG_FILES} \
+	 ${POLLY_JSON_FILES} \
+	 ${POLLY_PLUTO_FILES} \
+	 ${POLLY_SCOPLIB_FILES}
+
+#
+# Include Makefile.common so we know what to do.
+#
+include $(LEVEL)/Makefile.common
diff --git a/rc1/lib/Polly.cpp b/rc1/lib/Polly.cpp
new file mode 100644
index 0000000..c879fd9
--- /dev/null
+++ b/rc1/lib/Polly.cpp
@@ -0,0 +1,30 @@
+//===---------- Polly.cpp - Initialize the Polly Module -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/RegisterPasses.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+
+namespace {
+
+/// @brief Initialize Polly passes when library is loaded.
+///
+/// We use the constructor of a statically declared object to initialize the
+/// different Polly passes right after the Polly library is loaded. This ensures
+/// that the Polly passes are available e.g. in the 'opt' tool.
+class StaticInitializer {
+public:
+  StaticInitializer() {
+    llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
+    polly::initializePollyPasses(Registry);
+  }
+};
+static StaticInitializer InitializeEverything;
+} // end of anonymous namespace.
diff --git a/rc1/lib/Support/GICHelper.cpp b/rc1/lib/Support/GICHelper.cpp
new file mode 100644
index 0000000..530ce91
--- /dev/null
+++ b/rc1/lib/Support/GICHelper.cpp
@@ -0,0 +1,126 @@
+//===- 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/aff.h"
+#include "isl/map.h"
+#include "isl/schedule.h"
+#include "isl/set.h"
+#include "isl/union_map.h"
+#include "isl/union_set.h"
+#include "isl/val.h"
+
+using namespace llvm;
+
+__isl_give isl_val *polly::isl_valFromAPInt(isl_ctx *Ctx, const APInt Int,
+                                            bool IsSigned) {
+  APInt Abs;
+  isl_val *v;
+
+  if (IsSigned)
+    Abs = Int.abs();
+  else
+    Abs = Int;
+
+  const uint64_t *Data = Abs.getRawData();
+  unsigned Words = Abs.getNumWords();
+
+  v = isl_val_int_from_chunks(Ctx, Words, sizeof(uint64_t), Data);
+
+  if (IsSigned && Int.isNegative())
+    v = isl_val_neg(v);
+
+  return v;
+}
+
+APInt polly::APIntFromVal(__isl_take isl_val *Val) {
+  uint64_t *Data;
+  int NumChunks;
+
+  NumChunks = isl_val_n_abs_num_chunks(Val, sizeof(uint64_t));
+
+  Data = (uint64_t *)malloc(NumChunks * sizeof(uint64_t));
+  isl_val_get_abs_num_chunks(Val, sizeof(uint64_t), Data);
+  APInt A(8 * sizeof(uint64_t) * NumChunks, NumChunks, Data);
+
+  if (isl_val_is_neg(Val)) {
+    A = A.zext(A.getBitWidth() + 1);
+    A = -A;
+  }
+
+  if (A.getMinSignedBits() < A.getBitWidth())
+    A = A.trunc(A.getMinSignedBits());
+
+  free(Data);
+  isl_val_free(Val);
+  return A;
+}
+
+template <typename ISLTy, typename ISL_CTX_GETTER, typename ISL_PRINTER>
+static inline std::string stringFromIslObjInternal(__isl_keep ISLTy *isl_obj,
+                                                   ISL_CTX_GETTER ctx_getter_fn,
+                                                   ISL_PRINTER printer_fn) {
+  isl_ctx *ctx = ctx_getter_fn(isl_obj);
+  isl_printer *p = isl_printer_to_str(ctx);
+  printer_fn(p, isl_obj);
+  char *char_str = isl_printer_get_str(p);
+  std::string string(char_str);
+  free(char_str);
+  isl_printer_free(p);
+  return string;
+}
+
+static inline isl_ctx *schedule_get_ctx(__isl_keep isl_schedule *schedule) {
+  return isl_union_map_get_ctx(isl_schedule_get_map(schedule));
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_map *map) {
+  return stringFromIslObjInternal(map, isl_map_get_ctx, isl_printer_print_map);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_set *set) {
+  return stringFromIslObjInternal(set, isl_set_get_ctx, isl_printer_print_set);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_union_map *umap) {
+  return stringFromIslObjInternal(umap, isl_union_map_get_ctx,
+                                  isl_printer_print_union_map);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_union_set *uset) {
+  return stringFromIslObjInternal(uset, isl_union_set_get_ctx,
+                                  isl_printer_print_union_set);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_schedule *schedule) {
+  return stringFromIslObjInternal(schedule, schedule_get_ctx,
+                                  isl_printer_print_schedule);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_multi_aff *maff) {
+  return stringFromIslObjInternal(maff, isl_multi_aff_get_ctx,
+                                  isl_printer_print_multi_aff);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_pw_multi_aff *pma) {
+  return stringFromIslObjInternal(pma, isl_pw_multi_aff_get_ctx,
+                                  isl_printer_print_pw_multi_aff);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_aff *aff) {
+  return stringFromIslObjInternal(aff, isl_aff_get_ctx, isl_printer_print_aff);
+}
+
+std::string polly::stringFromIslObj(__isl_keep isl_pw_aff *pwaff) {
+  return stringFromIslObjInternal(pwaff, isl_pw_aff_get_ctx,
+                                  isl_printer_print_pw_aff);
+}
diff --git a/rc1/lib/Support/RegisterPasses.cpp b/rc1/lib/Support/RegisterPasses.cpp
new file mode 100644
index 0000000..d55749a
--- /dev/null
+++ b/rc1/lib/Support/RegisterPasses.cpp
@@ -0,0 +1,328 @@
+//===------ RegisterPasses.cpp - Add the Polly Passes to default passes  --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file composes the individual LLVM-IR passes provided by Polly to a
+// functional polyhedral optimizer. The polyhedral optimizer is automatically
+// made available to LLVM based compilers by loading the Polly shared library
+// into such a compiler.
+//
+// The Polly optimizer is made available by executing a static constructor that
+// registers the individual Polly passes in the LLVM pass manager builder. The
+// passes are registered such that the default behaviour of the compiler is not
+// changed, but that the flag '-polly' provided at optimization level '-O3'
+// enables additional polyhedral optimizations.
+//===----------------------------------------------------------------------===//
+
+#include "polly/RegisterPasses.h"
+#include "polly/Canonicalization.h"
+#include "polly/CodeGen/BlockGenerators.h"
+#include "polly/CodeGen/Cloog.h"
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/Dependences.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
+#include "polly/ScopDetection.h"
+#include "polly/ScopInfo.h"
+#include "polly/TempScopInfo.h"
+#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/PassManager.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Vectorize.h"
+
+using namespace llvm;
+using namespace polly;
+
+cl::OptionCategory PollyCategory("Polly Options",
+                                 "Configure the polly loop optimizer");
+
+static cl::opt<bool>
+    PollyEnabled("polly", cl::desc("Enable the polly optimizer (only at -O3)"),
+                 cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+enum OptimizerChoice {
+  OPTIMIZER_NONE,
+#ifdef PLUTO_FOUND
+  OPTIMIZER_PLUTO,
+#endif
+#ifdef SCOPLIB_FOUND
+  OPTIMIZER_POCC,
+#endif
+  OPTIMIZER_ISL
+};
+
+static cl::opt<OptimizerChoice> Optimizer(
+    "polly-optimizer", cl::desc("Select the scheduling optimizer"),
+    cl::values(
+        clEnumValN(OPTIMIZER_NONE, "none", "No optimizer"),
+#ifdef PLUTO_FOUND
+        clEnumValN(OPTIMIZER_PLUTO, "pluto", "The Pluto scheduling optimizer"),
+#endif
+#ifdef SCOPLIB_FOUND
+        clEnumValN(OPTIMIZER_POCC, "pocc", "The PoCC scheduling optimizer"),
+#endif
+        clEnumValN(OPTIMIZER_ISL, "isl", "The isl scheduling optimizer"),
+        clEnumValEnd),
+    cl::Hidden, cl::init(OPTIMIZER_ISL), cl::ZeroOrMore,
+    cl::cat(PollyCategory));
+
+enum CodeGenChoice {
+#ifdef CLOOG_FOUND
+  CODEGEN_CLOOG,
+#endif
+  CODEGEN_ISL,
+  CODEGEN_NONE
+};
+
+#ifdef CLOOG_FOUND
+enum CodeGenChoice DefaultCodeGen = CODEGEN_CLOOG;
+#else
+enum CodeGenChoice DefaultCodeGen = CODEGEN_ISL;
+#endif
+
+static cl::opt<CodeGenChoice> CodeGenerator(
+    "polly-code-generator", cl::desc("Select the code generator"),
+    cl::values(
+#ifdef CLOOG_FOUND
+        clEnumValN(CODEGEN_CLOOG, "cloog", "CLooG"),
+#endif
+        clEnumValN(CODEGEN_ISL, "isl", "isl code generator"),
+        clEnumValN(CODEGEN_NONE, "none", "no code generation"), clEnumValEnd),
+    cl::Hidden, cl::init(DefaultCodeGen), cl::ZeroOrMore,
+    cl::cat(PollyCategory));
+
+VectorizerChoice polly::PollyVectorizerChoice;
+static cl::opt<polly::VectorizerChoice, true> Vectorizer(
+    "polly-vectorizer", cl::desc("Select the vectorization strategy"),
+    cl::values(clEnumValN(polly::VECTORIZER_NONE, "none", "No Vectorization"),
+               clEnumValN(polly::VECTORIZER_POLLY, "polly",
+                          "Polly internal vectorizer"),
+               clEnumValN(polly::VECTORIZER_UNROLL_ONLY, "unroll-only",
+                          "Only grouped unroll the vectorize candidate loops"),
+               clEnumValN(polly::VECTORIZER_BB, "bb",
+                          "The Basic Block vectorizer driven by Polly"),
+               clEnumValEnd),
+    cl::location(PollyVectorizerChoice), cl::init(polly::VECTORIZER_NONE),
+    cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> ImportJScop(
+    "polly-import",
+    cl::desc("Export the polyhedral description of the detected Scops"),
+    cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> ExportJScop(
+    "polly-export",
+    cl::desc("Export the polyhedral description of the detected Scops"),
+    cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> DeadCodeElim("polly-run-dce",
+                                  cl::desc("Run the dead code elimination"),
+                                  cl::Hidden, cl::init(true), cl::ZeroOrMore,
+                                  cl::cat(PollyCategory));
+
+static cl::opt<bool> PollyViewer(
+    "polly-show",
+    cl::desc("Highlight the code regions that will be optimized in a "
+             "(CFG BBs and LLVM-IR instructions)"),
+    cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> PollyOnlyViewer(
+    "polly-show-only",
+    cl::desc("Highlight the code regions that will be optimized in "
+             "a (CFG only BBs)"),
+    cl::init(false), cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    PollyPrinter("polly-dot", cl::desc("Enable the Polly DOT printer in -O3"),
+                 cl::Hidden, cl::value_desc("Run the Polly DOT printer at -O3"),
+                 cl::init(false), cl::cat(PollyCategory));
+
+static cl::opt<bool> PollyOnlyPrinter(
+    "polly-dot-only",
+    cl::desc("Enable the Polly DOT printer in -O3 (no BB content)"), cl::Hidden,
+    cl::value_desc("Run the Polly DOT printer at -O3 (no BB content"),
+    cl::init(false), cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    CFGPrinter("polly-view-cfg",
+               cl::desc("Show the Polly CFG right after code generation"),
+               cl::Hidden, cl::init(false), cl::cat(PollyCategory));
+
+namespace polly {
+void initializePollyPasses(PassRegistry &Registry) {
+#ifdef CLOOG_FOUND
+  initializeCloogInfoPass(Registry);
+  initializeCodeGenerationPass(Registry);
+#endif
+  initializeIslCodeGenerationPass(Registry);
+  initializeCodePreparationPass(Registry);
+  initializeDeadCodeElimPass(Registry);
+  initializeDependencesPass(Registry);
+  initializeIndependentBlocksPass(Registry);
+  initializeJSONExporterPass(Registry);
+  initializeJSONImporterPass(Registry);
+  initializeIslAstInfoPass(Registry);
+  initializeIslScheduleOptimizerPass(Registry);
+#ifdef SCOPLIB_FOUND
+  initializePoccPass(Registry);
+#endif
+  initializePollyIndVarSimplifyPass(Registry);
+  initializePollyCanonicalizePass(Registry);
+  initializeScopDetectionPass(Registry);
+  initializeScopInfoPass(Registry);
+  initializeTempScopInfoPass(Registry);
+}
+
+/// @brief Register Polly passes such that they form a polyhedral optimizer.
+///
+/// The individual Polly passes are registered in the pass manager such that
+/// they form a full polyhedral optimizer. The flow of the optimizer starts with
+/// a set of preparing transformations that canonicalize the LLVM-IR such that
+/// the LLVM-IR is easier for us to understand and to optimizes. On the
+/// canonicalized LLVM-IR we first run the ScopDetection pass, which detects
+/// static control flow regions. Those regions are then translated by the
+/// ScopInfo pass into a polyhedral representation. As a next step, a scheduling
+/// optimizer is run on the polyhedral representation and finally the optimized
+/// polyhedral representation is code generated back to LLVM-IR.
+///
+/// Besides this core functionality, we optionally schedule passes that provide
+/// a graphical view of the scops (Polly[Only]Viewer, Polly[Only]Printer), that
+/// allow the export/import of the polyhedral representation
+/// (JSCON[Exporter|Importer]) or that show the cfg after code generation.
+///
+/// For certain parts of the Polly optimizer, several alternatives are provided:
+///
+/// As scheduling optimizer we support PoCC (http://pocc.sourceforge.net), PLUTO
+/// (http://pluto-compiler.sourceforge.net) as well as the isl scheduling
+/// optimizer (http://freecode.com/projects/isl). The isl optimizer is the
+/// default optimizer.
+/// It is also possible to run Polly with no optimizer. This mode is mainly
+/// provided to analyze the run and compile time changes caused by the
+/// scheduling optimizer.
+///
+/// Polly supports both CLooG (http://www.cloog.org) as well as the isl internal
+/// code generator. For the moment, the CLooG code generator is enabled by
+/// default.
+static void registerPollyPasses(llvm::PassManagerBase &PM) {
+  registerCanonicalicationPasses(PM, SCEVCodegen);
+
+  PM.add(polly::createScopInfoPass());
+
+  if (PollyViewer)
+    PM.add(polly::createDOTViewerPass());
+  if (PollyOnlyViewer)
+    PM.add(polly::createDOTOnlyViewerPass());
+  if (PollyPrinter)
+    PM.add(polly::createDOTPrinterPass());
+  if (PollyOnlyPrinter)
+    PM.add(polly::createDOTOnlyPrinterPass());
+
+  if (ImportJScop)
+    PM.add(polly::createJSONImporterPass());
+
+  if (DeadCodeElim)
+    PM.add(polly::createDeadCodeElimPass());
+
+  switch (Optimizer) {
+  case OPTIMIZER_NONE:
+    break; /* Do nothing */
+
+#ifdef SCOPLIB_FOUND
+  case OPTIMIZER_POCC:
+    PM.add(polly::createPoccPass());
+    break;
+#endif
+
+#ifdef PLUTO_FOUND
+  case OPTIMIZER_PLUTO:
+    PM.add(polly::createPlutoOptimizerPass());
+    break;
+#endif
+
+  case OPTIMIZER_ISL:
+    PM.add(polly::createIslScheduleOptimizerPass());
+    break;
+  }
+
+  if (ExportJScop)
+    PM.add(polly::createJSONExporterPass());
+
+  switch (CodeGenerator) {
+#ifdef CLOOG_FOUND
+  case CODEGEN_CLOOG:
+    PM.add(polly::createCodeGenerationPass());
+    if (PollyVectorizerChoice == VECTORIZER_BB) {
+      VectorizeConfig C;
+      C.FastDep = true;
+      PM.add(createBBVectorizePass(C));
+    }
+    break;
+#endif
+  case CODEGEN_ISL:
+    PM.add(polly::createIslCodeGenerationPass());
+    break;
+  case CODEGEN_NONE:
+    break;
+  }
+
+  if (CFGPrinter)
+    PM.add(llvm::createCFGPrinterPass());
+}
+
+static bool shouldEnablePolly() {
+  if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer)
+    PollyTrackFailures = true;
+
+  if (PollyOnlyPrinter || PollyPrinter || PollyOnlyViewer || PollyViewer ||
+      ExportJScop || ImportJScop)
+    PollyEnabled = true;
+
+  return PollyEnabled;
+}
+
+static void
+registerPollyEarlyAsPossiblePasses(const llvm::PassManagerBuilder &Builder,
+                                   llvm::PassManagerBase &PM) {
+  if (!polly::shouldEnablePolly())
+    return;
+
+  polly::registerPollyPasses(PM);
+}
+
+/// @brief Register Polly to be available as an optimizer
+///
+/// We currently register Polly such that it runs as early as possible. This has
+/// several implications:
+///
+///   1) We need to schedule more canonicalization passes
+///
+///   As nothing is run before Polly, it is necessary to run a set of preparing
+///   transformations before Polly to canonicalize the LLVM-IR and to allow
+///   Polly to detect and understand the code.
+///
+///   2) LICM and LoopIdiom pass have not yet been run
+///
+///   Loop invariant code motion as well as the loop idiom recognition pass make
+///   it more difficult for Polly to transform code. LICM may introduce
+///   additional data dependences that are hard to eliminate and the loop idiom
+///   recognition pass may introduce calls to memset that we currently do not
+///   understand. By running Polly early enough (meaning before these passes) we
+///   avoid difficulties that may be introduced by these passes.
+///
+///   3) We get the full -O3 optimization sequence after Polly
+///
+///   The LLVM-IR that is generated by Polly has been optimized on a high level,
+///   but it may be rather inefficient on the lower/scalar level. By scheduling
+///   Polly before all other passes, we have the full sequence of -O3
+///   optimizations behind us, such that inefficiencies on the low level can
+///   be optimized away.
+static llvm::RegisterStandardPasses
+    RegisterPollyOptimizer(llvm::PassManagerBuilder::EP_EarlyAsPossible,
+                           registerPollyEarlyAsPossiblePasses);
+}
diff --git a/rc1/lib/Support/SCEVValidator.cpp b/rc1/lib/Support/SCEVValidator.cpp
new file mode 100644
index 0000000..3a8895f
--- /dev/null
+++ b/rc1/lib/Support/SCEVValidator.cpp
@@ -0,0 +1,496 @@
+
+#include "polly/Support/SCEVValidator.h"
+#include "polly/ScopInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Support/Debug.h"
+
+#include <vector>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "polly-scev-validator"
+
+namespace SCEVType {
+/// @brief The type of a SCEV
+///
+/// To check for the validity of a SCEV we assign to each SCEV a type. The
+/// possible types are INT, PARAM, IV and INVALID. The order of the types is
+/// important. The subexpressions of SCEV with a type X can only have a type
+/// that is smaller or equal than X.
+enum TYPE {
+  // An integer value.
+  INT,
+
+  // An expression that is constant during the execution of the Scop,
+  // but that may depend on parameters unknown at compile time.
+  PARAM,
+
+  // An expression that may change during the execution of the SCoP.
+  IV,
+
+  // An invalid expression.
+  INVALID
+};
+}
+
+/// @brief The result the validator returns for a SCEV expression.
+class ValidatorResult {
+  /// @brief The type of the expression
+  SCEVType::TYPE Type;
+
+  /// @brief The set of Parameters in the expression.
+  std::vector<const SCEV *> Parameters;
+
+public:
+  /// @brief The copy constructor
+  ValidatorResult(const ValidatorResult &Source) {
+    Type = Source.Type;
+    Parameters = Source.Parameters;
+  }
+
+  /// @brief Construct a result with a certain type and no parameters.
+  ValidatorResult(SCEVType::TYPE Type) : Type(Type) {
+    assert(Type != SCEVType::PARAM && "Did you forget to pass the parameter");
+  }
+
+  /// @brief Construct a result with a certain type and a single parameter.
+  ValidatorResult(SCEVType::TYPE Type, const SCEV *Expr) : Type(Type) {
+    Parameters.push_back(Expr);
+  }
+
+  /// @brief Get the type of the ValidatorResult.
+  SCEVType::TYPE getType() { return Type; }
+
+  /// @brief Is the analyzed SCEV constant during the execution of the SCoP.
+  bool isConstant() { return Type == SCEVType::INT || Type == SCEVType::PARAM; }
+
+  /// @brief Is the analyzed SCEV valid.
+  bool isValid() { return Type != SCEVType::INVALID; }
+
+  /// @brief Is the analyzed SCEV of Type IV.
+  bool isIV() { return Type == SCEVType::IV; }
+
+  /// @brief Is the analyzed SCEV of Type INT.
+  bool isINT() { return Type == SCEVType::INT; }
+
+  /// @brief Is the analyzed SCEV of Type PARAM.
+  bool isPARAM() { return Type == SCEVType::PARAM; }
+
+  /// @brief Get the parameters of this validator result.
+  std::vector<const SCEV *> getParameters() { return Parameters; }
+
+  /// @brief Add the parameters of Source to this result.
+  void addParamsFrom(class ValidatorResult &Source) {
+    Parameters.insert(Parameters.end(), Source.Parameters.begin(),
+                      Source.Parameters.end());
+  }
+
+  /// @brief Merge a result.
+  ///
+  /// This means to merge the parameters and to set the Type to the most
+  /// specific Type that matches both.
+  void merge(class ValidatorResult &ToMerge) {
+    Type = std::max(Type, ToMerge.Type);
+    addParamsFrom(ToMerge);
+  }
+
+  void print(raw_ostream &OS) {
+    switch (Type) {
+    case SCEVType::INT:
+      OS << "SCEVType::INT";
+      break;
+    case SCEVType::PARAM:
+      OS << "SCEVType::PARAM";
+      break;
+    case SCEVType::IV:
+      OS << "SCEVType::IV";
+      break;
+    case SCEVType::INVALID:
+      OS << "SCEVType::INVALID";
+      break;
+    }
+  }
+};
+
+raw_ostream &operator<<(raw_ostream &OS, class ValidatorResult &VR) {
+  VR.print(OS);
+  return OS;
+}
+
+/// Check if a SCEV is valid in a SCoP.
+struct SCEVValidator
+    : public SCEVVisitor<SCEVValidator, class ValidatorResult> {
+private:
+  const Region *R;
+  ScalarEvolution &SE;
+  const Value *BaseAddress;
+
+public:
+  SCEVValidator(const Region *R, ScalarEvolution &SE, const Value *BaseAddress)
+      : R(R), SE(SE), BaseAddress(BaseAddress) {}
+
+  class ValidatorResult visitConstant(const SCEVConstant *Constant) {
+    return ValidatorResult(SCEVType::INT);
+  }
+
+  class ValidatorResult visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+    ValidatorResult Op = visit(Expr->getOperand());
+
+    switch (Op.getType()) {
+    case SCEVType::INT:
+    case SCEVType::PARAM:
+      // We currently do not represent a truncate expression as an affine
+      // expression. If it is constant during Scop execution, we treat it as a
+      // parameter.
+      return ValidatorResult(SCEVType::PARAM, Expr);
+    case SCEVType::IV:
+      DEBUG(dbgs() << "INVALID: Truncation of SCEVType::IV expression");
+      return ValidatorResult(SCEVType::INVALID);
+    case SCEVType::INVALID:
+      return Op;
+    }
+
+    llvm_unreachable("Unknown SCEVType");
+  }
+
+  class ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+    ValidatorResult Op = visit(Expr->getOperand());
+
+    switch (Op.getType()) {
+    case SCEVType::INT:
+    case SCEVType::PARAM:
+      // We currently do not represent a truncate expression as an affine
+      // expression. If it is constant during Scop execution, we treat it as a
+      // parameter.
+      return ValidatorResult(SCEVType::PARAM, Expr);
+    case SCEVType::IV:
+      DEBUG(dbgs() << "INVALID: ZeroExtend of SCEVType::IV expression");
+      return ValidatorResult(SCEVType::INVALID);
+    case SCEVType::INVALID:
+      return Op;
+    }
+
+    llvm_unreachable("Unknown SCEVType");
+  }
+
+  class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+    // We currently allow only signed SCEV expressions. In the case of a
+    // signed value, a sign extend is a noop.
+    //
+    // TODO: Reconsider this when we add support for unsigned values.
+    return visit(Expr->getOperand());
+  }
+
+  class ValidatorResult visitAddExpr(const SCEVAddExpr *Expr) {
+    ValidatorResult Return(SCEVType::INT);
+
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
+      ValidatorResult Op = visit(Expr->getOperand(i));
+      Return.merge(Op);
+
+      // Early exit.
+      if (!Return.isValid())
+        break;
+    }
+
+    // TODO: Check for NSW and NUW.
+    return Return;
+  }
+
+  class ValidatorResult visitMulExpr(const SCEVMulExpr *Expr) {
+    ValidatorResult Return(SCEVType::INT);
+
+    bool HasMultipleParams = false;
+
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
+      ValidatorResult Op = visit(Expr->getOperand(i));
+
+      if (Op.isINT())
+        continue;
+
+      if (Op.isPARAM() && Return.isPARAM()) {
+        HasMultipleParams = true;
+        continue;
+      }
+
+      if ((Op.isIV() || Op.isPARAM()) && !Return.isINT()) {
+        DEBUG(dbgs() << "INVALID: More than one non-int operand in MulExpr\n"
+                     << "\tExpr: " << *Expr << "\n"
+                     << "\tPrevious expression type: " << Return << "\n"
+                     << "\tNext operand (" << Op
+                     << "): " << *Expr->getOperand(i) << "\n");
+
+        return ValidatorResult(SCEVType::INVALID);
+      }
+
+      Return.merge(Op);
+    }
+
+    if (HasMultipleParams)
+      return ValidatorResult(SCEVType::PARAM, Expr);
+
+    // TODO: Check for NSW and NUW.
+    return Return;
+  }
+
+  class ValidatorResult visitUDivExpr(const SCEVUDivExpr *Expr) {
+    ValidatorResult LHS = visit(Expr->getLHS());
+    ValidatorResult RHS = visit(Expr->getRHS());
+
+    // We currently do not represent an unsigned division as an affine
+    // expression. If the division is constant during Scop execution we treat it
+    // as a parameter, otherwise we bail out.
+    if (LHS.isConstant() && RHS.isConstant())
+      return ValidatorResult(SCEVType::PARAM, Expr);
+
+    DEBUG(dbgs() << "INVALID: unsigned division of non-constant expressions");
+    return ValidatorResult(SCEVType::INVALID);
+  }
+
+  class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+    if (!Expr->isAffine()) {
+      DEBUG(dbgs() << "INVALID: AddRec is not affine");
+      return ValidatorResult(SCEVType::INVALID);
+    }
+
+    ValidatorResult Start = visit(Expr->getStart());
+    ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE));
+
+    if (!Start.isValid())
+      return Start;
+
+    if (!Recurrence.isValid())
+      return Recurrence;
+
+    if (R->contains(Expr->getLoop())) {
+      if (Recurrence.isINT()) {
+        ValidatorResult Result(SCEVType::IV);
+        Result.addParamsFrom(Start);
+        return Result;
+      }
+
+      DEBUG(dbgs() << "INVALID: AddRec within scop has non-int"
+                      "recurrence part");
+      return ValidatorResult(SCEVType::INVALID);
+    }
+
+    assert(Start.isConstant() && Recurrence.isConstant() &&
+           "Expected 'Start' and 'Recurrence' to be constant");
+
+    // Directly generate ValidatorResult for Expr if 'start' is zero.
+    if (Expr->getStart()->isZero())
+      return ValidatorResult(SCEVType::PARAM, Expr);
+
+    // Translate AddRecExpr from '{start, +, inc}' into 'start + {0, +, inc}'
+    // if 'start' is not zero.
+    const SCEV *ZeroStartExpr = SE.getAddRecExpr(
+        SE.getConstant(Expr->getStart()->getType(), 0),
+        Expr->getStepRecurrence(SE), Expr->getLoop(), SCEV::FlagAnyWrap);
+
+    ValidatorResult ZeroStartResult =
+        ValidatorResult(SCEVType::PARAM, ZeroStartExpr);
+    ZeroStartResult.addParamsFrom(Start);
+
+    return ZeroStartResult;
+  }
+
+  class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+    ValidatorResult Return(SCEVType::INT);
+
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
+      ValidatorResult Op = visit(Expr->getOperand(i));
+
+      if (!Op.isValid())
+        return Op;
+
+      Return.merge(Op);
+    }
+
+    return Return;
+  }
+
+  class ValidatorResult visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+    // We do not support unsigned operations. If 'Expr' is constant during Scop
+    // execution we treat this as a parameter, otherwise we bail out.
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
+      ValidatorResult Op = visit(Expr->getOperand(i));
+
+      if (!Op.isConstant()) {
+        DEBUG(dbgs() << "INVALID: UMaxExpr has a non-constant operand");
+        return ValidatorResult(SCEVType::INVALID);
+      }
+    }
+
+    return ValidatorResult(SCEVType::PARAM, Expr);
+  }
+
+  ValidatorResult visitUnknown(const SCEVUnknown *Expr) {
+    Value *V = Expr->getValue();
+
+    // We currently only support integer types. It may be useful to support
+    // pointer types, e.g. to support code like:
+    //
+    //   if (A)
+    //     A[i] = 1;
+    //
+    // See test/CodeGen/20120316-InvalidCast.ll
+    if (!Expr->getType()->isIntegerTy()) {
+      DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer type");
+      return ValidatorResult(SCEVType::INVALID);
+    }
+
+    if (isa<UndefValue>(V)) {
+      DEBUG(dbgs() << "INVALID: UnknownExpr references an undef value");
+      return ValidatorResult(SCEVType::INVALID);
+    }
+
+    if (Instruction *I = dyn_cast<Instruction>(Expr->getValue()))
+      if (R->contains(I)) {
+        DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction "
+                        "within the region\n");
+        return ValidatorResult(SCEVType::INVALID);
+      }
+
+    if (BaseAddress == V) {
+      DEBUG(dbgs() << "INVALID: UnknownExpr references BaseAddress\n");
+      return ValidatorResult(SCEVType::INVALID);
+    }
+
+    return ValidatorResult(SCEVType::PARAM, Expr);
+  }
+};
+
+/// @brief Check whether a SCEV refers to an SSA name defined inside a region.
+///
+struct SCEVInRegionDependences
+    : public SCEVVisitor<SCEVInRegionDependences, bool> {
+public:
+  /// Returns true when the SCEV has SSA names defined in region R.
+  static bool hasDependences(const SCEV *S, const Region *R) {
+    SCEVInRegionDependences Ignore(R);
+    return Ignore.visit(S);
+  }
+
+  SCEVInRegionDependences(const Region *R) : R(R) {}
+
+  bool visit(const SCEV *Expr) {
+    return SCEVVisitor<SCEVInRegionDependences, bool>::visit(Expr);
+  }
+
+  bool visitConstant(const SCEVConstant *Constant) { return false; }
+
+  bool visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+    return visit(Expr->getOperand());
+  }
+
+  bool visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+    return visit(Expr->getOperand());
+  }
+
+  bool visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+    return visit(Expr->getOperand());
+  }
+
+  bool visitAddExpr(const SCEVAddExpr *Expr) {
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitMulExpr(const SCEVMulExpr *Expr) {
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitUDivExpr(const SCEVUDivExpr *Expr) {
+    if (visit(Expr->getLHS()))
+      return true;
+
+    if (visit(Expr->getRHS()))
+      return true;
+
+    return false;
+  }
+
+  bool visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+    if (visit(Expr->getStart()))
+      return true;
+
+    for (size_t i = 0; i < Expr->getNumOperands(); ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+    for (size_t i = 0; i < Expr->getNumOperands(); ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+    for (size_t i = 0; i < Expr->getNumOperands(); ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitUnknown(const SCEVUnknown *Expr) {
+    Instruction *Inst = dyn_cast<Instruction>(Expr->getValue());
+
+    // Return true when Inst is defined inside the region R.
+    if (Inst && R->contains(Inst))
+      return true;
+
+    return false;
+  }
+
+private:
+  const Region *R;
+};
+
+namespace polly {
+bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R) {
+  return SCEVInRegionDependences::hasDependences(Expr, R);
+}
+
+bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
+                  const Value *BaseAddress) {
+  if (isa<SCEVCouldNotCompute>(Expr))
+    return false;
+
+  SCEVValidator Validator(R, SE, BaseAddress);
+  DEBUG(dbgs() << "\n"; dbgs() << "Expr: " << *Expr << "\n";
+        dbgs() << "Region: " << R->getNameStr() << "\n"; dbgs() << " -> ");
+
+  ValidatorResult Result = Validator.visit(Expr);
+
+  DEBUG(if (Result.isValid()) dbgs() << "VALID\n"; dbgs() << "\n";);
+
+  return Result.isValid();
+}
+
+std::vector<const SCEV *> getParamsInAffineExpr(const Region *R,
+                                                const SCEV *Expr,
+                                                ScalarEvolution &SE,
+                                                const Value *BaseAddress) {
+  if (isa<SCEVCouldNotCompute>(Expr))
+    return std::vector<const SCEV *>();
+
+  SCEVValidator Validator(R, SE, BaseAddress);
+  ValidatorResult Result = Validator.visit(Expr);
+
+  return Result.getParameters();
+}
+}
diff --git a/rc1/lib/Support/ScopHelper.cpp b/rc1/lib/Support/ScopHelper.cpp
new file mode 100644
index 0000000..15adf2d
--- /dev/null
+++ b/rc1/lib/Support/ScopHelper.cpp
@@ -0,0 +1,126 @@
+//===- 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 "polly/ScopInfo.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "polly-scop-helper"
+
+// 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;
+}
+
+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;
+}
+
+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, ".region", P);
+}
+
+void polly::simplifyRegion(Scop *S, Pass *P) {
+  Region *R = &S->getRegion();
+
+  // Create single entry edge if the region has multiple entry edges.
+  if (!R->getEnteringBlock()) {
+    BasicBlock *OldEntry = R->getEntry();
+    BasicBlock *NewEntry = SplitBlock(OldEntry, OldEntry->begin(), P);
+
+    for (ScopStmt *Stmt : *S)
+      if (Stmt->getBasicBlock() == OldEntry) {
+        Stmt->setBasicBlock(NewEntry);
+        break;
+      }
+
+    R->replaceEntryRecursive(NewEntry);
+  }
+
+  // Create single exit edge if the region has multiple exit edges.
+  if (!R->getExitingBlock()) {
+    BasicBlock *NewExit = createSingleExitEdge(R, P);
+
+    for (auto &&SubRegion : *R)
+      SubRegion->replaceExitRecursive(NewExit);
+  }
+}
+
+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 (RegionInfoPass *RIP = P->getAnalysisIfAvailable<RegionInfoPass>())
+    RIP->getRegionInfo().splitBlock(NewEntry, EntryBlock);
+}
diff --git a/rc1/lib/Transform/Canonicalization.cpp b/rc1/lib/Transform/Canonicalization.cpp
new file mode 100644
index 0000000..d6ce12f
--- /dev/null
+++ b/rc1/lib/Transform/Canonicalization.cpp
@@ -0,0 +1,86 @@
+//===---- Canonicalization.cpp - Run canonicalization passes ======-------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Run the set of default canonicalization passes.
+//
+// This pass is mainly used for debugging.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+#include "polly/Canonicalization.h"
+#include "llvm/Transforms/Scalar.h"
+
+using namespace llvm;
+using namespace polly;
+
+void polly::registerCanonicalicationPasses(llvm::PassManagerBase &PM,
+                                           bool SCEVCodegen) {
+  PM.add(llvm::createPromoteMemoryToRegisterPass());
+  PM.add(llvm::createPromoteMemoryToRegisterPass());
+  PM.add(llvm::createInstructionCombiningPass());
+  PM.add(llvm::createCFGSimplificationPass());
+  PM.add(llvm::createTailCallEliminationPass());
+  PM.add(llvm::createCFGSimplificationPass());
+  PM.add(llvm::createReassociatePass());
+  PM.add(llvm::createLoopRotatePass());
+  PM.add(llvm::createInstructionCombiningPass());
+
+  if (!SCEVCodegen)
+    PM.add(polly::createIndVarSimplifyPass());
+
+  PM.add(polly::createCodePreparationPass());
+}
+
+namespace {
+class PollyCanonicalize : public ModulePass {
+  PollyCanonicalize(const PollyCanonicalize &) LLVM_DELETED_FUNCTION;
+  const PollyCanonicalize &
+  operator=(const PollyCanonicalize &) LLVM_DELETED_FUNCTION;
+
+public:
+  static char ID;
+
+  explicit PollyCanonicalize() : ModulePass(ID) {}
+  ~PollyCanonicalize();
+
+  /// @name FunctionPass interface.
+  //@{
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void releaseMemory();
+  virtual bool runOnModule(Module &M);
+  virtual void print(raw_ostream &OS, const Module *) const;
+  //@}
+};
+}
+
+PollyCanonicalize::~PollyCanonicalize() {}
+
+void PollyCanonicalize::getAnalysisUsage(AnalysisUsage &AU) const {}
+
+void PollyCanonicalize::releaseMemory() {}
+
+bool PollyCanonicalize::runOnModule(Module &M) {
+  PassManager PM;
+  registerCanonicalicationPasses(PM);
+  PM.run(M);
+
+  return true;
+}
+
+void PollyCanonicalize::print(raw_ostream &OS, const Module *) const {}
+
+char PollyCanonicalize::ID = 0;
+
+Pass *polly::createPollyCanonicalizePass() { return new PollyCanonicalize(); }
+
+INITIALIZE_PASS_BEGIN(PollyCanonicalize, "polly-canonicalize",
+                      "Polly - Run canonicalization passes", false, false)
+INITIALIZE_PASS_END(PollyCanonicalize, "polly-canonicalize",
+                    "Polly - Run canonicalization passes", false, false)
diff --git a/rc1/lib/Transform/CodePreparation.cpp b/rc1/lib/Transform/CodePreparation.cpp
new file mode 100644
index 0000000..40d2723
--- /dev/null
+++ b/rc1/lib/Transform/CodePreparation.cpp
@@ -0,0 +1,248 @@
+//===---- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// The Polly code preparation pass is executed before SCoP detection. Its only
+// use is to translate all PHI nodes that can not be expressed by the code
+// generator into explicit memory dependences. Depending of the code generation
+// strategy different PHI nodes are translated:
+//
+// - indvars based code generation:
+//
+// The indvars based code generation requires explicit canonical induction
+// variables. Such variables are generated before scop detection and
+// also before the code preparation pass. All PHI nodes that are not canonical
+// induction variables are not supported by the indvars based code generation
+// and are consequently translated into explict memory accesses.
+//
+// - scev based code generation:
+//
+// The scev based code generation can code generate all PHI nodes that do not
+// reference parameters within the scop. As the code preparation pass is run
+// before scop detection, we can not check this condition, because without
+// a detected scop, we do not know SCEVUnknowns that appear in the SCEV of
+// a PHI node may later be within or outside of the SCoP. Hence, we follow a
+// heuristic and translate all PHI nodes that are either directly SCEVUnknown
+// or SCEVCouldNotCompute. This will hopefully get most of the PHI nodes that
+// are introduced due to conditional control flow, but not the ones that are
+// referencing loop counters.
+//
+// XXX: In the future, we should remove the need for this pass entirely and
+// instead add support for scalar dependences to ScopInfo and code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+#include "polly/CodeGen/BlockGenerators.h"
+#include "polly/Support/ScopHelper.h"
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Transforms/Utils/Local.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+
+// Helper function which (for a given PHI node):
+//
+// 1) Remembers all incoming values and the associated basic blocks
+// 2) Demotes the phi node to the stack
+// 3) Remembers the correlation between the PHI node and the new alloca
+//
+// When we combine the information from 1) and 3) we know the values stored
+// in this alloca at the end of the predecessor basic blocks of the PHI.
+static void DemotePHI(
+    PHINode *PN, DenseMap<PHINode *, AllocaInst *> &PNallocMap,
+    DenseMap<std::pair<Value *, BasicBlock *>, PHINode *> &ValueLocToPhiMap) {
+
+  for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+    auto *InVal = PN->getIncomingValue(i);
+    auto *InBB = PN->getIncomingBlock(i);
+    ValueLocToPhiMap[std::make_pair(InVal, InBB)] = PN;
+  }
+
+  PNallocMap[PN] = DemotePHIToStack(PN);
+}
+
+/// @brief Prepare the IR for the scop detection.
+///
+class CodePreparation : public FunctionPass {
+  CodePreparation(const CodePreparation &) LLVM_DELETED_FUNCTION;
+  const CodePreparation &
+  operator=(const CodePreparation &) LLVM_DELETED_FUNCTION;
+
+  LoopInfo *LI;
+  ScalarEvolution *SE;
+
+  void clear();
+
+  bool eliminatePHINodes(Function &F);
+
+public:
+  static char ID;
+
+  explicit CodePreparation() : FunctionPass(ID) {}
+  ~CodePreparation();
+
+  /// @name FunctionPass interface.
+  //@{
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+  virtual void releaseMemory();
+  virtual bool runOnFunction(Function &F);
+  virtual void print(raw_ostream &OS, const Module *) const;
+  //@}
+};
+}
+
+void CodePreparation::clear() {}
+
+CodePreparation::~CodePreparation() { clear(); }
+
+bool CodePreparation::eliminatePHINodes(Function &F) {
+  // The PHINodes that will be demoted.
+  std::vector<PHINode *> PNtoDemote;
+  // The PHINodes that will be deleted (stack slot sharing).
+  std::vector<PHINode *> PNtoDelete;
+  // The PHINodes that will be preserved.
+  std::vector<PHINode *> PNtoPreserve;
+  // Map to remember values stored in PHINodes at the end of basic blocks.
+  DenseMap<std::pair<Value *, BasicBlock *>, PHINode *> ValueLocToPhiMap;
+  // Map from PHINodes to their alloca (after demotion) counterpart.
+  DenseMap<PHINode *, AllocaInst *> PNallocMap;
+
+  // Scan the PHINodes in this function and categorize them to be either:
+  // o Preserved, if they are (canonical) induction variables or can be
+  //              synthesized during code generation ('SCEVable')
+  // o Deleted, if they are trivial PHI nodes (one incoming value) and the
+  //            incoming value is a PHI node we will demote
+  // o Demoted, if they do not fit any of the previous categories
+  for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI)
+    for (BasicBlock::iterator II = BI->begin(), IE = BI->getFirstNonPHI();
+         II != IE; ++II) {
+      PHINode *PN = cast<PHINode>(II);
+      if (SCEVCodegen) {
+        if (SE->isSCEVable(PN->getType())) {
+          const SCEV *S = SE->getSCEV(PN);
+          if (!isa<SCEVUnknown>(S) && !isa<SCEVCouldNotCompute>(S)) {
+            PNtoPreserve.push_back(PN);
+            continue;
+          }
+        }
+      } else {
+        if (Loop *L = LI->getLoopFor(BI)) {
+          // Induction variables will be preserved.
+          if (L->getCanonicalInductionVariable() == PN) {
+            PNtoPreserve.push_back(PN);
+            continue;
+          }
+        }
+      }
+
+      // As DemotePHIToStack does not support invoke edges, we preserve
+      // PHINodes that have invoke edges.
+      if (hasInvokeEdge(PN)) {
+        PNtoPreserve.push_back(PN);
+      } else {
+        if (PN->getNumIncomingValues() == 1)
+          PNtoDelete.push_back(PN);
+        else
+          PNtoDemote.push_back(PN);
+      }
+    }
+
+  if (PNtoDemote.empty() && PNtoDelete.empty())
+    return false;
+
+  while (!PNtoDemote.empty()) {
+    PHINode *PN = PNtoDemote.back();
+    PNtoDemote.pop_back();
+    DemotePHI(PN, PNallocMap, ValueLocToPhiMap);
+  }
+
+  // For each trivial PHI we encountered (and we want to delete) we try to find
+  // the value it will hold in a alloca we already created by PHI demotion. If
+  // we succeed (the incoming value is stored in an alloca at the predecessor
+  // block), we can replace the trivial PHI by the value stored in the alloca.
+  // If not, we will demote this trivial PHI as any other one.
+  for (auto PNIt = PNtoDelete.rbegin(), PNEnd = PNtoDelete.rend();
+       PNIt != PNEnd; ++PNIt) {
+    PHINode *TrivPN = *PNIt;
+    assert(TrivPN->getNumIncomingValues() == 1 && "Assumed trivial PHI");
+
+    auto *InVal = TrivPN->getIncomingValue(0);
+    auto *InBB = TrivPN->getIncomingBlock(0);
+    const auto &ValLocIt = ValueLocToPhiMap.find(std::make_pair(InVal, InBB));
+    if (ValLocIt != ValueLocToPhiMap.end()) {
+      PHINode *InPHI = ValLocIt->second;
+      assert(PNallocMap.count(InPHI) &&
+             "Inconsitent state, PN was not demoted!");
+      auto *InPHIAlloca = PNallocMap[InPHI];
+      PNallocMap[TrivPN] = InPHIAlloca;
+      LoadInst *LI = new LoadInst(InPHIAlloca, "",
+                                  TrivPN->getParent()->getFirstInsertionPt());
+      TrivPN->replaceAllUsesWith(LI);
+      TrivPN->eraseFromParent();
+      continue;
+    }
+
+    DemotePHI(TrivPN, PNallocMap, ValueLocToPhiMap);
+  }
+
+  // Move preserved PHINodes to the beginning of the BasicBlock.
+  while (!PNtoPreserve.empty()) {
+    PHINode *PN = PNtoPreserve.back();
+    PNtoPreserve.pop_back();
+
+    BasicBlock *BB = PN->getParent();
+    if (PN == BB->begin())
+      continue;
+
+    PN->moveBefore(BB->begin());
+  }
+
+  return true;
+}
+
+void CodePreparation::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<LoopInfo>();
+  AU.addRequired<ScalarEvolution>();
+
+  AU.addPreserved<LoopInfo>();
+  AU.addPreserved<RegionInfoPass>();
+  AU.addPreserved<DominatorTreeWrapperPass>();
+  AU.addPreserved<DominanceFrontier>();
+}
+
+bool CodePreparation::runOnFunction(Function &F) {
+  LI = &getAnalysis<LoopInfo>();
+  SE = &getAnalysis<ScalarEvolution>();
+
+  splitEntryBlockForAlloca(&F.getEntryBlock(), this);
+
+  eliminatePHINodes(F);
+
+  return false;
+}
+
+void CodePreparation::releaseMemory() { clear(); }
+
+void CodePreparation::print(raw_ostream &OS, const Module *) const {}
+
+char CodePreparation::ID = 0;
+char &polly::CodePreparationID = CodePreparation::ID;
+
+Pass *polly::createCodePreparationPass() { return new CodePreparation(); }
+
+INITIALIZE_PASS_BEGIN(CodePreparation, "polly-prepare",
+                      "Polly - Prepare code for polly", false, false)
+INITIALIZE_PASS_DEPENDENCY(LoopInfo)
+INITIALIZE_PASS_END(CodePreparation, "polly-prepare",
+                    "Polly - Prepare code for polly", false, false)
diff --git a/rc1/lib/Transform/DeadCodeElimination.cpp b/rc1/lib/Transform/DeadCodeElimination.cpp
new file mode 100644
index 0000000..c5cd579
--- /dev/null
+++ b/rc1/lib/Transform/DeadCodeElimination.cpp
@@ -0,0 +1,175 @@
+//===- DeadCodeElimination.cpp - Eliminate dead iteration  ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The polyhedral dead code elimination pass analyses a SCoP to eliminate
+// statement instances that can be proven dead.
+// As a consequence, the code generated for this SCoP may execute a statement
+// less often. This means, a statement may be executed only in certain loop
+// iterations or it may not even be part of the generated code at all.
+//
+// This code:
+//
+//    for (i = 0; i < N; i++)
+//        arr[i] = 0;
+//    for (i = 0; i < N; i++)
+//        arr[i] = 10;
+//    for (i = 0; i < N; i++)
+//        arr[i] = i;
+//
+// is e.g. simplified to:
+//
+//    for (i = 0; i < N; i++)
+//        arr[i] = i;
+//
+// The idea and the algorithm used was first implemented by Sven Verdoolaege in
+// the 'ppcg' tool.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Dependences.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/ScopInfo.h"
+#include "llvm/Support/CommandLine.h"
+#include "isl/flow.h"
+#include "isl/set.h"
+#include "isl/map.h"
+#include "isl/union_map.h"
+
+using namespace llvm;
+using namespace polly;
+
+namespace {
+
+cl::opt<int> DCEPreciseSteps(
+    "polly-dce-precise-steps",
+    cl::desc("The number of precise steps between two approximating "
+             "iterations. (A value of -1 schedules another approximation stage "
+             "before the actual dead code elimination."),
+    cl::ZeroOrMore, cl::init(-1));
+
+class DeadCodeElim : public ScopPass {
+public:
+  static char ID;
+  explicit DeadCodeElim() : ScopPass(ID) {}
+
+  virtual bool runOnScop(Scop &S);
+
+  void printScop(llvm::raw_ostream &OS) const;
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+
+private:
+  /// @brief Return the set of live iterations.
+  ///
+  /// The set of live iterations are all iterations that write to memory and for
+  /// which we can not prove that there will be a later write that _must_
+  /// overwrite the same memory location and is consequently the only one that
+  /// is visible after the execution of the SCoP.
+  ///
+  isl_union_set *getLiveOut(Scop &S);
+  bool eliminateDeadCode(Scop &S, int PreciseSteps);
+};
+}
+
+char DeadCodeElim::ID = 0;
+
+// To compute the live outs, we compute for the data-locations that are
+// must-written to the last statement that touches these locations. On top of
+// this we add all statements that perform may-write accesses.
+//
+// We could be more precise by removing may-write accesses for which we know
+// that they are overwritten by a must-write after. However, at the moment the
+// only may-writes we introduce access the full (unbounded) array, such that
+// bounded write accesses can not overwrite all of the data-locations. As
+// this means may-writes are in the current situation always live, there is
+// no point in trying to remove them from the live-out set.
+isl_union_set *DeadCodeElim::getLiveOut(Scop &S) {
+  isl_union_map *Schedule = S.getSchedule();
+  isl_union_map *WriteIterations = isl_union_map_reverse(S.getMustWrites());
+  isl_union_map *WriteTimes =
+      isl_union_map_apply_range(WriteIterations, isl_union_map_copy(Schedule));
+
+  isl_union_map *LastWriteTimes = isl_union_map_lexmax(WriteTimes);
+  isl_union_map *LastWriteIterations = isl_union_map_apply_range(
+      LastWriteTimes, isl_union_map_reverse(Schedule));
+
+  isl_union_set *Live = isl_union_map_range(LastWriteIterations);
+  Live = isl_union_set_union(Live, isl_union_map_domain(S.getMayWrites()));
+  return isl_union_set_coalesce(Live);
+}
+
+/// Performs polyhedral dead iteration elimination by:
+/// o Assuming that the last write to each location is live.
+/// o Following each RAW dependency from a live iteration backwards and adding
+///   that iteration to the live set.
+///
+/// To ensure the set of live iterations does not get too complex we always
+/// combine a certain number of precise steps with one approximating step that
+/// simplifies the life set with an affine hull.
+bool DeadCodeElim::eliminateDeadCode(Scop &S, int PreciseSteps) {
+  Dependences *D = &getAnalysis<Dependences>();
+
+  if (!D->hasValidDependences())
+    return false;
+
+  isl_union_set *Live = getLiveOut(S);
+  isl_union_map *Dep =
+      D->getDependences(Dependences::TYPE_RAW | Dependences::TYPE_RED);
+  Dep = isl_union_map_reverse(Dep);
+
+  if (PreciseSteps == -1)
+    Live = isl_union_set_affine_hull(Live);
+
+  isl_union_set *OriginalDomain = S.getDomains();
+  int Steps = 0;
+  while (true) {
+    isl_union_set *Extra;
+    Steps++;
+
+    Extra =
+        isl_union_set_apply(isl_union_set_copy(Live), isl_union_map_copy(Dep));
+
+    if (isl_union_set_is_subset(Extra, Live)) {
+      isl_union_set_free(Extra);
+      break;
+    }
+
+    Live = isl_union_set_union(Live, Extra);
+
+    if (Steps > PreciseSteps) {
+      Steps = 0;
+      Live = isl_union_set_affine_hull(Live);
+    }
+
+    Live = isl_union_set_intersect(Live, isl_union_set_copy(OriginalDomain));
+  }
+  isl_union_map_free(Dep);
+  isl_union_set_free(OriginalDomain);
+
+  return S.restrictDomains(isl_union_set_coalesce(Live));
+}
+
+bool DeadCodeElim::runOnScop(Scop &S) {
+  return eliminateDeadCode(S, DCEPreciseSteps);
+}
+
+void DeadCodeElim::printScop(raw_ostream &OS) const {}
+
+void DeadCodeElim::getAnalysisUsage(AnalysisUsage &AU) const {
+  ScopPass::getAnalysisUsage(AU);
+  AU.addRequired<Dependences>();
+}
+
+Pass *polly::createDeadCodeElimPass() { return new DeadCodeElim(); }
+
+INITIALIZE_PASS_BEGIN(DeadCodeElim, "polly-dce",
+                      "Polly - Remove dead iterations", false, false)
+INITIALIZE_PASS_DEPENDENCY(Dependences)
+INITIALIZE_PASS_DEPENDENCY(ScopInfo)
+INITIALIZE_PASS_END(DeadCodeElim, "polly-dce", "Polly - Remove dead iterations",
+                    false, false)
diff --git a/rc1/lib/Transform/IndVarSimplify.cpp b/rc1/lib/Transform/IndVarSimplify.cpp
new file mode 100644
index 0000000..8d4f51c
--- /dev/null
+++ b/rc1/lib/Transform/IndVarSimplify.cpp
@@ -0,0 +1,2009 @@
+//===- IndVarSimplify.cpp - Induction Variable Elimination ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This transformation analyzes and transforms the induction variables (and
+// computations derived from them) into simpler forms suitable for subsequent
+// analysis and transformation.
+//
+// If the trip count of a loop is computable, this pass also makes the following
+// changes:
+//   1. The exit condition for the loop is canonicalized to compare the
+//      induction value against the exit value.  This turns loops like:
+//        'for (i = 7; i*i < 1000; ++i)' into 'for (i = 0; i != 25; ++i)'
+//   2. Any use outside of the loop of an expression derived from the indvar
+//      is changed to compute the derived value outside of the loop, eliminating
+//      the dependence on the exit value of the induction variable.  If the only
+//      purpose of the loop is to compute the exit value of some derived
+//      expression, this transformation will make the loop dead.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/LinkAllPasses.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/IVUsers.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Transforms/Utils/SimplifyIndVar.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "indvars"
+
+STATISTIC(NumRemoved, "Number of aux indvars removed");
+STATISTIC(NumWidened, "Number of indvars widened");
+STATISTIC(NumInserted, "Number of canonical indvars added");
+STATISTIC(NumReplaced, "Number of exit values replaced");
+STATISTIC(NumLFTR, "Number of loop exit tests replaced");
+STATISTIC(NumElimExt, "Number of IV sign/zero extends eliminated");
+STATISTIC(NumElimIV, "Number of congruent IVs eliminated");
+
+static const bool EnableIVRewrite = true;
+#ifndef NDEBUG
+static const bool VerifyIndvars = false;
+#endif
+
+namespace {
+class PollyIndVarSimplify : public LoopPass {
+  IVUsers *IU;
+  LoopInfo *LI;
+  ScalarEvolution *SE;
+  DominatorTree *DT;
+  const DataLayout *TD;
+
+  SmallVector<WeakVH, 16> DeadInsts;
+  bool Changed;
+
+public:
+  static char ID; // Pass identification, replacement for typeid
+  PollyIndVarSimplify()
+      : LoopPass(ID), IU(0), LI(0), SE(0), DT(0), TD(0), Changed(false) {
+    initializeIndVarSimplifyPass(*PassRegistry::getPassRegistry());
+  }
+
+  virtual bool runOnLoop(Loop *L, LPPassManager &LPM);
+
+  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.addRequired<DominatorTreeWrapperPass>();
+    AU.addRequired<LoopInfo>();
+    AU.addRequired<ScalarEvolution>();
+    AU.addRequiredID(LoopSimplifyID);
+    AU.addRequiredID(LCSSAID);
+    if (EnableIVRewrite)
+      AU.addRequired<IVUsers>();
+    AU.addPreserved<ScalarEvolution>();
+    AU.addPreservedID(LoopSimplifyID);
+    AU.addPreservedID(LCSSAID);
+    if (EnableIVRewrite)
+      AU.addPreserved<IVUsers>();
+    AU.setPreservesCFG();
+  }
+
+private:
+  virtual void releaseMemory() { DeadInsts.clear(); }
+
+  bool isValidRewrite(Value *FromVal, Value *ToVal);
+
+  void HandleFloatingPointIV(Loop *L, PHINode *PH);
+  void RewriteNonIntegerIVs(Loop *L);
+
+  void SimplifyAndExtend(Loop *L, SCEVExpander &Rewriter, LPPassManager &LPM);
+
+  void RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter);
+
+  void RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter);
+
+  Value *LinearFunctionTestReplace(Loop *L, const SCEV *BackedgeTakenCount,
+                                   PHINode *IndVar, SCEVExpander &Rewriter);
+
+  void SinkUnusedInvariants(Loop *L);
+};
+}
+
+char PollyIndVarSimplify::ID = 0;
+Pass *polly::createIndVarSimplifyPass() { return new PollyIndVarSimplify(); }
+
+/// isValidRewrite - Return true if the SCEV expansion generated by the
+/// rewriter can replace the original value. SCEV guarantees that it
+/// produces the same value, but the way it is produced may be illegal IR.
+/// Ideally, this function will only be called for verification.
+bool PollyIndVarSimplify::isValidRewrite(Value *FromVal, Value *ToVal) {
+  // If an SCEV expression subsumed multiple pointers, its expansion could
+  // reassociate the GEP changing the base pointer. This is illegal because the
+  // final address produced by a GEP chain must be inbounds relative to its
+  // underlying object. Otherwise basic alias analysis, among other things,
+  // could fail in a dangerous way. Ultimately, SCEV will be improved to avoid
+  // producing an expression involving multiple pointers. Until then, we must
+  // bail out here.
+  //
+  // Retrieve the pointer operand of the GEP. Don't use GetUnderlyingObject
+  // because it understands lcssa phis while SCEV does not.
+  Value *FromPtr = FromVal;
+  Value *ToPtr = ToVal;
+  if (GEPOperator *GEP = dyn_cast<GEPOperator>(FromVal)) {
+    FromPtr = GEP->getPointerOperand();
+  }
+  if (GEPOperator *GEP = dyn_cast<GEPOperator>(ToVal)) {
+    ToPtr = GEP->getPointerOperand();
+  }
+  if (FromPtr != FromVal || ToPtr != ToVal) {
+    // Quickly check the common case
+    if (FromPtr == ToPtr)
+      return true;
+
+    // SCEV may have rewritten an expression that produces the GEP's pointer
+    // operand. That's ok as long as the pointer operand has the same base
+    // pointer. Unlike GetUnderlyingObject(), getPointerBase() will find the
+    // base of a recurrence. This handles the case in which SCEV expansion
+    // converts a pointer type recurrence into a nonrecurrent pointer base
+    // indexed by an integer recurrence.
+
+    // If the GEP base pointer is a vector of pointers, abort.
+    if (!FromPtr->getType()->isPointerTy() || !ToPtr->getType()->isPointerTy())
+      return false;
+
+    const SCEV *FromBase = SE->getPointerBase(SE->getSCEV(FromPtr));
+    const SCEV *ToBase = SE->getPointerBase(SE->getSCEV(ToPtr));
+    if (FromBase == ToBase)
+      return true;
+
+    DEBUG(dbgs() << "INDVARS: GEP rewrite bail out " << *FromBase
+                 << " != " << *ToBase << "\n");
+
+    return false;
+  }
+  return true;
+}
+
+/// Determine the insertion point for this user. By default, insert immediately
+/// before the user. SCEVExpander or LICM will hoist loop invariants out of the
+/// loop. For PHI nodes, there may be multiple uses, so compute the nearest
+/// common dominator for the incoming blocks.
+static Instruction *getInsertPointForUses(Instruction *User, Value *Def,
+                                          DominatorTree *DT) {
+  PHINode *PHI = dyn_cast<PHINode>(User);
+  if (!PHI)
+    return User;
+
+  Instruction *InsertPt = 0;
+  for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) {
+    if (PHI->getIncomingValue(i) != Def)
+      continue;
+
+    BasicBlock *InsertBB = PHI->getIncomingBlock(i);
+    if (!InsertPt) {
+      InsertPt = InsertBB->getTerminator();
+      continue;
+    }
+    InsertBB = DT->findNearestCommonDominator(InsertPt->getParent(), InsertBB);
+    InsertPt = InsertBB->getTerminator();
+  }
+  assert(InsertPt && "Missing phi operand");
+  assert((!isa<Instruction>(Def) ||
+          DT->dominates(cast<Instruction>(Def), InsertPt)) &&
+         "def does not dominate all uses");
+  return InsertPt;
+}
+
+//===----------------------------------------------------------------------===//
+// RewriteNonIntegerIVs and helpers. Prefer integer IVs.
+//===----------------------------------------------------------------------===//
+
+/// ConvertToSInt - Convert APF to an integer, if possible.
+static bool ConvertToSInt(const APFloat &APF, int64_t &IntVal) {
+  bool isExact = false;
+  if (&APF.getSemantics() == &APFloat::PPCDoubleDouble)
+    return false;
+  // See if we can convert this to an int64_t
+  uint64_t UIntVal;
+  if (APF.convertToInteger(&UIntVal, 64, true, APFloat::rmTowardZero,
+                           &isExact) != APFloat::opOK ||
+      !isExact)
+    return false;
+  IntVal = UIntVal;
+  return true;
+}
+
+/// HandleFloatingPointIV - If the loop has floating induction variable
+/// then insert corresponding integer induction variable if possible.
+/// For example,
+/// for(double i = 0; i < 10000; ++i)
+///   bar(i)
+/// is converted into
+/// for(int i = 0; i < 10000; ++i)
+///   bar((double)i);
+///
+void PollyIndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) {
+  unsigned IncomingEdge = L->contains(PN->getIncomingBlock(0));
+  unsigned BackEdge = IncomingEdge ^ 1;
+
+  // Check incoming value.
+  ConstantFP *InitValueVal =
+      dyn_cast<ConstantFP>(PN->getIncomingValue(IncomingEdge));
+
+  int64_t InitValue;
+  if (!InitValueVal || !ConvertToSInt(InitValueVal->getValueAPF(), InitValue))
+    return;
+
+  // Check IV increment. Reject this PN if increment operation is not
+  // an add or increment value can not be represented by an integer.
+  BinaryOperator *Incr =
+      dyn_cast<BinaryOperator>(PN->getIncomingValue(BackEdge));
+  if (Incr == 0 || Incr->getOpcode() != Instruction::FAdd)
+    return;
+
+  // If this is not an add of the PHI with a constantfp, or if the constant fp
+  // is not an integer, bail out.
+  ConstantFP *IncValueVal = dyn_cast<ConstantFP>(Incr->getOperand(1));
+  int64_t IncValue;
+  if (IncValueVal == 0 || Incr->getOperand(0) != PN ||
+      !ConvertToSInt(IncValueVal->getValueAPF(), IncValue))
+    return;
+
+  // Check Incr uses. One user is PN and the other user is an exit condition
+  // used by the conditional terminator.
+  Value::user_iterator IncrUse = Incr->user_begin();
+  Instruction *U1 = cast<Instruction>(*IncrUse++);
+  if (IncrUse == Incr->user_end())
+    return;
+  Instruction *U2 = cast<Instruction>(*IncrUse++);
+  if (IncrUse != Incr->user_end())
+    return;
+
+  // Find exit condition, which is an fcmp.  If it doesn't exist, or if it isn't
+  // only used by a branch, we can't transform it.
+  FCmpInst *Compare = dyn_cast<FCmpInst>(U1);
+  if (!Compare)
+    Compare = dyn_cast<FCmpInst>(U2);
+  if (Compare == 0 || !Compare->hasOneUse() ||
+      !isa<BranchInst>(Compare->user_back()))
+    return;
+
+  BranchInst *TheBr = cast<BranchInst>(Compare->user_back());
+
+  // We need to verify that the branch actually controls the iteration count
+  // of the loop.  If not, the new IV can overflow and no one will notice.
+  // The branch block must be in the loop and one of the successors must be out
+  // of the loop.
+  assert(TheBr->isConditional() && "Can't use fcmp if not conditional");
+  if (!L->contains(TheBr->getParent()) ||
+      (L->contains(TheBr->getSuccessor(0)) &&
+       L->contains(TheBr->getSuccessor(1))))
+    return;
+
+  // If it isn't a comparison with an integer-as-fp (the exit value), we can't
+  // transform it.
+  ConstantFP *ExitValueVal = dyn_cast<ConstantFP>(Compare->getOperand(1));
+  int64_t ExitValue;
+  if (ExitValueVal == 0 ||
+      !ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue))
+    return;
+
+  // Find new predicate for integer comparison.
+  CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE;
+  switch (Compare->getPredicate()) {
+  default:
+    return; // Unknown comparison.
+  case CmpInst::FCMP_OEQ:
+  case CmpInst::FCMP_UEQ:
+    NewPred = CmpInst::ICMP_EQ;
+    break;
+  case CmpInst::FCMP_ONE:
+  case CmpInst::FCMP_UNE:
+    NewPred = CmpInst::ICMP_NE;
+    break;
+  case CmpInst::FCMP_OGT:
+  case CmpInst::FCMP_UGT:
+    NewPred = CmpInst::ICMP_SGT;
+    break;
+  case CmpInst::FCMP_OGE:
+  case CmpInst::FCMP_UGE:
+    NewPred = CmpInst::ICMP_SGE;
+    break;
+  case CmpInst::FCMP_OLT:
+  case CmpInst::FCMP_ULT:
+    NewPred = CmpInst::ICMP_SLT;
+    break;
+  case CmpInst::FCMP_OLE:
+  case CmpInst::FCMP_ULE:
+    NewPred = CmpInst::ICMP_SLE;
+    break;
+  }
+
+  // We convert the floating point induction variable to a signed i32 value if
+  // we can.  This is only safe if the comparison will not overflow in a way
+  // that won't be trapped by the integer equivalent operations.  Check for this
+  // now.
+  // TODO: We could use i64 if it is native and the range requires it.
+
+  // The start/stride/exit values must all fit in signed i32.
+  if (!isInt<32>(InitValue) || !isInt<32>(IncValue) || !isInt<32>(ExitValue))
+    return;
+
+  // If not actually striding (add x, 0.0), avoid touching the code.
+  if (IncValue == 0)
+    return;
+
+  // Positive and negative strides have different safety conditions.
+  if (IncValue > 0) {
+    // If we have a positive stride, we require the init to be less than the
+    // exit value.
+    if (InitValue >= ExitValue)
+      return;
+
+    uint32_t Range = uint32_t(ExitValue - InitValue);
+    // Check for infinite loop, either:
+    // while (i <= Exit) or until (i > Exit)
+    if (NewPred == CmpInst::ICMP_SLE || NewPred == CmpInst::ICMP_SGT) {
+      if (++Range == 0)
+        return; // Range overflows.
+    }
+
+    unsigned Leftover = Range % uint32_t(IncValue);
+
+    // If this is an equality comparison, we require that the strided value
+    // exactly land on the exit value, otherwise the IV condition will wrap
+    // around and do things the fp IV wouldn't.
+    if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) &&
+        Leftover != 0)
+      return;
+
+    // If the stride would wrap around the i32 before exiting, we can't
+    // transform the IV.
+    if (Leftover != 0 && int32_t(ExitValue + IncValue) < ExitValue)
+      return;
+
+  } else {
+    // If we have a negative stride, we require the init to be greater than the
+    // exit value.
+    if (InitValue <= ExitValue)
+      return;
+
+    uint32_t Range = uint32_t(InitValue - ExitValue);
+    // Check for infinite loop, either:
+    // while (i >= Exit) or until (i < Exit)
+    if (NewPred == CmpInst::ICMP_SGE || NewPred == CmpInst::ICMP_SLT) {
+      if (++Range == 0)
+        return; // Range overflows.
+    }
+
+    unsigned Leftover = Range % uint32_t(-IncValue);
+
+    // If this is an equality comparison, we require that the strided value
+    // exactly land on the exit value, otherwise the IV condition will wrap
+    // around and do things the fp IV wouldn't.
+    if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) &&
+        Leftover != 0)
+      return;
+
+    // If the stride would wrap around the i32 before exiting, we can't
+    // transform the IV.
+    if (Leftover != 0 && int32_t(ExitValue + IncValue) > ExitValue)
+      return;
+  }
+
+  IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext());
+
+  // Insert new integer induction variable.
+  PHINode *NewPHI = PHINode::Create(Int32Ty, 2, PN->getName() + ".int", PN);
+  NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue),
+                      PN->getIncomingBlock(IncomingEdge));
+
+  Value *NewAdd =
+      BinaryOperator::CreateAdd(NewPHI, ConstantInt::get(Int32Ty, IncValue),
+                                Incr->getName() + ".int", Incr);
+  NewPHI->addIncoming(NewAdd, PN->getIncomingBlock(BackEdge));
+
+  ICmpInst *NewCompare =
+      new ICmpInst(TheBr, NewPred, NewAdd, ConstantInt::get(Int32Ty, ExitValue),
+                   Compare->getName());
+
+  // In the following deletions, PN may become dead and may be deleted.
+  // Use a WeakVH to observe whether this happens.
+  WeakVH WeakPH = PN;
+
+  // Delete the old floating point exit comparison.  The branch starts using the
+  // new comparison.
+  NewCompare->takeName(Compare);
+  Compare->replaceAllUsesWith(NewCompare);
+  RecursivelyDeleteTriviallyDeadInstructions(Compare);
+
+  // Delete the old floating point increment.
+  Incr->replaceAllUsesWith(UndefValue::get(Incr->getType()));
+  RecursivelyDeleteTriviallyDeadInstructions(Incr);
+
+  // If the FP induction variable still has uses, this is because something else
+  // in the loop uses its value.  In order to canonicalize the induction
+  // variable, we chose to eliminate the IV and rewrite it in terms of an
+  // int->fp cast.
+  //
+  // We give preference to sitofp over uitofp because it is faster on most
+  // platforms.
+  if (WeakPH) {
+    Value *Conv = new SIToFPInst(NewPHI, PN->getType(), "indvar.conv",
+                                 PN->getParent()->getFirstInsertionPt());
+    PN->replaceAllUsesWith(Conv);
+    RecursivelyDeleteTriviallyDeadInstructions(PN);
+  }
+
+  // Add a new IVUsers entry for the newly-created integer PHI.
+  if (IU)
+    IU->AddUsersIfInteresting(NewPHI);
+
+  Changed = true;
+}
+
+void PollyIndVarSimplify::RewriteNonIntegerIVs(Loop *L) {
+  // First step.  Check to see if there are any floating-point recurrences.
+  // If there are, change them into integer recurrences, permitting analysis by
+  // the SCEV routines.
+  //
+  BasicBlock *Header = L->getHeader();
+
+  SmallVector<WeakVH, 8> PHIs;
+  for (BasicBlock::iterator I = Header->begin();
+       PHINode *PN = dyn_cast<PHINode>(I); ++I)
+    PHIs.push_back(PN);
+
+  for (unsigned i = 0, e = PHIs.size(); i != e; ++i)
+    if (PHINode *PN = dyn_cast_or_null<PHINode>(&*PHIs[i]))
+      HandleFloatingPointIV(L, PN);
+
+  // If the loop previously had floating-point IV, ScalarEvolution
+  // may not have been able to compute a trip count. Now that we've done some
+  // re-writing, the trip count may be computable.
+  if (Changed)
+    SE->forgetLoop(L);
+}
+
+//===----------------------------------------------------------------------===//
+// RewriteLoopExitValues - Optimize IV users outside the loop.
+// As a side effect, reduces the amount of IV processing within the loop.
+//===----------------------------------------------------------------------===//
+
+/// RewriteLoopExitValues - Check to see if this loop has a computable
+/// loop-invariant execution count.  If so, this means that we can compute the
+/// final value of any expressions that are recurrent in the loop, and
+/// substitute the exit values from the loop into any instructions outside of
+/// the loop that use the final values of the current expressions.
+///
+/// This is mostly redundant with the regular IndVarSimplify activities that
+/// happen later, except that it's more powerful in some cases, because it's
+/// able to brute-force evaluate arbitrary instructions as long as they have
+/// constant operands at the beginning of the loop.
+void PollyIndVarSimplify::RewriteLoopExitValues(Loop *L,
+                                                SCEVExpander &Rewriter) {
+  // Verify the input to the pass in already in LCSSA form.
+  assert(L->isLCSSAForm(*DT));
+
+  SmallVector<BasicBlock *, 8> ExitBlocks;
+  L->getUniqueExitBlocks(ExitBlocks);
+
+  // Find all values that are computed inside the loop, but used outside of it.
+  // Because of LCSSA, these values will only occur in LCSSA PHI Nodes.  Scan
+  // the exit blocks of the loop to find them.
+  for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
+    BasicBlock *ExitBB = ExitBlocks[i];
+
+    // If there are no PHI nodes in this exit block, then no values defined
+    // inside the loop are used on this path, skip it.
+    PHINode *PN = dyn_cast<PHINode>(ExitBB->begin());
+    if (!PN)
+      continue;
+
+    unsigned NumPreds = PN->getNumIncomingValues();
+
+    // Iterate over all of the PHI nodes.
+    BasicBlock::iterator BBI = ExitBB->begin();
+    while ((PN = dyn_cast<PHINode>(BBI++))) {
+      if (PN->use_empty())
+        continue; // dead use, don't replace it
+
+      // SCEV only supports integer expressions for now.
+      if (!PN->getType()->isIntegerTy() && !PN->getType()->isPointerTy())
+        continue;
+
+      // It's necessary to tell ScalarEvolution about this explicitly so that
+      // it can walk the def-use list and forget all SCEVs, as it may not be
+      // watching the PHI itself. Once the new exit value is in place, there
+      // may not be a def-use connection between the loop and every instruction
+      // which got a SCEVAddRecExpr for that loop.
+      SE->forgetValue(PN);
+
+      // Iterate over all of the values in all the PHI nodes.
+      for (unsigned i = 0; i != NumPreds; ++i) {
+        // If the value being merged in is not integer or is not defined
+        // in the loop, skip it.
+        Value *InVal = PN->getIncomingValue(i);
+        if (!isa<Instruction>(InVal))
+          continue;
+
+        // If this pred is for a subloop, not L itself, skip it.
+        if (LI->getLoopFor(PN->getIncomingBlock(i)) != L)
+          continue; // The Block is in a subloop, skip it.
+
+        // Check that InVal is defined in the loop.
+        Instruction *Inst = cast<Instruction>(InVal);
+        if (!L->contains(Inst))
+          continue;
+
+        // Okay, this instruction has a user outside of the current loop
+        // and varies predictably *inside* the loop.  Evaluate the value it
+        // contains when the loop exits, if possible.
+        const SCEV *ExitValue = SE->getSCEVAtScope(Inst, L->getParentLoop());
+        if (!SE->isLoopInvariant(ExitValue, L))
+          continue;
+
+        Value *ExitVal = Rewriter.expandCodeFor(ExitValue, PN->getType(), Inst);
+
+        DEBUG(dbgs() << "INDVARS: RLEV: AfterLoopVal = " << *ExitVal << '\n'
+                     << "  LoopVal = " << *Inst << "\n");
+
+        if (!isValidRewrite(Inst, ExitVal)) {
+          DeadInsts.push_back(ExitVal);
+          continue;
+        }
+        Changed = true;
+        ++NumReplaced;
+
+        PN->setIncomingValue(i, ExitVal);
+
+        // If this instruction is dead now, delete it.
+        RecursivelyDeleteTriviallyDeadInstructions(Inst);
+
+        if (NumPreds == 1) {
+          // Completely replace a single-pred PHI. This is safe, because the
+          // NewVal won't be variant in the loop, so we don't need an LCSSA phi
+          // node anymore.
+          PN->replaceAllUsesWith(ExitVal);
+          RecursivelyDeleteTriviallyDeadInstructions(PN);
+        }
+      }
+      if (NumPreds != 1) {
+        // Clone the PHI and delete the original one. This lets IVUsers and
+        // any other maps purge the original user from their records.
+        PHINode *NewPN = cast<PHINode>(PN->clone());
+        NewPN->takeName(PN);
+        NewPN->insertBefore(PN);
+        PN->replaceAllUsesWith(NewPN);
+        PN->eraseFromParent();
+      }
+    }
+  }
+
+  // The insertion point instruction may have been deleted; clear it out
+  // so that the rewriter doesn't trip over it later.
+  Rewriter.clearInsertPoint();
+}
+
+//===----------------------------------------------------------------------===//
+//  Rewrite IV users based on a canonical IV.
+//  Only for use with -enable-iv-rewrite.
+//===----------------------------------------------------------------------===//
+
+/// FIXME: It is an extremely bad idea to indvar substitute anything more
+/// complex than affine induction variables.  Doing so will put expensive
+/// polynomial evaluations inside of the loop, and the str reduction pass
+/// currently can only reduce affine polynomials.  For now just disable
+/// indvar subst on anything more complex than an affine addrec, unless
+/// it can be expanded to a trivial value.
+static bool isSafe(const SCEV *S, const Loop *L, ScalarEvolution *SE) {
+  // Loop-invariant values are safe.
+  if (SE->isLoopInvariant(S, L))
+    return true;
+
+  // Affine addrecs are safe. Non-affine are not, because LSR doesn't know how
+  // to transform them into efficient code.
+  if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(S))
+    return AR->isAffine();
+
+  // An add is safe it all its operands are safe.
+  if (const SCEVCommutativeExpr *Commutative =
+          dyn_cast<SCEVCommutativeExpr>(S)) {
+    for (SCEVCommutativeExpr::op_iterator I = Commutative->op_begin(),
+                                          E = Commutative->op_end();
+         I != E; ++I)
+      if (!isSafe(*I, L, SE))
+        return false;
+    return true;
+  }
+
+  // A cast is safe if its operand is.
+  if (const SCEVCastExpr *C = dyn_cast<SCEVCastExpr>(S))
+    return isSafe(C->getOperand(), L, SE);
+
+  // A udiv is safe if its operands are.
+  if (const SCEVUDivExpr *UD = dyn_cast<SCEVUDivExpr>(S))
+    return isSafe(UD->getLHS(), L, SE) && isSafe(UD->getRHS(), L, SE);
+
+  // SCEVUnknown is always safe.
+  if (isa<SCEVUnknown>(S))
+    return true;
+
+  // Nothing else is safe.
+  return false;
+}
+
+void PollyIndVarSimplify::RewriteIVExpressions(Loop *L,
+                                               SCEVExpander &Rewriter) {
+  // Rewrite all induction variable expressions in terms of the canonical
+  // induction variable.
+  //
+  // If there were induction variables of other sizes or offsets, manually
+  // add the offsets to the primary induction variable and cast, avoiding
+  // the need for the code evaluation methods to insert induction variables
+  // of different sizes.
+  for (IVUsers::iterator UI = IU->begin(), E = IU->end(); UI != E; ++UI) {
+    Value *Op = UI->getOperandValToReplace();
+    Type *UseTy = Op->getType();
+    Instruction *User = UI->getUser();
+
+    // Compute the final addrec to expand into code.
+    const SCEV *AR = IU->getReplacementExpr(*UI);
+
+    // Evaluate the expression out of the loop, if possible.
+    if (!L->contains(UI->getUser())) {
+      const SCEV *ExitVal = SE->getSCEVAtScope(AR, L->getParentLoop());
+      if (SE->isLoopInvariant(ExitVal, L))
+        AR = ExitVal;
+    }
+
+    // FIXME: It is an extremely bad idea to indvar substitute anything more
+    // complex than affine induction variables.  Doing so will put expensive
+    // polynomial evaluations inside of the loop, and the str reduction pass
+    // currently can only reduce affine polynomials.  For now just disable
+    // indvar subst on anything more complex than an affine addrec, unless
+    // it can be expanded to a trivial value.
+    if (!isSafe(AR, L, SE))
+      continue;
+
+    // Determine the insertion point for this user. By default, insert
+    // immediately before the user. The SCEVExpander class will automatically
+    // hoist loop invariants out of the loop. For PHI nodes, there may be
+    // multiple uses, so compute the nearest common dominator for the
+    // incoming blocks.
+    Instruction *InsertPt = getInsertPointForUses(User, Op, DT);
+
+    // Now expand it into actual Instructions and patch it into place.
+    Value *NewVal = Rewriter.expandCodeFor(AR, UseTy, InsertPt);
+
+    DEBUG(dbgs() << "INDVARS: Rewrote IV '" << *AR << "' " << *Op << '\n'
+                 << "   into = " << *NewVal << "\n");
+
+    if (!isValidRewrite(Op, NewVal)) {
+      DeadInsts.push_back(NewVal);
+      continue;
+    }
+    // Inform ScalarEvolution that this value is changing. The change doesn't
+    // affect its value, but it does potentially affect which use lists the
+    // value will be on after the replacement, which affects ScalarEvolution's
+    // ability to walk use lists and drop dangling pointers when a value is
+    // deleted.
+    SE->forgetValue(User);
+
+    // Patch the new value into place.
+    if (Op->hasName())
+      NewVal->takeName(Op);
+    if (Instruction *NewValI = dyn_cast<Instruction>(NewVal))
+      NewValI->setDebugLoc(User->getDebugLoc());
+    User->replaceUsesOfWith(Op, NewVal);
+    UI->setOperandValToReplace(NewVal);
+
+    ++NumRemoved;
+    Changed = true;
+
+    // The old value may be dead now.
+    DeadInsts.push_back(Op);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//  IV Widening - Extend the width of an IV to cover its widest uses.
+//===----------------------------------------------------------------------===//
+
+namespace {
+// Collect information about induction variables that are used by sign/zero
+// extend operations. This information is recorded by CollectExtend and
+// provides the input to WidenIV.
+struct WideIVInfo {
+  PHINode *NarrowIV;
+  Type *WidestNativeType; // Widest integer type created [sz]ext
+  bool IsSigned;          // Was an sext user seen before a zext?
+
+  WideIVInfo() : NarrowIV(0), WidestNativeType(0), IsSigned(false) {}
+};
+
+class WideIVVisitor : public IVVisitor {
+  ScalarEvolution *SE;
+  const DataLayout *TD;
+
+public:
+  WideIVInfo WI;
+
+  WideIVVisitor(PHINode *NarrowIV, ScalarEvolution *SCEV,
+                const DataLayout *TData)
+      : SE(SCEV), TD(TData) {
+    WI.NarrowIV = NarrowIV;
+  }
+
+  // Implement the interface used by simplifyUsersOfIV.
+  virtual void visitCast(CastInst *Cast);
+};
+}
+
+/// visitCast - Update information about the induction variable that is
+/// extended by this sign or zero extend operation. This is used to determine
+/// the final width of the IV before actually widening it.
+void WideIVVisitor::visitCast(CastInst *Cast) {
+  bool IsSigned = Cast->getOpcode() == Instruction::SExt;
+  if (!IsSigned && Cast->getOpcode() != Instruction::ZExt)
+    return;
+
+  Type *Ty = Cast->getType();
+  uint64_t Width = SE->getTypeSizeInBits(Ty);
+  if (TD && !TD->isLegalInteger(Width))
+    return;
+
+  if (!WI.WidestNativeType) {
+    WI.WidestNativeType = SE->getEffectiveSCEVType(Ty);
+    WI.IsSigned = IsSigned;
+    return;
+  }
+
+  // We extend the IV to satisfy the sign of its first user, arbitrarily.
+  if (WI.IsSigned != IsSigned)
+    return;
+
+  if (Width > SE->getTypeSizeInBits(WI.WidestNativeType))
+    WI.WidestNativeType = SE->getEffectiveSCEVType(Ty);
+}
+
+namespace {
+
+/// NarrowIVDefUse - Record a link in the Narrow IV def-use chain along with the
+/// WideIV that computes the same value as the Narrow IV def.  This avoids
+/// caching Use* pointers.
+struct NarrowIVDefUse {
+  Instruction *NarrowDef;
+  Instruction *NarrowUse;
+  Instruction *WideDef;
+
+  NarrowIVDefUse() : NarrowDef(0), NarrowUse(0), WideDef(0) {}
+
+  NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD)
+      : NarrowDef(ND), NarrowUse(NU), WideDef(WD) {}
+};
+
+/// WidenIV - The goal of this transform is to remove sign and zero extends
+/// without creating any new induction variables. To do this, it creates a new
+/// phi of the wider type and redirects all users, either removing extends or
+/// inserting truncs whenever we stop propagating the type.
+///
+class WidenIV {
+  // Parameters
+  PHINode *OrigPhi;
+  Type *WideType;
+  bool IsSigned;
+
+  // Context
+  LoopInfo *LI;
+  Loop *L;
+  ScalarEvolution *SE;
+  DominatorTree *DT;
+
+  // Result
+  PHINode *WidePhi;
+  Instruction *WideInc;
+  const SCEV *WideIncExpr;
+  SmallVectorImpl<WeakVH> &DeadInsts;
+
+  SmallPtrSet<Instruction *, 16> Widened;
+  SmallVector<NarrowIVDefUse, 8> NarrowIVUsers;
+
+public:
+  WidenIV(const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv,
+          DominatorTree *DTree, SmallVectorImpl<WeakVH> &DI)
+      : OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType),
+        IsSigned(WI.IsSigned), LI(LInfo),
+        L(LI->getLoopFor(OrigPhi->getParent())), SE(SEv), DT(DTree), WidePhi(0),
+        WideInc(0), WideIncExpr(0), DeadInsts(DI) {
+    assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV");
+  }
+
+  PHINode *CreateWideIV(SCEVExpander &Rewriter);
+
+protected:
+  Value *getExtend(Value *NarrowOper, Type *WideType, bool IsSigned,
+                   Instruction *Use);
+
+  Instruction *CloneIVUser(NarrowIVDefUse DU);
+
+  const SCEVAddRecExpr *GetWideRecurrence(Instruction *NarrowUse);
+
+  const SCEVAddRecExpr *GetExtendedOperandRecurrence(NarrowIVDefUse DU);
+
+  Instruction *WidenIVUse(NarrowIVDefUse DU, SCEVExpander &Rewriter);
+
+  void pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef);
+};
+} // anonymous namespace
+
+/// isLoopInvariant - Perform a quick domtree based check for loop invariance
+/// assuming that V is used within the loop. LoopInfo::isLoopInvariant() seems
+/// gratuitous for this purpose.
+static bool isLoopInvariant(Value *V, const Loop *L, const DominatorTree *DT) {
+  Instruction *Inst = dyn_cast<Instruction>(V);
+  if (!Inst)
+    return true;
+
+  return DT->properlyDominates(Inst->getParent(), L->getHeader());
+}
+
+Value *WidenIV::getExtend(Value *NarrowOper, Type *WideType, bool IsSigned,
+                          Instruction *Use) {
+  // Set the debug location and conservative insertion point.
+  IRBuilder<> Builder(Use);
+  // Hoist the insertion point into loop preheaders as far as possible.
+  for (const Loop *L = LI->getLoopFor(Use->getParent());
+       L && L->getLoopPreheader() && isLoopInvariant(NarrowOper, L, DT);
+       L = L->getParentLoop())
+    Builder.SetInsertPoint(L->getLoopPreheader()->getTerminator());
+
+  return IsSigned ? Builder.CreateSExt(NarrowOper, WideType)
+                  : Builder.CreateZExt(NarrowOper, WideType);
+}
+
+/// CloneIVUser - Instantiate a wide operation to replace a narrow
+/// operation. This only needs to handle operations that can evaluation to
+/// SCEVAddRec. It can safely return 0 for any operation we decide not to clone.
+Instruction *WidenIV::CloneIVUser(NarrowIVDefUse DU) {
+  unsigned Opcode = DU.NarrowUse->getOpcode();
+  switch (Opcode) {
+  default:
+    return 0;
+  case Instruction::Add:
+  case Instruction::Mul:
+  case Instruction::UDiv:
+  case Instruction::Sub:
+  case Instruction::And:
+  case Instruction::Or:
+  case Instruction::Xor:
+  case Instruction::Shl:
+  case Instruction::LShr:
+  case Instruction::AShr:
+    DEBUG(dbgs() << "Cloning IVUser: " << *DU.NarrowUse << "\n");
+
+    // Replace NarrowDef operands with WideDef. Otherwise, we don't know
+    // anything about the narrow operand yet so must insert a [sz]ext. It is
+    // probably loop invariant and will be folded or hoisted. If it actually
+    // comes from a widened IV, it should be removed during a future call to
+    // WidenIVUse.
+    Value *LHS = (DU.NarrowUse->getOperand(0) == DU.NarrowDef)
+                     ? DU.WideDef
+                     : getExtend(DU.NarrowUse->getOperand(0), WideType,
+                                 IsSigned, DU.NarrowUse);
+    Value *RHS = (DU.NarrowUse->getOperand(1) == DU.NarrowDef)
+                     ? DU.WideDef
+                     : getExtend(DU.NarrowUse->getOperand(1), WideType,
+                                 IsSigned, DU.NarrowUse);
+
+    BinaryOperator *NarrowBO = cast<BinaryOperator>(DU.NarrowUse);
+    BinaryOperator *WideBO = BinaryOperator::Create(NarrowBO->getOpcode(), LHS,
+                                                    RHS, NarrowBO->getName());
+    IRBuilder<> Builder(DU.NarrowUse);
+    Builder.Insert(WideBO);
+    if (const OverflowingBinaryOperator *OBO =
+            dyn_cast<OverflowingBinaryOperator>(NarrowBO)) {
+      if (OBO->hasNoUnsignedWrap())
+        WideBO->setHasNoUnsignedWrap();
+      if (OBO->hasNoSignedWrap())
+        WideBO->setHasNoSignedWrap();
+    }
+    return WideBO;
+  }
+  llvm_unreachable(0);
+}
+
+/// No-wrap operations can transfer sign extension of their result to their
+/// operands. Generate the SCEV value for the widened operation without
+/// actually modifying the IR yet. If the expression after extending the
+/// operands is an AddRec for this loop, return it.
+const SCEVAddRecExpr *WidenIV::GetExtendedOperandRecurrence(NarrowIVDefUse DU) {
+  // Handle the common case of add<nsw/nuw>
+  if (DU.NarrowUse->getOpcode() != Instruction::Add)
+    return 0;
+
+  // One operand (NarrowDef) has already been extended to WideDef. Now determine
+  // if extending the other will lead to a recurrence.
+  unsigned ExtendOperIdx = DU.NarrowUse->getOperand(0) == DU.NarrowDef ? 1 : 0;
+  assert(DU.NarrowUse->getOperand(1 - ExtendOperIdx) == DU.NarrowDef &&
+         "bad DU");
+
+  const SCEV *ExtendOperExpr = 0;
+  const OverflowingBinaryOperator *OBO =
+      cast<OverflowingBinaryOperator>(DU.NarrowUse);
+  if (IsSigned && OBO->hasNoSignedWrap())
+    ExtendOperExpr = SE->getSignExtendExpr(
+        SE->getSCEV(DU.NarrowUse->getOperand(ExtendOperIdx)), WideType);
+  else if (!IsSigned && OBO->hasNoUnsignedWrap())
+    ExtendOperExpr = SE->getZeroExtendExpr(
+        SE->getSCEV(DU.NarrowUse->getOperand(ExtendOperIdx)), WideType);
+  else
+    return 0;
+
+  // When creating this AddExpr, don't apply the current operations NSW or NUW
+  // flags. This instruction may be guarded by control flow that the no-wrap
+  // behavior depends on. Non-control-equivalent instructions can be mapped to
+  // the same SCEV expression, and it would be incorrect to transfer NSW/NUW
+  // semantics to those operations.
+  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(
+      SE->getAddExpr(SE->getSCEV(DU.WideDef), ExtendOperExpr));
+
+  if (!AddRec || AddRec->getLoop() != L)
+    return 0;
+  return AddRec;
+}
+
+/// GetWideRecurrence - Is this instruction potentially interesting from
+/// IVUsers' perspective after widening it's type? In other words, can the
+/// extend be safely hoisted out of the loop with SCEV reducing the value to a
+/// recurrence on the same loop. If so, return the sign or zero extended
+/// recurrence. Otherwise return nullptr.
+const SCEVAddRecExpr *WidenIV::GetWideRecurrence(Instruction *NarrowUse) {
+  if (!SE->isSCEVable(NarrowUse->getType()))
+    return 0;
+
+  const SCEV *NarrowExpr = SE->getSCEV(NarrowUse);
+  if (SE->getTypeSizeInBits(NarrowExpr->getType()) >=
+      SE->getTypeSizeInBits(WideType)) {
+    // NarrowUse implicitly widens its operand. e.g. a gep with a narrow
+    // index. So don't follow this use.
+    return 0;
+  }
+
+  const SCEV *WideExpr = IsSigned ? SE->getSignExtendExpr(NarrowExpr, WideType)
+                                  : SE->getZeroExtendExpr(NarrowExpr, WideType);
+  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(WideExpr);
+  if (!AddRec || AddRec->getLoop() != L)
+    return 0;
+  return AddRec;
+}
+
+/// WidenIVUse - Determine whether an individual user of the narrow IV can be
+/// widened. If so, return the wide clone of the user.
+Instruction *WidenIV::WidenIVUse(NarrowIVDefUse DU, SCEVExpander &Rewriter) {
+  // Stop traversing the def-use chain at inner-loop phis or post-loop phis.
+  if (isa<PHINode>(DU.NarrowUse) &&
+      LI->getLoopFor(DU.NarrowUse->getParent()) != L)
+    return 0;
+
+  // Our raison d'etre! Eliminate sign and zero extension.
+  if (IsSigned ? isa<SExtInst>(DU.NarrowUse) : isa<ZExtInst>(DU.NarrowUse)) {
+    Value *NewDef = DU.WideDef;
+    if (DU.NarrowUse->getType() != WideType) {
+      unsigned CastWidth = SE->getTypeSizeInBits(DU.NarrowUse->getType());
+      unsigned IVWidth = SE->getTypeSizeInBits(WideType);
+      if (CastWidth < IVWidth) {
+        // The cast isn't as wide as the IV, so insert a Trunc.
+        IRBuilder<> Builder(DU.NarrowUse);
+        NewDef = Builder.CreateTrunc(DU.WideDef, DU.NarrowUse->getType());
+      } else {
+        // A wider extend was hidden behind a narrower one. This may induce
+        // another round of IV widening in which the intermediate IV becomes
+        // dead. It should be very rare.
+        DEBUG(dbgs() << "INDVARS: New IV " << *WidePhi
+                     << " not wide enough to subsume " << *DU.NarrowUse
+                     << "\n");
+        DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, DU.WideDef);
+        NewDef = DU.NarrowUse;
+      }
+    }
+    if (NewDef != DU.NarrowUse) {
+      DEBUG(dbgs() << "INDVARS: eliminating " << *DU.NarrowUse
+                   << " replaced by " << *DU.WideDef << "\n");
+      ++NumElimExt;
+      DU.NarrowUse->replaceAllUsesWith(NewDef);
+      DeadInsts.push_back(DU.NarrowUse);
+    }
+    // Now that the extend is gone, we want to expose it's uses for potential
+    // further simplification. We don't need to directly inform SimplifyIVUsers
+    // of the new users, because their parent IV will be processed later as a
+    // new loop phi. If we preserved IVUsers analysis, we would also want to
+    // push the uses of WideDef here.
+
+    // No further widening is needed. The deceased [sz]ext had done it for us.
+    return 0;
+  }
+
+  // Does this user itself evaluate to a recurrence after widening?
+  const SCEVAddRecExpr *WideAddRec = GetWideRecurrence(DU.NarrowUse);
+  if (!WideAddRec) {
+    WideAddRec = GetExtendedOperandRecurrence(DU);
+  }
+  if (!WideAddRec) {
+    // This user does not evaluate to a recurence after widening, so don't
+    // follow it. Instead insert a Trunc to kill off the original use,
+    // eventually isolating the original narrow IV so it can be removed.
+    IRBuilder<> Builder(getInsertPointForUses(DU.NarrowUse, DU.NarrowDef, DT));
+    Value *Trunc = Builder.CreateTrunc(DU.WideDef, DU.NarrowDef->getType());
+    DU.NarrowUse->replaceUsesOfWith(DU.NarrowDef, Trunc);
+    return 0;
+  }
+  // Assume block terminators cannot evaluate to a recurrence. We can't to
+  // insert a Trunc after a terminator if there happens to be a critical edge.
+  assert(DU.NarrowUse != DU.NarrowUse->getParent()->getTerminator() &&
+         "SCEV is not expected to evaluate a block terminator");
+
+  // Reuse the IV increment that SCEVExpander created as long as it dominates
+  // NarrowUse.
+  Instruction *WideUse = 0;
+  if (WideAddRec == WideIncExpr && Rewriter.hoistIVInc(WideInc, DU.NarrowUse))
+    WideUse = WideInc;
+  else {
+    WideUse = CloneIVUser(DU);
+    if (!WideUse)
+      return 0;
+  }
+  // Evaluation of WideAddRec ensured that the narrow expression could be
+  // extended outside the loop without overflow. This suggests that the wide use
+  // evaluates to the same expression as the extended narrow use, but doesn't
+  // absolutely guarantee it. Hence the following failsafe check. In rare cases
+  // where it fails, we simply throw away the newly created wide use.
+  if (WideAddRec != SE->getSCEV(WideUse)) {
+    DEBUG(dbgs() << "Wide use expression mismatch: " << *WideUse << ": "
+                 << *SE->getSCEV(WideUse) << " != " << *WideAddRec << "\n");
+    DeadInsts.push_back(WideUse);
+    return 0;
+  }
+
+  // Returning WideUse pushes it on the worklist.
+  return WideUse;
+}
+
+/// pushNarrowIVUsers - Add eligible users of NarrowDef to NarrowIVUsers.
+///
+void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
+  for (User *U : NarrowDef->users()) {
+    Instruction *NarrowUser = cast<Instruction>(U);
+
+    // Handle data flow merges and bizarre phi cycles.
+    if (!Widened.insert(NarrowUser))
+      continue;
+
+    NarrowIVUsers.push_back(NarrowIVDefUse(NarrowDef, NarrowUser, WideDef));
+  }
+}
+
+/// CreateWideIV - Process a single induction variable. First use the
+/// SCEVExpander to create a wide induction variable that evaluates to the same
+/// recurrence as the original narrow IV. Then use a worklist to forward
+/// traverse the narrow IV's def-use chain. After WidenIVUse has processed all
+/// interesting IV users, the narrow IV will be isolated for removal by
+/// DeleteDeadPHIs.
+///
+/// It would be simpler to delete uses as they are processed, but we must avoid
+/// invalidating SCEV expressions.
+///
+PHINode *WidenIV::CreateWideIV(SCEVExpander &Rewriter) {
+  // Is this phi an induction variable?
+  const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(OrigPhi));
+  if (!AddRec)
+    return nullptr;
+
+  // Widen the induction variable expression.
+  const SCEV *WideIVExpr = IsSigned ? SE->getSignExtendExpr(AddRec, WideType)
+                                    : SE->getZeroExtendExpr(AddRec, WideType);
+
+  assert(SE->getEffectiveSCEVType(WideIVExpr->getType()) == WideType &&
+         "Expect the new IV expression to preserve its type");
+
+  // Can the IV be extended outside the loop without overflow?
+  AddRec = dyn_cast<SCEVAddRecExpr>(WideIVExpr);
+  if (!AddRec || AddRec->getLoop() != L)
+    return nullptr;
+
+  // An AddRec must have loop-invariant operands. Since this AddRec is
+  // materialized by a loop header phi, the expression cannot have any post-loop
+  // operands, so they must dominate the loop header.
+  assert(
+      SE->properlyDominates(AddRec->getStart(), L->getHeader()) &&
+      SE->properlyDominates(AddRec->getStepRecurrence(*SE), L->getHeader()) &&
+      "Loop header phi recurrence inputs do not dominate the loop");
+
+  // The rewriter provides a value for the desired IV expression. This may
+  // either find an existing phi or materialize a new one. Either way, we
+  // expect a well-formed cyclic phi-with-increments. i.e. any operand not part
+  // of the phi-SCC dominates the loop entry.
+  Instruction *InsertPt = L->getHeader()->begin();
+  WidePhi = cast<PHINode>(Rewriter.expandCodeFor(AddRec, WideType, InsertPt));
+
+  // Remembering the WideIV increment generated by SCEVExpander allows
+  // WidenIVUse to reuse it when widening the narrow IV's increment. We don't
+  // employ a general reuse mechanism because the call above is the only call to
+  // SCEVExpander. Henceforth, we produce 1-to-1 narrow to wide uses.
+  if (BasicBlock *LatchBlock = L->getLoopLatch()) {
+    WideInc = cast<Instruction>(WidePhi->getIncomingValueForBlock(LatchBlock));
+    WideIncExpr = SE->getSCEV(WideInc);
+  }
+
+  DEBUG(dbgs() << "Wide IV: " << *WidePhi << "\n");
+  ++NumWidened;
+
+  // Traverse the def-use chain using a worklist starting at the original IV.
+  assert(Widened.empty() && NarrowIVUsers.empty() && "expect initial state");
+
+  Widened.insert(OrigPhi);
+  pushNarrowIVUsers(OrigPhi, WidePhi);
+
+  while (!NarrowIVUsers.empty()) {
+    NarrowIVDefUse DU = NarrowIVUsers.pop_back_val();
+
+    // Process a def-use edge. This may replace the use, so don't hold a
+    // use_iterator across it.
+    Instruction *WideUse = WidenIVUse(DU, Rewriter);
+
+    // Follow all def-use edges from the previous narrow use.
+    if (WideUse)
+      pushNarrowIVUsers(DU.NarrowUse, WideUse);
+
+    // WidenIVUse may have removed the def-use edge.
+    if (DU.NarrowDef->use_empty())
+      DeadInsts.push_back(DU.NarrowDef);
+  }
+  return WidePhi;
+}
+
+//===----------------------------------------------------------------------===//
+//  Simplification of IV users based on SCEV evaluation.
+//===----------------------------------------------------------------------===//
+
+/// SimplifyAndExtend - Iteratively perform simplification on a worklist of IV
+/// users. Each successive simplification may push more users which may
+/// themselves be candidates for simplification.
+///
+/// Sign/Zero extend elimination is interleaved with IV simplification.
+///
+void PollyIndVarSimplify::SimplifyAndExtend(Loop *L, SCEVExpander &Rewriter,
+                                            LPPassManager &LPM) {
+  SmallVector<WideIVInfo, 8> WideIVs;
+
+  SmallVector<PHINode *, 8> LoopPhis;
+  for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) {
+    LoopPhis.push_back(cast<PHINode>(I));
+  }
+  // Each round of simplification iterates through the SimplifyIVUsers worklist
+  // for all current phis, then determines whether any IVs can be
+  // widened. Widening adds new phis to LoopPhis, inducing another round of
+  // simplification on the wide IVs.
+  while (!LoopPhis.empty()) {
+    // Evaluate as many IV expressions as possible before widening any IVs. This
+    // forces SCEV to set no-wrap flags before evaluating sign/zero
+    // extension. The first time SCEV attempts to normalize sign/zero extension,
+    // the result becomes final. So for the most predictable results, we delay
+    // evaluation of sign/zero extend evaluation until needed, and avoid running
+    // other SCEV based analysis prior to SimplifyAndExtend.
+    do {
+      PHINode *CurrIV = LoopPhis.pop_back_val();
+
+      // Information about sign/zero extensions of CurrIV.
+      WideIVVisitor WIV(CurrIV, SE, TD);
+
+      Changed |= simplifyUsersOfIV(CurrIV, SE, &LPM, DeadInsts, &WIV);
+
+      if (WIV.WI.WidestNativeType) {
+        WideIVs.push_back(WIV.WI);
+      }
+    } while (!LoopPhis.empty());
+
+    for (; !WideIVs.empty(); WideIVs.pop_back()) {
+      WidenIV Widener(WideIVs.back(), LI, SE, DT, DeadInsts);
+      if (PHINode *WidePhi = Widener.CreateWideIV(Rewriter)) {
+        Changed = true;
+        LoopPhis.push_back(WidePhi);
+      }
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//  LinearFunctionTestReplace and its kin. Rewrite the loop exit condition.
+//===----------------------------------------------------------------------===//
+
+/// Check for expressions that ScalarEvolution generates to compute
+/// BackedgeTakenInfo. If these expressions have not been reduced, then
+/// expanding them may incur additional cost (albeit in the loop preheader).
+static bool isHighCostExpansion(const SCEV *S, BranchInst *BI,
+                                SmallPtrSet<const SCEV *, 8> &Processed,
+                                ScalarEvolution *SE) {
+  if (!Processed.insert(S))
+    return false;
+
+  // If the backedge-taken count is a UDiv, it's very likely a UDiv that
+  // ScalarEvolution's HowFarToZero or HowManyLessThans produced to compute a
+  // precise expression, rather than a UDiv from the user's code. If we can't
+  // find a UDiv in the code with some simple searching, assume the former and
+  // forego rewriting the loop.
+  if (isa<SCEVUDivExpr>(S)) {
+    ICmpInst *OrigCond = dyn_cast<ICmpInst>(BI->getCondition());
+    if (!OrigCond)
+      return true;
+    const SCEV *R = SE->getSCEV(OrigCond->getOperand(1));
+    R = SE->getMinusSCEV(R, SE->getConstant(R->getType(), 1));
+    if (R != S) {
+      const SCEV *L = SE->getSCEV(OrigCond->getOperand(0));
+      L = SE->getMinusSCEV(L, SE->getConstant(L->getType(), 1));
+      if (L != S)
+        return true;
+    }
+  }
+
+  if (EnableIVRewrite)
+    return false;
+
+  // Recurse past add expressions, which commonly occur in the
+  // BackedgeTakenCount. They may already exist in program code, and if not,
+  // they are not too expensive rematerialize.
+  if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(S)) {
+    for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end();
+         I != E; ++I) {
+      if (isHighCostExpansion(*I, BI, Processed, SE))
+        return true;
+    }
+    return false;
+  }
+
+  // HowManyLessThans uses a Max expression whenever the loop is not guarded by
+  // the exit condition.
+  if (isa<SCEVSMaxExpr>(S) || isa<SCEVUMaxExpr>(S))
+    return true;
+
+  // If we haven't recognized an expensive SCEV pattern, assume it's an
+  // expression produced by program code.
+  return false;
+}
+
+/// canExpandBackedgeTakenCount - Return true if this loop's backedge taken
+/// count expression can be safely and cheaply expanded into an instruction
+/// sequence that can be used by LinearFunctionTestReplace.
+///
+/// TODO: This fails for pointer-type loop counters with greater than one byte
+/// strides, consequently preventing LFTR from running. For the purpose of LFTR
+/// we could skip this check in the case that the LFTR loop counter (chosen by
+/// FindLoopCounter) is also pointer type. Instead, we could directly convert
+/// the loop test to an inequality test by checking the target data's alignment
+/// of element types (given that the initial pointer value originates from or is
+/// used by ABI constrained operation, as opposed to inttoptr/ptrtoint).
+/// However, we don't yet have a strong motivation for converting loop tests
+/// into inequality tests.
+static bool canExpandBackedgeTakenCount(Loop *L, ScalarEvolution *SE) {
+  const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
+  if (isa<SCEVCouldNotCompute>(BackedgeTakenCount) ||
+      BackedgeTakenCount->isZero())
+    return false;
+
+  if (!L->getExitingBlock())
+    return false;
+
+  // Can't rewrite non-branch yet.
+  BranchInst *BI = dyn_cast<BranchInst>(L->getExitingBlock()->getTerminator());
+  if (!BI)
+    return false;
+
+  SmallPtrSet<const SCEV *, 8> Processed;
+  if (isHighCostExpansion(BackedgeTakenCount, BI, Processed, SE))
+    return false;
+
+  return true;
+}
+
+/// getBackedgeIVType - Get the widest type used by the loop test after peeking
+/// through Truncs.
+///
+/// TODO: Unnecessary when ForceLFTR is removed.
+static Type *getBackedgeIVType(Loop *L) {
+  if (!L->getExitingBlock())
+    return 0;
+
+  // Can't rewrite non-branch yet.
+  BranchInst *BI = dyn_cast<BranchInst>(L->getExitingBlock()->getTerminator());
+  if (!BI)
+    return 0;
+
+  ICmpInst *Cond = dyn_cast<ICmpInst>(BI->getCondition());
+  if (!Cond)
+    return 0;
+
+  Type *Ty = 0;
+  for (User::op_iterator OI = Cond->op_begin(), OE = Cond->op_end(); OI != OE;
+       ++OI) {
+    assert((!Ty || Ty == (*OI)->getType()) && "bad icmp operand types");
+    TruncInst *Trunc = dyn_cast<TruncInst>(*OI);
+    if (!Trunc)
+      continue;
+
+    return Trunc->getSrcTy();
+  }
+  return Ty;
+}
+
+/// getLoopPhiForCounter - Return the loop header phi IFF IncV adds a loop
+/// invariant value to the phi.
+static PHINode *getLoopPhiForCounter(Value *IncV, Loop *L, DominatorTree *DT) {
+  Instruction *IncI = dyn_cast<Instruction>(IncV);
+  if (!IncI)
+    return 0;
+
+  switch (IncI->getOpcode()) {
+  case Instruction::Add:
+  case Instruction::Sub:
+    break;
+  case Instruction::GetElementPtr:
+    // An IV counter must preserve its type.
+    if (IncI->getNumOperands() == 2)
+      break;
+  default:
+    return 0;
+  }
+
+  PHINode *Phi = dyn_cast<PHINode>(IncI->getOperand(0));
+  if (Phi && Phi->getParent() == L->getHeader()) {
+    if (isLoopInvariant(IncI->getOperand(1), L, DT))
+      return Phi;
+    return 0;
+  }
+  if (IncI->getOpcode() == Instruction::GetElementPtr)
+    return 0;
+
+  // Allow add/sub to be commuted.
+  Phi = dyn_cast<PHINode>(IncI->getOperand(1));
+  if (Phi && Phi->getParent() == L->getHeader()) {
+    if (isLoopInvariant(IncI->getOperand(0), L, DT))
+      return Phi;
+  }
+  return 0;
+}
+
+/// needsLFTR - LinearFunctionTestReplace policy. Return true unless we can show
+/// that the current exit test is already sufficiently canonical.
+static bool needsLFTR(Loop *L, DominatorTree *DT) {
+  assert(L->getExitingBlock() && "expected loop exit");
+
+  BasicBlock *LatchBlock = L->getLoopLatch();
+  // Don't bother with LFTR if the loop is not properly simplified.
+  if (!LatchBlock)
+    return false;
+
+  BranchInst *BI = dyn_cast<BranchInst>(L->getExitingBlock()->getTerminator());
+  assert(BI && "expected exit branch");
+
+  // Do LFTR to simplify the exit condition to an ICMP.
+  ICmpInst *Cond = dyn_cast<ICmpInst>(BI->getCondition());
+  if (!Cond)
+    return true;
+
+  // Do LFTR to simplify the exit ICMP to EQ/NE
+  ICmpInst::Predicate Pred = Cond->getPredicate();
+  if (Pred != ICmpInst::ICMP_NE && Pred != ICmpInst::ICMP_EQ)
+    return true;
+
+  // Look for a loop invariant RHS
+  Value *LHS = Cond->getOperand(0);
+  Value *RHS = Cond->getOperand(1);
+  if (!isLoopInvariant(RHS, L, DT)) {
+    if (!isLoopInvariant(LHS, L, DT))
+      return true;
+    std::swap(LHS, RHS);
+  }
+  // Look for a simple IV counter LHS
+  PHINode *Phi = dyn_cast<PHINode>(LHS);
+  if (!Phi)
+    Phi = getLoopPhiForCounter(LHS, L, DT);
+
+  if (!Phi)
+    return true;
+
+  // Do LFTR if the exit condition's IV is *not* a simple counter.
+  Value *IncV = Phi->getIncomingValueForBlock(L->getLoopLatch());
+  return Phi != getLoopPhiForCounter(IncV, L, DT);
+}
+
+/// AlmostDeadIV - Return true if this IV has any uses other than the (soon to
+/// be rewritten) loop exit test.
+static bool AlmostDeadIV(PHINode *Phi, BasicBlock *LatchBlock, Value *Cond) {
+  int LatchIdx = Phi->getBasicBlockIndex(LatchBlock);
+  Value *IncV = Phi->getIncomingValue(LatchIdx);
+
+  for (User *U : Phi->users())
+    if (U != Cond && U != IncV)
+      return false;
+
+  for (User *U : IncV->users())
+    if (U != Cond && U != Phi)
+      return false;
+
+  return true;
+}
+
+/// FindLoopCounter - Find an affine IV in canonical form.
+///
+/// BECount may be an i8* pointer type. The pointer difference is already
+/// valid count without scaling the address stride, so it remains a pointer
+/// expression as far as SCEV is concerned.
+///
+/// FIXME: Accept -1 stride and set IVLimit = IVInit - BECount
+///
+/// FIXME: Accept non-unit stride as long as SCEV can reduce BECount * Stride.
+/// This is difficult in general for SCEV because of potential overflow. But we
+/// could at least handle constant BECounts.
+static PHINode *FindLoopCounter(Loop *L, const SCEV *BECount,
+                                ScalarEvolution *SE, DominatorTree *DT,
+                                const DataLayout *TD) {
+  uint64_t BCWidth = SE->getTypeSizeInBits(BECount->getType());
+
+  Value *Cond =
+      cast<BranchInst>(L->getExitingBlock()->getTerminator())->getCondition();
+
+  // Loop over all of the PHI nodes, looking for a simple counter.
+  PHINode *BestPhi = 0;
+  const SCEV *BestInit = 0;
+  BasicBlock *LatchBlock = L->getLoopLatch();
+  assert(LatchBlock && "needsLFTR should guarantee a loop latch");
+
+  for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) {
+    PHINode *Phi = cast<PHINode>(I);
+    if (!SE->isSCEVable(Phi->getType()))
+      continue;
+
+    // Avoid comparing an integer IV against a pointer Limit.
+    if (BECount->getType()->isPointerTy() && !Phi->getType()->isPointerTy())
+      continue;
+
+    const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(Phi));
+    if (!AR || AR->getLoop() != L || !AR->isAffine())
+      continue;
+
+    // AR may be a pointer type, while BECount is an integer type.
+    // AR may be wider than BECount. With eq/ne tests overflow is immaterial.
+    // AR may not be a narrower type, or we may never exit.
+    uint64_t PhiWidth = SE->getTypeSizeInBits(AR->getType());
+    if (PhiWidth < BCWidth || (TD && !TD->isLegalInteger(PhiWidth)))
+      continue;
+
+    const SCEV *Step = dyn_cast<SCEVConstant>(AR->getStepRecurrence(*SE));
+    if (!Step || !Step->isOne())
+      continue;
+
+    int LatchIdx = Phi->getBasicBlockIndex(LatchBlock);
+    Value *IncV = Phi->getIncomingValue(LatchIdx);
+    if (getLoopPhiForCounter(IncV, L, DT) != Phi)
+      continue;
+
+    const SCEV *Init = AR->getStart();
+
+    if (BestPhi && !AlmostDeadIV(BestPhi, LatchBlock, Cond)) {
+      // Don't force a live loop counter if another IV can be used.
+      if (AlmostDeadIV(Phi, LatchBlock, Cond))
+        continue;
+
+      // Prefer to count-from-zero. This is a more "canonical" counter form. It
+      // also prefers integer to pointer IVs.
+      if (BestInit->isZero() != Init->isZero()) {
+        if (BestInit->isZero())
+          continue;
+      }
+      // If two IVs both count from zero or both count from nonzero then the
+      // narrower is likely a dead phi that has been widened. Use the wider phi
+      // to allow the other to be eliminated.
+      if (PhiWidth <= SE->getTypeSizeInBits(BestPhi->getType()))
+        continue;
+    }
+    BestPhi = Phi;
+    BestInit = Init;
+  }
+  return BestPhi;
+}
+
+/// genLoopLimit - Help LinearFunctionTestReplace by generating a value that
+/// holds the RHS of the new loop test.
+static Value *genLoopLimit(PHINode *IndVar, const SCEV *IVCount, Loop *L,
+                           SCEVExpander &Rewriter, ScalarEvolution *SE) {
+  const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(SE->getSCEV(IndVar));
+  assert(AR && AR->getLoop() == L && AR->isAffine() && "bad loop counter");
+  const SCEV *IVInit = AR->getStart();
+
+  // IVInit may be a pointer while IVCount is an integer when FindLoopCounter
+  // finds a valid pointer IV. Sign extend BECount in order to materialize a
+  // GEP. Avoid running SCEVExpander on a new pointer value, instead reusing
+  // the existing GEPs whenever possible.
+  if (IndVar->getType()->isPointerTy() && !IVCount->getType()->isPointerTy()) {
+    Type *OfsTy = SE->getEffectiveSCEVType(IVInit->getType());
+    const SCEV *IVOffset = SE->getTruncateOrSignExtend(IVCount, OfsTy);
+
+    // Expand the code for the iteration count.
+    assert(SE->isLoopInvariant(IVOffset, L) &&
+           "Computed iteration count is not loop invariant!");
+    BranchInst *BI = cast<BranchInst>(L->getExitingBlock()->getTerminator());
+    Value *GEPOffset = Rewriter.expandCodeFor(IVOffset, OfsTy, BI);
+
+    Value *GEPBase = IndVar->getIncomingValueForBlock(L->getLoopPreheader());
+    assert(AR->getStart() == SE->getSCEV(GEPBase) && "bad loop counter");
+    // We could handle pointer IVs other than i8*, but we need to compensate for
+    // gep index scaling. See canExpandBackedgeTakenCount comments.
+    assert(SE->getSizeOfExpr(IntegerType::getInt64Ty(IndVar->getContext()),
+                             cast<PointerType>(GEPBase->getType())
+                                 ->getElementType())->isOne() &&
+           "unit stride pointer IV must be i8*");
+
+    IRBuilder<> Builder(L->getLoopPreheader()->getTerminator());
+    return Builder.CreateGEP(GEPBase, GEPOffset, "lftr.limit");
+  } else {
+    // In any other case, convert both IVInit and IVCount to integers before
+    // comparing. This may result in SCEV expension of pointers, but in practice
+    // SCEV will fold the pointer arithmetic away as such:
+    // BECount = (IVEnd - IVInit - 1) => IVLimit = IVInit (postinc).
+    //
+    // Valid Cases: (1) both integers is most common; (2) both may be pointers
+    // for simple memset-style loops; (3) IVInit is an integer and IVCount is a
+    // pointer may occur when enable-iv-rewrite generates a canonical IV on top
+    // of case #2.
+
+    const SCEV *IVLimit = 0;
+    // For unit stride, IVCount = Start + BECount with 2's complement overflow.
+    // For non-zero Start, compute IVCount here.
+    if (AR->getStart()->isZero())
+      IVLimit = IVCount;
+    else {
+      assert(AR->getStepRecurrence(*SE)->isOne() && "only handles unit stride");
+      const SCEV *IVInit = AR->getStart();
+
+      // For integer IVs, truncate the IV before computing IVInit + BECount.
+      if (SE->getTypeSizeInBits(IVInit->getType()) >
+          SE->getTypeSizeInBits(IVCount->getType()))
+        IVInit = SE->getTruncateExpr(IVInit, IVCount->getType());
+
+      IVLimit = SE->getAddExpr(IVInit, IVCount);
+    }
+    // Expand the code for the iteration count.
+    BranchInst *BI = cast<BranchInst>(L->getExitingBlock()->getTerminator());
+    IRBuilder<> Builder(BI);
+    assert(SE->isLoopInvariant(IVLimit, L) &&
+           "Computed iteration count is not loop invariant!");
+    // Ensure that we generate the same type as IndVar, or a smaller integer
+    // type. In the presence of null pointer values, we have an integer type
+    // SCEV expression (IVInit) for a pointer type IV value (IndVar).
+    Type *LimitTy = IVCount->getType()->isPointerTy() ? IndVar->getType()
+                                                      : IVCount->getType();
+    return Rewriter.expandCodeFor(IVLimit, LimitTy, BI);
+  }
+}
+
+/// LinearFunctionTestReplace - This method rewrites the exit condition of the
+/// loop to be a canonical != comparison against the incremented loop induction
+/// variable.  This pass is able to rewrite the exit tests of any loop where the
+/// SCEV analysis can determine a loop-invariant trip count of the loop, which
+/// is actually a much broader range than just linear tests.
+Value *PollyIndVarSimplify::LinearFunctionTestReplace(
+    Loop *L, const SCEV *BackedgeTakenCount, PHINode *IndVar,
+    SCEVExpander &Rewriter) {
+  assert(canExpandBackedgeTakenCount(L, SE) && "precondition");
+
+  // LFTR can ignore IV overflow and truncate to the width of
+  // BECount. This avoids materializing the add(zext(add)) expression.
+  Type *CntTy =
+      !EnableIVRewrite ? BackedgeTakenCount->getType() : IndVar->getType();
+
+  const SCEV *IVCount = BackedgeTakenCount;
+
+  // If the exiting block is the same as the backedge block, we prefer to
+  // compare against the post-incremented value, otherwise we must compare
+  // against the preincremented value.
+  Value *CmpIndVar;
+  if (L->getExitingBlock() == L->getLoopLatch()) {
+    // Add one to the "backedge-taken" count to get the trip count.
+    // If this addition may overflow, we have to be more pessimistic and
+    // cast the induction variable before doing the add.
+    const SCEV *N =
+        SE->getAddExpr(IVCount, SE->getConstant(IVCount->getType(), 1));
+    if (CntTy == IVCount->getType())
+      IVCount = N;
+    else {
+      const SCEV *Zero = SE->getConstant(IVCount->getType(), 0);
+      if ((isa<SCEVConstant>(N) && !N->isZero()) ||
+          SE->isLoopEntryGuardedByCond(L, ICmpInst::ICMP_NE, N, Zero)) {
+        // No overflow. Cast the sum.
+        IVCount = SE->getTruncateOrZeroExtend(N, CntTy);
+      } else {
+        // Potential overflow. Cast before doing the add.
+        IVCount = SE->getTruncateOrZeroExtend(IVCount, CntTy);
+        IVCount = SE->getAddExpr(IVCount, SE->getConstant(CntTy, 1));
+      }
+    }
+    // The BackedgeTaken expression contains the number of times that the
+    // backedge branches to the loop header.  This is one less than the
+    // number of times the loop executes, so use the incremented indvar.
+    CmpIndVar = IndVar->getIncomingValueForBlock(L->getExitingBlock());
+  } else {
+    // We must use the preincremented value...
+    IVCount = SE->getTruncateOrZeroExtend(IVCount, CntTy);
+    CmpIndVar = IndVar;
+  }
+
+  Value *ExitCnt = genLoopLimit(IndVar, IVCount, L, Rewriter, SE);
+  assert(ExitCnt->getType()->isPointerTy() ==
+             IndVar->getType()->isPointerTy() &&
+         "genLoopLimit missed a cast");
+
+  // Insert a new icmp_ne or icmp_eq instruction before the branch.
+  BranchInst *BI = cast<BranchInst>(L->getExitingBlock()->getTerminator());
+  ICmpInst::Predicate P;
+  if (L->contains(BI->getSuccessor(0)))
+    P = ICmpInst::ICMP_NE;
+  else
+    P = ICmpInst::ICMP_EQ;
+
+  DEBUG(dbgs() << "INDVARS: Rewriting loop exit condition to:\n"
+               << "      LHS:" << *CmpIndVar << '\n' << "       op:\t"
+               << (P == ICmpInst::ICMP_NE ? "!=" : "==") << "\n"
+               << "      RHS:\t" << *ExitCnt << "\n"
+               << "  IVCount:\t" << *IVCount << "\n");
+
+  IRBuilder<> Builder(BI);
+  if (SE->getTypeSizeInBits(CmpIndVar->getType()) >
+      SE->getTypeSizeInBits(ExitCnt->getType())) {
+    CmpIndVar =
+        Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(), "lftr.wideiv");
+  }
+
+  Value *Cond = Builder.CreateICmp(P, CmpIndVar, ExitCnt, "exitcond");
+  Value *OrigCond = BI->getCondition();
+  // It's tempting to use replaceAllUsesWith here to fully replace the old
+  // comparison, but that's not immediately safe, since users of the old
+  // comparison may not be dominated by the new comparison. Instead, just
+  // update the branch to use the new comparison; in the common case this
+  // will make old comparison dead.
+  BI->setCondition(Cond);
+  DeadInsts.push_back(OrigCond);
+
+  ++NumLFTR;
+  Changed = true;
+  return Cond;
+}
+
+//===----------------------------------------------------------------------===//
+//  SinkUnusedInvariants. A late subpass to cleanup loop preheaders.
+//===----------------------------------------------------------------------===//
+
+/// If there's a single exit block, sink any loop-invariant values that
+/// were defined in the preheader but not used inside the loop into the
+/// exit block to reduce register pressure in the loop.
+void PollyIndVarSimplify::SinkUnusedInvariants(Loop *L) {
+  BasicBlock *ExitBlock = L->getExitBlock();
+  if (!ExitBlock)
+    return;
+
+  BasicBlock *Preheader = L->getLoopPreheader();
+  if (!Preheader)
+    return;
+
+  Instruction *InsertPt = ExitBlock->getFirstInsertionPt();
+  BasicBlock::iterator I = Preheader->getTerminator();
+  while (I != Preheader->begin()) {
+    --I;
+    // New instructions were inserted at the end of the preheader.
+    if (isa<PHINode>(I))
+      break;
+
+    // Don't move instructions which might have side effects, since the side
+    // effects need to complete before instructions inside the loop.  Also don't
+    // move instructions which might read memory, since the loop may modify
+    // memory. Note that it's okay if the instruction might have undefined
+    // behavior: LoopSimplify guarantees that the preheader dominates the exit
+    // block.
+    if (I->mayHaveSideEffects() || I->mayReadFromMemory())
+      continue;
+
+    // Skip debug info intrinsics.
+    if (isa<DbgInfoIntrinsic>(I))
+      continue;
+
+    // Skip landingpad instructions.
+    if (isa<LandingPadInst>(I))
+      continue;
+
+    // Don't sink alloca: we never want to sink static alloca's out of the
+    // entry block, and correctly sinking dynamic alloca's requires
+    // checks for stacksave/stackrestore intrinsics.
+    // FIXME: Refactor this check somehow?
+    if (isa<AllocaInst>(I))
+      continue;
+
+    // Determine if there is a use in or before the loop (direct or
+    // otherwise).
+    bool UsedInLoop = false;
+    for (Use &U : I->uses()) {
+      Instruction *UI = cast<Instruction>(U.getUser());
+      BasicBlock *UseBB = UI->getParent();
+      if (PHINode *P = dyn_cast<PHINode>(UI)) {
+        unsigned i = PHINode::getIncomingValueNumForOperand(U.getOperandNo());
+        UseBB = P->getIncomingBlock(i);
+      }
+      if (UseBB == Preheader || L->contains(UseBB)) {
+        UsedInLoop = true;
+        break;
+      }
+    }
+
+    // If there is, the def must remain in the preheader.
+    if (UsedInLoop)
+      continue;
+
+    // Otherwise, sink it to the exit block.
+    Instruction *ToMove = I;
+    bool Done = false;
+
+    if (I != Preheader->begin()) {
+      // Skip debug info intrinsics.
+      do {
+        --I;
+      } while (isa<DbgInfoIntrinsic>(I) && I != Preheader->begin());
+
+      if (isa<DbgInfoIntrinsic>(I) && I == Preheader->begin())
+        Done = true;
+    } else {
+      Done = true;
+    }
+
+    ToMove->moveBefore(InsertPt);
+    if (Done)
+      break;
+    InsertPt = ToMove;
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//  IndVarSimplify driver. Manage several subpasses of IV simplification.
+//===----------------------------------------------------------------------===//
+
+bool PollyIndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
+  // If LoopSimplify form is not available, stay out of trouble. Some notes:
+  //  - LSR currently only supports LoopSimplify-form loops. Indvars'
+  //    canonicalization can be a pessimization without LSR to "clean up"
+  //    afterwards.
+  //  - We depend on having a preheader; in particular,
+  //    Loop::getCanonicalInductionVariable only supports loops with preheaders,
+  //    and we're in trouble if we can't find the induction variable even when
+  //    we've manually inserted one.
+  if (!L->isLoopSimplifyForm())
+    return false;
+
+  if (EnableIVRewrite)
+    IU = &getAnalysis<IVUsers>();
+  LI = &getAnalysis<LoopInfo>();
+  SE = &getAnalysis<ScalarEvolution>();
+  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
+  TD = DLP ? &DLP->getDataLayout() : 0;
+
+  DeadInsts.clear();
+  Changed = false;
+
+  // If there are any floating-point recurrences, attempt to
+  // transform them to use integer recurrences.
+  RewriteNonIntegerIVs(L);
+
+  const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
+
+  // Create a rewriter object which we'll use to transform the code with.
+  SCEVExpander Rewriter(*SE, "indvars");
+#ifndef NDEBUG
+  Rewriter.setDebugType(DEBUG_TYPE);
+#endif
+
+  // Eliminate redundant IV users.
+  //
+  // Simplification works best when run before other consumers of SCEV. We
+  // attempt to avoid evaluating SCEVs for sign/zero extend operations until
+  // other expressions involving loop IVs have been evaluated. This helps SCEV
+  // set no-wrap flags before normalizing sign/zero extension.
+  if (!EnableIVRewrite) {
+    Rewriter.disableCanonicalMode();
+    SimplifyAndExtend(L, Rewriter, LPM);
+  }
+
+  // Check to see if this loop has a computable loop-invariant execution count.
+  // If so, this means that we can compute the final value of any expressions
+  // that are recurrent in the loop, and substitute the exit values from the
+  // loop into any instructions outside of the loop that use the final values of
+  // the current expressions.
+  //
+  if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount))
+    RewriteLoopExitValues(L, Rewriter);
+
+  // Eliminate redundant IV users.
+  // FIXME: Disabled as the function was removed from LLVM trunk. We may get
+  //        along with this, as Polly does not need a lot of simplifications,
+  //        but just a canonical induction variable. In the near future, we
+  //        should remove the need of canonical induction variables all
+  //        together.
+  // if (EnableIVRewrite)
+  //  Changed |= simplifyIVUsers(IU, SE, &LPM, DeadInsts);
+
+  // Eliminate redundant IV cycles.
+  if (!EnableIVRewrite)
+    NumElimIV += Rewriter.replaceCongruentIVs(L, DT, DeadInsts);
+
+  // Compute the type of the largest recurrence expression, and decide whether
+  // a canonical induction variable should be inserted.
+  Type *LargestType = 0;
+  bool NeedCannIV = false;
+  bool ExpandBECount = canExpandBackedgeTakenCount(L, SE);
+  if (EnableIVRewrite && ExpandBECount) {
+    // If we have a known trip count and a single exit block, we'll be
+    // rewriting the loop exit test condition below, which requires a
+    // canonical induction variable.
+    NeedCannIV = true;
+    Type *Ty = BackedgeTakenCount->getType();
+    if (!EnableIVRewrite) {
+      // In this mode, SimplifyIVUsers may have already widened the IV used by
+      // the backedge test and inserted a Trunc on the compare's operand. Get
+      // the wider type to avoid creating a redundant narrow IV only used by the
+      // loop test.
+      LargestType = getBackedgeIVType(L);
+    }
+    if (!LargestType ||
+        SE->getTypeSizeInBits(Ty) > SE->getTypeSizeInBits(LargestType))
+      LargestType = SE->getEffectiveSCEVType(Ty);
+  }
+  if (EnableIVRewrite) {
+    for (IVUsers::const_iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
+      NeedCannIV = true;
+      Type *Ty =
+          SE->getEffectiveSCEVType(I->getOperandValToReplace()->getType());
+      if (!LargestType ||
+          SE->getTypeSizeInBits(Ty) > SE->getTypeSizeInBits(LargestType))
+        LargestType = Ty;
+    }
+  }
+
+  // Now that we know the largest of the induction variable expressions
+  // in this loop, insert a canonical induction variable of the largest size.
+  PHINode *IndVar = 0;
+  if (NeedCannIV) {
+    // Check to see if the loop already has any canonical-looking induction
+    // variables. If any are present and wider than the planned canonical
+    // induction variable, temporarily remove them, so that the Rewriter
+    // doesn't attempt to reuse them.
+    SmallVector<PHINode *, 2> OldCannIVs;
+    while (PHINode *OldCannIV = L->getCanonicalInductionVariable()) {
+      if (SE->getTypeSizeInBits(OldCannIV->getType()) >
+          SE->getTypeSizeInBits(LargestType))
+        OldCannIV->removeFromParent();
+      else
+        break;
+      OldCannIVs.push_back(OldCannIV);
+    }
+
+    IndVar = Rewriter.getOrInsertCanonicalInductionVariable(L, LargestType);
+
+    ++NumInserted;
+    Changed = true;
+    DEBUG(dbgs() << "INDVARS: New CanIV: " << *IndVar << '\n');
+
+    // Now that the official induction variable is established, reinsert
+    // any old canonical-looking variables after it so that the IR remains
+    // consistent. They will be deleted as part of the dead-PHI deletion at
+    // the end of the pass.
+    while (!OldCannIVs.empty()) {
+      PHINode *OldCannIV = OldCannIVs.pop_back_val();
+      OldCannIV->insertBefore(L->getHeader()->getFirstInsertionPt());
+    }
+  } else if (!EnableIVRewrite && ExpandBECount && needsLFTR(L, DT)) {
+    IndVar = FindLoopCounter(L, BackedgeTakenCount, SE, DT, TD);
+  }
+  // If we have a trip count expression, rewrite the loop's exit condition
+  // using it.  We can currently only handle loops with a single exit.
+  Value *NewICmp = 0;
+  if (ExpandBECount && IndVar) {
+    // Check preconditions for proper SCEVExpander operation. SCEV does not
+    // express SCEVExpander's dependencies, such as LoopSimplify. Instead any
+    // pass that uses the SCEVExpander must do it. This does not work well for
+    // loop passes because SCEVExpander makes assumptions about all loops, while
+    // LoopPassManager only forces the current loop to be simplified.
+    //
+    // FIXME: SCEV expansion has no way to bail out, so the caller must
+    // explicitly check any assumptions made by SCEV. Brittle.
+    const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(BackedgeTakenCount);
+    if (!AR || AR->getLoop()->getLoopPreheader())
+      NewICmp =
+          LinearFunctionTestReplace(L, BackedgeTakenCount, IndVar, Rewriter);
+  }
+  // Rewrite IV-derived expressions.
+  if (EnableIVRewrite)
+    RewriteIVExpressions(L, Rewriter);
+
+  // Clear the rewriter cache, because values that are in the rewriter's cache
+  // can be deleted in the loop below, causing the AssertingVH in the cache to
+  // trigger.
+  Rewriter.clear();
+
+  // Now that we're done iterating through lists, clean up any instructions
+  // which are now dead.
+  while (!DeadInsts.empty())
+    if (Instruction *Inst =
+            dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val()))
+      RecursivelyDeleteTriviallyDeadInstructions(Inst);
+
+  // The Rewriter may not be used from this point on.
+
+  // Loop-invariant instructions in the preheader that aren't used in the
+  // loop may be sunk below the loop to reduce register pressure.
+  SinkUnusedInvariants(L);
+
+  // For completeness, inform IVUsers of the IV use in the newly-created
+  // loop exit test instruction.
+  if (IU && NewICmp) {
+    ICmpInst *NewICmpInst = dyn_cast<ICmpInst>(NewICmp);
+    if (NewICmpInst)
+      IU->AddUsersIfInteresting(cast<Instruction>(NewICmpInst->getOperand(0)));
+  }
+  // Clean up dead instructions.
+  Changed |= DeleteDeadPHIs(L->getHeader());
+  // Check a post-condition.
+  assert(L->isLCSSAForm(*DT) &&
+         "Indvars did not leave the loop in lcssa form!");
+
+// Verify that LFTR, and any other change have not interfered with SCEV's
+// ability to compute trip count.
+#ifndef NDEBUG
+  if (!EnableIVRewrite && VerifyIndvars &&
+      !isa<SCEVCouldNotCompute>(BackedgeTakenCount)) {
+    SE->forgetLoop(L);
+    const SCEV *NewBECount = SE->getBackedgeTakenCount(L);
+    if (SE->getTypeSizeInBits(BackedgeTakenCount->getType()) <
+        SE->getTypeSizeInBits(NewBECount->getType()))
+      NewBECount =
+          SE->getTruncateOrNoop(NewBECount, BackedgeTakenCount->getType());
+    else
+      BackedgeTakenCount =
+          SE->getTruncateOrNoop(BackedgeTakenCount, NewBECount->getType());
+    assert(BackedgeTakenCount == NewBECount && "indvars must preserve SCEV");
+  }
+#endif
+
+  return Changed;
+}
+
+INITIALIZE_PASS_BEGIN(PollyIndVarSimplify, "polly-indvars",
+                      "Induction Variable Simplification (Polly version)",
+                      false, false);
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
+INITIALIZE_PASS_DEPENDENCY(LoopInfo);
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
+INITIALIZE_PASS_DEPENDENCY(LoopSimplify);
+INITIALIZE_PASS_DEPENDENCY(LCSSA);
+INITIALIZE_PASS_DEPENDENCY(IVUsers);
+INITIALIZE_PASS_END(PollyIndVarSimplify, "polly-indvars",
+                    "Induction Variable Simplification (Polly version)", false,
+                    false)
diff --git a/rc1/lib/Transform/IndependentBlocks.cpp b/rc1/lib/Transform/IndependentBlocks.cpp
new file mode 100644
index 0000000..1894f45
--- /dev/null
+++ b/rc1/lib/Transform/IndependentBlocks.cpp
@@ -0,0 +1,566 @@
+//===------ 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/Options.h"
+#include "polly/CodeGen/BlockGenerators.h"
+#include "polly/CodeGen/Cloog.h"
+#include "polly/ScopDetection.h"
+#include "polly/Support/ScopHelper.h"
+#include "llvm/Analysis/DominanceFrontier.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+
+#include <vector>
+
+using namespace polly;
+using namespace llvm;
+
+#define DEBUG_TYPE "polly-independent"
+
+static cl::opt<bool> DisableIntraScopScalarToArray(
+    "disable-polly-intra-scop-scalar-to-array",
+    cl::desc("Do not rewrite scalar to array to generate independent blocks"),
+    cl::Hidden, cl::init(false), cl::cat(PollyCategory));
+
+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 onlyUsedInRegion(Instruction *Inst, const Region *R);
+  bool translateScalarToArray(BasicBlock *BB, const Region *R);
+  bool translateScalarToArray(Instruction *Inst, const Region *R);
+  bool translateScalarToArray(const Region *R);
+
+  bool runOnFunction(Function &F);
+  void verifyAnalysis() const;
+  void verifyScop(const Region *R) const;
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+};
+}
+
+bool IndependentBlocks::isSafeToMove(Instruction *Inst) {
+  if (Inst->mayReadFromMemory() || Inst->mayWriteToMemory())
+    return false;
+
+  return isSafeToSpeculativelyExecute(Inst);
+}
+
+void IndependentBlocks::moveOperandTree(Instruction *Inst, const Region *R,
+                                        ReplacedMapType &ReplacedMap,
+                                        Instruction *InsertPos) {
+  BasicBlock *CurBB = Inst->getParent();
+
+  // Depth first traverse the operand tree (or operand dag, because we will
+  // stop at PHINodes, so there are no cycle).
+  typedef Instruction::op_iterator ChildIt;
+  std::vector<std::pair<Instruction *, ChildIt>> WorkStack;
+
+  WorkStack.push_back(std::make_pair(Inst, Inst->op_begin()));
+  DenseSet<Instruction *> VisitedSet;
+
+  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);
+        SE->forgetValue(CurInst);
+      }
+
+      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 operands 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;
+      }
+
+      if (canSynthesize(Operand, LI, SE, R)) {
+        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 is contained in the same BB with
+      // the root instruction.
+      if (Operand->getParent() == CurBB) {
+        DEBUG(dbgs() << "No need to move.\n");
+        // Try to move its operand, but do not visit an instuction twice.
+        if (VisitedSet.insert(Operand).second)
+          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);
+        SE->forgetValue(MovedOp);
+      } 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));
+        SE->forgetValue(Operand);
+
+        // Process its operands, but do not visit an instuction twice.
+        if (VisitedSet.insert(NewOp).second)
+          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 (Instruction &Inst : *BB)
+    if (!isSafeToMove(&Inst) && !canSynthesize(&Inst, LI, SE, R))
+      WorkList.push_back(&Inst);
+
+  ReplacedMapType ReplacedMap;
+  Instruction *InsertPos = BB->getFirstNonPHIOrDbg();
+
+  for (Instruction *Inst : WorkList)
+    moveOperandTree(Inst, 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 (BasicBlock *BB : R->blocks())
+    Changed |= createIndependentBlocks(BB, R);
+
+  return Changed;
+}
+
+bool IndependentBlocks::eliminateDeadCode(const Region *R) {
+  std::vector<Instruction *> WorkList;
+
+  // Find all trivially dead instructions.
+  for (BasicBlock *BB : R->blocks())
+    for (Instruction &Inst : *BB)
+      if (isInstructionTriviallyDead(&Inst))
+        WorkList.push_back(&Inst);
+
+  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 (canSynthesize(OpInst, LI, SE, R))
+    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 *R = toUpdate.back();
+    toUpdate.pop_back();
+
+    for (auto &&SubRegion : *R)
+      if (SubRegion->getExit() == ExitBB)
+        toUpdate.push_back(SubRegion.get());
+
+    R->replaceExit(NewExit);
+  }
+
+  RI->setRegionFor(NewExit, R->getParent());
+  return true;
+}
+
+bool IndependentBlocks::translateScalarToArray(const Region *R) {
+  bool Changed = false;
+
+  for (BasicBlock *BB : R->blocks())
+    Changed |= translateScalarToArray(BB, R);
+
+  return Changed;
+}
+
+// Returns true when Inst is only used inside region R.
+bool IndependentBlocks::onlyUsedInRegion(Instruction *Inst, const Region *R) {
+  for (User *U : Inst->users())
+    if (Instruction *UI = dyn_cast<Instruction>(U))
+      if (isEscapeUse(UI, R))
+        return false;
+
+  return true;
+}
+
+bool IndependentBlocks::translateScalarToArray(Instruction *Inst,
+                                               const Region *R) {
+  if (canSynthesize(Inst, LI, SE, R) && onlyUsedInRegion(Inst, R))
+    return false;
+
+  SmallVector<Instruction *, 4> LoadInside, LoadOutside;
+  for (User *U : Inst->users())
+    // Inst is referenced outside or referenced as an escaped operand.
+    if (Instruction *UI = dyn_cast<Instruction>(U)) {
+      if (isEscapeUse(UI, R))
+        LoadOutside.push_back(UI);
+
+      if (DisableIntraScopScalarToArray)
+        continue;
+
+      if (canSynthesize(UI, LI, SE, R))
+        continue;
+
+      BasicBlock *UParent = UI->getParent();
+      if (R->contains(UParent) && isEscapeOperand(Inst, UParent, R))
+        LoadInside.push_back(UI);
+    }
+
+  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, and make sure the position is after all phi nodes.
+  BasicBlock::iterator StorePos;
+  if (isa<PHINode>(Inst)) {
+    StorePos = Inst->getParent()->getFirstNonPHI();
+  } else {
+    StorePos = Inst;
+    StorePos++;
+  }
+  (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();
+      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 inside!");
+    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 (Instruction &Inst : *BB) {
+    if (canSynthesize(&Inst, LI, SE, R))
+      continue;
+
+    // A value inside the Scop is referenced outside.
+    for (User *U : Inst.users()) {
+      if (isEscapeUse(U, R)) {
+        DEBUG(dbgs() << "Instruction not independent:\n");
+        DEBUG(dbgs() << "Instruction used outside the Scop!\n");
+        DEBUG(Inst.print(dbgs()));
+        DEBUG(dbgs() << "\n");
+        return false;
+      }
+    }
+
+    if (DisableIntraScopScalarToArray)
+      continue;
+
+    for (Value *Op : Inst.operands()) {
+      if (isEscapeOperand(Op, BB, R)) {
+        DEBUG(dbgs() << "Instruction in function '";
+              BB->getParent()->printAsOperand(dbgs(), false);
+              dbgs() << "' not independent:\n");
+        DEBUG(dbgs() << "Uses invalid operator\n");
+        DEBUG(Inst.print(dbgs()));
+        DEBUG(dbgs() << "\n");
+        DEBUG(dbgs() << "Invalid operator is: ";
+              Op->printAsOperand(dbgs(), false); dbgs() << "\n");
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+bool IndependentBlocks::areAllBlocksIndependent(const Region *R) const {
+  for (BasicBlock *BB : R->blocks())
+    if (!isIndependentBlock(R, BB))
+      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<DominatorTreeWrapperPass>();
+  AU.addPreserved<DominanceFrontier>();
+  AU.addPreserved<PostDominatorTree>();
+  AU.addRequired<RegionInfoPass>();
+  AU.addPreserved<RegionInfoPass>();
+  AU.addRequired<LoopInfo>();
+  AU.addPreserved<LoopInfo>();
+  AU.addRequired<ScalarEvolution>();
+  AU.addPreserved<ScalarEvolution>();
+  AU.addRequired<ScopDetection>();
+  AU.addPreserved<ScopDetection>();
+#ifdef CLOOG_FOUND
+  AU.addPreserved<CloogInfo>();
+#endif
+}
+
+bool IndependentBlocks::runOnFunction(llvm::Function &F) {
+  bool Changed = false;
+
+  RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
+  LI = &getAnalysis<LoopInfo>();
+  SD = &getAnalysis<ScopDetection>();
+  SE = &getAnalysis<ScalarEvolution>();
+
+  AllocaBlock = &F.getEntryBlock();
+
+  DEBUG(dbgs() << "Run IndepBlock on " << F.getName() << '\n');
+
+  for (const Region *R : *SD) {
+    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 (const Region *R : *SD)
+    Changed |= translateScalarToArray(R);
+
+  DEBUG(dbgs() << "After Independent Blocks------------->\n");
+  DEBUG(F.dump());
+
+  verifyAnalysis();
+
+  return Changed;
+}
+
+void IndependentBlocks::verifyAnalysis() const {
+  for (const Region *R : *SD)
+    verifyScop(R);
+}
+
+void IndependentBlocks::verifyScop(const Region *R) const {
+  assert(areAllBlocksIndependent(R) && "Cannot generate independent blocks");
+}
+
+char IndependentBlocks::ID = 0;
+char &polly::IndependentBlocksID = IndependentBlocks::ID;
+
+Pass *polly::createIndependentBlocksPass() { return new IndependentBlocks(); }
+
+INITIALIZE_PASS_BEGIN(IndependentBlocks, "polly-independent",
+                      "Polly - Create independent blocks", false, false);
+INITIALIZE_PASS_DEPENDENCY(LoopInfo);
+INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
+INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
+INITIALIZE_PASS_DEPENDENCY(ScopDetection);
+INITIALIZE_PASS_END(IndependentBlocks, "polly-independent",
+                    "Polly - Create independent blocks", false, false)
diff --git a/rc1/lib/Transform/Pluto.cpp b/rc1/lib/Transform/Pluto.cpp
new file mode 100644
index 0000000..e0ab060
--- /dev/null
+++ b/rc1/lib/Transform/Pluto.cpp
@@ -0,0 +1,270 @@
+//===- Pluto.cpp - Calculate an optimized schedule ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Use libpluto to optimize the schedule.
+//
+//===----------------------------------------------------------------------===//
+
+#include "polly/Config/config.h"
+
+#ifdef PLUTO_FOUND
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/Dependences.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
+#include "polly/ScopInfo.h"
+#include "polly/Support/GICHelper.h"
+#include "llvm/Support/Debug.h"
+
+#include "pluto/libpluto.h"
+#include "isl/map.h"
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-opt-pluto"
+
+static cl::opt<bool> EnableTiling("polly-pluto-tile", cl::desc("Enable tiling"),
+                                  cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                                  cl::cat(PollyCategory));
+
+static cl::opt<bool> EnableIntraTiling("polly-pluto-intratileopt",
+                                       cl::desc("Enable intratiling"),
+                                       cl::Hidden, cl::init(true),
+                                       cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoDebug("polly-pluto-debug",
+                                cl::desc("Enable pluto debug"), cl::Hidden,
+                                cl::init(false), cl::ZeroOrMore,
+                                cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoMoreDebug("polly-pluto-moredebug",
+                                    cl::desc("Enable more pluto debugging"),
+                                    cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                                    cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoParallel("polly-pluto-parallel",
+                                   cl::desc("Enable pluto parallel transforms"),
+                                   cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                                   cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    PlutoInnerParallel("polly-pluto-innerpara",
+                       cl::desc("Enable inner parallelism instead of piped."),
+                       cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                       cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    PlutoIdentity("polly-pluto-identity",
+                  cl::desc("Enable pluto identity transformation"), cl::Hidden,
+                  cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoUnroll("polly-pluto-unroll",
+                                 cl::desc("Enable pluto unrolling"), cl::Hidden,
+                                 cl::init(false), cl::ZeroOrMore,
+                                 cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoRar("polly-pluto-rar",
+                              cl::desc("Enable pluto rar deps"), cl::Hidden,
+                              cl::init(false), cl::ZeroOrMore,
+                              cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoParaPipe("polly-pluto-multipipe",
+                                   cl::desc("Enable multipipe parallelism"),
+                                   cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                                   cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoL2Tile("polly-pluto-l2tile",
+                                 cl::desc("Enable L2 tiling"), cl::Hidden,
+                                 cl::init(false), cl::ZeroOrMore,
+                                 cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoPollyUnroll("polly-pluto-pollyunroll",
+                                      cl::desc("Enable pluto polly unrolling"),
+                                      cl::Hidden, cl::init(false),
+                                      cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool>
+    PlutoIslDep("polly-pluto-isldep",
+                cl::desc("Enable pluto isl dependency scanning"), cl::Hidden,
+                cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoIslDepCompact(
+    "polly-pluto-isldepcom", cl::desc("Enable pluto isl dependency compaction"),
+    cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoIslSolve("polly-pluto-islsolve",
+                                   cl::desc("Enable pluto isl solver"),
+                                   cl::Hidden, cl::init(false), cl::ZeroOrMore,
+                                   cl::cat(PollyCategory));
+
+static cl::opt<bool> PlutoLastWriter("polly-pluto-lastwriter",
+                                     cl::desc("Enable pluto lastwriter"),
+                                     cl::Hidden, cl::init(false),
+                                     cl::ZeroOrMore, cl::cat(PollyCategory));
+
+namespace {
+/// Convert an int into a string.
+static std::string convertInt(int number) {
+  if (number == 0)
+    return "0";
+  std::string temp = "";
+  std::string returnvalue = "";
+  while (number > 0) {
+    temp += number % 10 + 48;
+    number /= 10;
+  }
+  for (unsigned i = 0; i < temp.length(); i++)
+    returnvalue += temp[temp.length() - i - 1];
+  return returnvalue;
+}
+
+class PlutoOptimizer : public ScopPass {
+public:
+  static char ID;
+  explicit PlutoOptimizer() : ScopPass(ID) {}
+
+  virtual bool runOnScop(Scop &S);
+  void printScop(llvm::raw_ostream &OS) const;
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+  static void extendScattering(Scop &S, unsigned NewDimensions);
+};
+}
+
+char PlutoOptimizer::ID = 0;
+
+static int getSingleMap(__isl_take isl_map *map, void *user) {
+  isl_map **singleMap = (isl_map **)user;
+  *singleMap = map;
+
+  return 0;
+}
+
+void PlutoOptimizer::extendScattering(Scop &S, unsigned NewDimensions) {
+  for (ScopStmt *Stmt : S) {
+    unsigned OldDimensions = Stmt->getNumScattering();
+    isl_space *Space;
+    isl_map *Map, *New;
+
+    Space = isl_space_alloc(Stmt->getIslCtx(), 0, OldDimensions, NewDimensions);
+    Map = isl_map_universe(Space);
+
+    for (unsigned i = 0; i < OldDimensions; i++)
+      Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
+
+    for (unsigned i = OldDimensions; i < NewDimensions; i++)
+      Map = isl_map_fix_si(Map, isl_dim_out, i, 0);
+
+    Map = isl_map_align_params(Map, S.getParamSpace());
+    New = isl_map_apply_range(Stmt->getScattering(), Map);
+    Stmt->setScattering(New);
+  }
+}
+
+bool PlutoOptimizer::runOnScop(Scop &S) {
+  isl_union_set *Domain;
+  isl_union_map *Deps, *ToPlutoNames, *Schedule;
+  PlutoOptions *Options;
+
+  Dependences *D = &getAnalysis<Dependences>();
+
+  int DependencesKinds =
+      Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+
+  Deps = D->getDependences(DependencesKinds);
+  Domain = S.getDomains();
+  ToPlutoNames = isl_union_map_empty(S.getParamSpace());
+
+  int counter = 0;
+  for (ScopStmt *Stmt : S) {
+    std::string Name = "S_" + convertInt(counter);
+    isl_map *Identity = isl_map_identity(isl_space_map_from_domain_and_range(
+        Stmt->getDomainSpace(), Stmt->getDomainSpace()));
+    Identity = isl_map_set_tuple_name(Identity, isl_dim_out, Name.c_str());
+    ToPlutoNames = isl_union_map_add_map(ToPlutoNames, Identity);
+    counter++;
+  }
+
+  Deps = isl_union_map_apply_domain(Deps, isl_union_map_copy(ToPlutoNames));
+  Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(ToPlutoNames));
+  Domain = isl_union_set_apply(Domain, isl_union_map_copy(ToPlutoNames));
+
+  Options = pluto_options_alloc();
+  Options->debug = PlutoDebug;
+  Options->fuse = 2;
+  Options->identity = PlutoIdentity;
+  Options->innerpar = PlutoInnerParallel;
+  Options->intratileopt = EnableIntraTiling;
+  Options->isldep = PlutoIslDep;
+  Options->isldepcompact = PlutoIslDepCompact;
+  Options->islsolve = PlutoIslSolve;
+  Options->l2tile = PlutoL2Tile;
+  Options->lastwriter = PlutoLastWriter;
+  Options->moredebug = PlutoMoreDebug;
+  Options->multipipe = PlutoParaPipe;
+  Options->parallel = PlutoParallel;
+  Options->polyunroll = PlutoPollyUnroll;
+  Options->rar = PlutoRar;
+  Options->tile = EnableTiling;
+  Options->unroll = PlutoUnroll;
+
+  DEBUG(dbgs() << "Domain: " << stringFromIslObj(Domain) << "\n";
+        dbgs() << "Dependences: " << stringFromIslObj(Deps) << "\n";);
+  Schedule = pluto_schedule(Domain, Deps, Options);
+  pluto_options_free(Options);
+
+  isl_union_set_free(Domain);
+  isl_union_map_free(Deps);
+
+  if (!Schedule)
+    return false;
+
+  Schedule =
+      isl_union_map_apply_domain(Schedule, isl_union_map_reverse(ToPlutoNames));
+
+  for (ScopStmt *Stmt : S) {
+    isl_set *Domain = Stmt->getDomain();
+    isl_union_map *StmtBand;
+    StmtBand = isl_union_map_intersect_domain(isl_union_map_copy(Schedule),
+                                              isl_union_set_from_set(Domain));
+    isl_map *StmtSchedule;
+    isl_union_map_foreach_map(StmtBand, getSingleMap, &StmtSchedule);
+    Stmt->setScattering(StmtSchedule);
+    isl_union_map_free(StmtBand);
+  }
+
+  isl_union_map_free(Schedule);
+
+  unsigned MaxScatDims = 0;
+
+  for (ScopStmt *Stmt : S)
+    MaxScatDims = std::max(Stmt->getNumScattering(), MaxScatDims);
+
+  extendScattering(S, MaxScatDims);
+  return false;
+}
+
+void PlutoOptimizer::printScop(raw_ostream &OS) const {}
+
+void PlutoOptimizer::getAnalysisUsage(AnalysisUsage &AU) const {
+  ScopPass::getAnalysisUsage(AU);
+  AU.addRequired<Dependences>();
+}
+
+Pass *polly::createPlutoOptimizerPass() { return new PlutoOptimizer(); }
+
+INITIALIZE_PASS_BEGIN(PlutoOptimizer, "polly-opt-pluto",
+                      "Polly - Optimize schedule of SCoP (Pluto)", false,
+                      false);
+INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(ScopInfo);
+INITIALIZE_PASS_END(PlutoOptimizer, "polly-opt-pluto",
+                    "Polly - Optimize schedule of SCoP (Pluto)", false, false)
+
+#endif // PLUTO_FOUND
diff --git a/rc1/lib/Transform/Pocc.cpp b/rc1/lib/Transform/Pocc.cpp
new file mode 100644
index 0000000..edf9114
--- /dev/null
+++ b/rc1/lib/Transform/Pocc.cpp
@@ -0,0 +1,282 @@
+//===- 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/LinkAllPasses.h"
+
+#ifdef SCOPLIB_FOUND
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/Dependences.h"
+#include "polly/Options.h"
+#include "polly/ScheduleOptimizer.h"
+#include "polly/ScopInfo.h"
+#include "polly/ScopLib.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/SmallString.h"
+
+#include "isl/space.h"
+#include "isl/map.h"
+#include "isl/constraint.h"
+
+#include <memory>
+#include <system_error>
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-opt-pocc"
+
+static cl::opt<std::string> PlutoFuse("pluto-fuse", cl::desc(""), cl::Hidden,
+                                      cl::value_desc("Set fuse mode of Pluto"),
+                                      cl::init("maxfuse"),
+                                      cl::cat(PollyCategory));
+
+namespace {
+
+class Pocc : public ScopPass {
+  SmallString<128> PlutoStderr;
+  SmallString<128> 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;
+
+private:
+  bool runTransform(Scop &S);
+};
+}
+
+char Pocc::ID = 0;
+bool Pocc::runTransform(Scop &S) {
+  Dependences *D = &getAnalysis<Dependences>();
+
+  // Create the scop file.
+  SmallString<128> TempDir;
+  SmallString<128> ScopFile;
+  llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/true, TempDir);
+  ScopFile = TempDir;
+  llvm::sys::path::append(ScopFile, "polly.scop");
+
+  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
+  std::string pocc = sys::FindProgramByName("pocc");
+
+  arguments.push_back("pocc");
+  arguments.push_back("--read-scop");
+  arguments.push_back(ScopFile.c_str());
+  arguments.push_back("--pluto-tile-scat");
+  arguments.push_back("--candl-dep-isl-simp");
+  arguments.push_back("--cloogify-scheds");
+  arguments.push_back("--output-scop");
+  arguments.push_back("--pluto");
+  arguments.push_back("--pluto-bounds");
+  arguments.push_back("10");
+  arguments.push_back("--pluto-fuse");
+
+  arguments.push_back(PlutoFuse.c_str());
+
+  if (!DisablePollyTiling)
+    arguments.push_back("--pluto-tile");
+
+  if (PollyVectorizerChoice != VECTORIZER_NONE)
+    arguments.push_back("--pluto-prevector");
+
+  arguments.push_back(0);
+
+  PlutoStdout = TempDir;
+  llvm::sys::path::append(PlutoStdout, "pluto.stdout");
+  PlutoStderr = TempDir;
+  llvm::sys::path::append(PlutoStderr, "pluto.stderr");
+
+  std::vector<llvm::StringRef> Redirect;
+  Redirect.push_back(0);
+  Redirect.push_back(PlutoStdout.c_str());
+  Redirect.push_back(PlutoStderr.c_str());
+
+  sys::ExecuteAndWait(pocc, &arguments[0], 0,
+                      (const llvm::StringRef **)&Redirect[0]);
+
+  // Read the created scop file
+  SmallString<128> NewScopFile;
+  NewScopFile = TempDir;
+  llvm::sys::path::append(NewScopFile, "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 (const char *Arg : arguments)
+      if (Arg)
+        errs() << " " << Arg;
+    errs() << "\n";
+    return false;
+  } else
+    fclose(poccFile);
+
+  if (PollyVectorizerChoice == VECTORIZER_NONE)
+    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 (ScopStmt *Stmt : S) {
+      isl_map *scat = Stmt->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 (ScopStmt *Stmt : S) {
+    isl_map *scat = Stmt->getScattering();
+    int scatDims = Stmt->getNumScattering();
+    isl_space *Space = isl_space_alloc(S.getIslCtx(), S.getNumParams(),
+                                       scatDims, scatDims + 1);
+    isl_basic_map *map = isl_basic_map_universe(isl_space_copy(Space));
+    isl_local_space *LSpace = isl_local_space_from_space(Space);
+
+    for (int i = 0; i <= lastLoop - 1; i++) {
+      isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LSpace));
+
+      isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1);
+      isl_constraint_set_coefficient_si(c, isl_dim_out, i, -1);
+
+      map = isl_basic_map_add_constraint(map, c);
+    }
+
+    for (int i = lastLoop; i < scatDims; i++) {
+      isl_constraint *c = isl_equality_alloc(isl_local_space_copy(LSpace));
+
+      isl_constraint_set_coefficient_si(c, isl_dim_in, i, 1);
+      isl_constraint_set_coefficient_si(c, isl_dim_out, i + 1, -1);
+
+      map = isl_basic_map_add_constraint(map, c);
+    }
+
+    isl_constraint *c;
+
+    int vectorWidth = 4;
+    c = isl_inequality_alloc(isl_local_space_copy(LSpace));
+    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, -vectorWidth);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, 1);
+    map = isl_basic_map_add_constraint(map, c);
+
+    c = isl_inequality_alloc(LSpace);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop, vectorWidth);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, lastLoop + 1, -1);
+    isl_constraint_set_constant_si(c, vectorWidth - 1);
+    map = isl_basic_map_add_constraint(map, c);
+
+    isl_map *transform = isl_map_from_basic_map(map);
+    transform = isl_map_set_tuple_name(transform, isl_dim_out, "scattering");
+    transform = isl_map_set_tuple_name(transform, isl_dim_in, "scattering");
+
+    scat = isl_map_apply_range(scat, isl_map_copy(transform));
+    Stmt->setScattering(scat);
+  }
+
+  return false;
+}
+bool Pocc::runOnScop(Scop &S) {
+  bool Result = runTransform(S);
+  DEBUG(printScop(dbgs()));
+
+  return Result;
+}
+
+void Pocc::printScop(raw_ostream &OS) const {
+  std::unique_ptr<MemoryBuffer> stdoutBuffer;
+  std::unique_ptr<MemoryBuffer> stderrBuffer;
+
+  OS << "Command line: ";
+
+  for (const char *Arg : arguments)
+    if (Arg)
+      OS << " " << Arg;
+
+  OS << "\n";
+
+  if (std::error_code ec =
+          MemoryBuffer::getFile(PlutoStdout.str(), stdoutBuffer))
+    OS << "Could not open pocc stdout file: " + ec.message() << "\n";
+  else {
+    OS << "pocc stdout: " << stdoutBuffer->getBufferIdentifier() << "\n";
+    OS << stdoutBuffer->getBuffer() << "\n";
+  }
+
+  if (std::error_code ec =
+          MemoryBuffer::getFile(PlutoStderr.str(), stderrBuffer))
+    OS << "Could not open pocc stderr file: " + ec.message() << "\n";
+  else {
+    OS << "pocc stderr: " << PlutoStderr << "\n";
+    OS << stderrBuffer->getBuffer() << "\n";
+  }
+}
+
+void Pocc::getAnalysisUsage(AnalysisUsage &AU) const {
+  ScopPass::getAnalysisUsage(AU);
+  AU.addRequired<Dependences>();
+}
+
+Pass *polly::createPoccPass() { return new Pocc(); }
+
+INITIALIZE_PASS_BEGIN(Pocc, "polly-opt-pocc",
+                      "Polly - Optimize the scop using pocc", false, false);
+INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(ScopInfo);
+INITIALIZE_PASS_END(Pocc, "polly-opt-pocc",
+                    "Polly - Optimize the scop using pocc", false, false)
+#endif /* SCOPLIB_FOUND */
diff --git a/rc1/lib/Transform/ScheduleOptimizer.cpp b/rc1/lib/Transform/ScheduleOptimizer.cpp
new file mode 100644
index 0000000..16c6e54
--- /dev/null
+++ b/rc1/lib/Transform/ScheduleOptimizer.cpp
@@ -0,0 +1,624 @@
+//===- Schedule.cpp - Calculate an optimized schedule ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass the isl to calculate a schedule that is optimized for parallelism
+// and tileablility. The algorithm used in isl is an optimized version of the
+// algorithm described in following paper:
+//
+// U. Bondhugula, A. Hartono, J. Ramanujam, and P. Sadayappan.
+// A Practical Automatic Polyhedral Parallelizer and Locality Optimizer.
+// In Proceedings of the 2008 ACM SIGPLAN Conference On Programming Language
+// Design and Implementation, PLDI ’08, pages 101–113. ACM, 2008.
+//===----------------------------------------------------------------------===//
+
+#include "polly/ScheduleOptimizer.h"
+#include "isl/aff.h"
+#include "isl/band.h"
+#include "isl/constraint.h"
+#include "isl/map.h"
+#include "isl/options.h"
+#include "isl/schedule.h"
+#include "isl/space.h"
+#include "polly/CodeGen/CodeGeneration.h"
+#include "polly/Dependences.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
+#include "polly/ScopInfo.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+using namespace polly;
+
+#define DEBUG_TYPE "polly-opt-isl"
+
+namespace polly {
+bool DisablePollyTiling;
+}
+static cl::opt<bool, true>
+    DisableTiling("polly-no-tiling",
+                  cl::desc("Disable tiling in the scheduler"),
+                  cl::location(polly::DisablePollyTiling), cl::init(false),
+                  cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<std::string>
+    OptimizeDeps("polly-opt-optimize-only",
+                 cl::desc("Only a certain kind of dependences (all/raw)"),
+                 cl::Hidden, cl::init("all"), cl::ZeroOrMore,
+                 cl::cat(PollyCategory));
+
+static cl::opt<std::string>
+    SimplifyDeps("polly-opt-simplify-deps",
+                 cl::desc("Dependences should be simplified (yes/no)"),
+                 cl::Hidden, cl::init("yes"), cl::ZeroOrMore,
+                 cl::cat(PollyCategory));
+
+static cl::opt<int> MaxConstantTerm(
+    "polly-opt-max-constant-term",
+    cl::desc("The maximal constant term allowed (-1 is unlimited)"), cl::Hidden,
+    cl::init(20), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<int> MaxCoefficient(
+    "polly-opt-max-coefficient",
+    cl::desc("The maximal coefficient allowed (-1 is unlimited)"), cl::Hidden,
+    cl::init(20), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<std::string> FusionStrategy(
+    "polly-opt-fusion", cl::desc("The fusion strategy to choose (min/max)"),
+    cl::Hidden, cl::init("min"), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<std::string>
+    MaximizeBandDepth("polly-opt-maximize-bands",
+                      cl::desc("Maximize the band depth (yes/no)"), cl::Hidden,
+                      cl::init("yes"), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<int> DefaultTileSize(
+    "polly-default-tile-size",
+    cl::desc("The default tile size (if not enough were provided by"
+             " --polly-tile-sizes)"),
+    cl::Hidden, cl::init(32), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::list<int> TileSizes("polly-tile-sizes",
+                               cl::desc("A tile size"
+                                        " for each loop dimension, filled with"
+                                        " --polly-default-tile-size"),
+                               cl::Hidden, cl::ZeroOrMore, cl::CommaSeparated,
+                               cl::cat(PollyCategory));
+namespace {
+
+class IslScheduleOptimizer : public ScopPass {
+public:
+  static char ID;
+  explicit IslScheduleOptimizer() : ScopPass(ID) { LastSchedule = nullptr; }
+
+  ~IslScheduleOptimizer() { isl_schedule_free(LastSchedule); }
+
+  virtual bool runOnScop(Scop &S);
+  void printScop(llvm::raw_ostream &OS) const;
+  void getAnalysisUsage(AnalysisUsage &AU) const;
+
+private:
+  isl_schedule *LastSchedule;
+
+  static void extendScattering(Scop &S, unsigned NewDimensions);
+
+  /// @brief Create a map that describes a n-dimensonal tiling.
+  ///
+  /// getTileMap creates a map from a n-dimensional scattering space into an
+  /// 2*n-dimensional scattering space. The map describes a rectangular
+  /// tiling.
+  ///
+  /// Example:
+  ///   scheduleDimensions = 2, parameterDimensions = 1, TileSizes = <32, 64>
+  ///
+  ///   tileMap := [p0] -> {[s0, s1] -> [t0, t1, s0, s1]:
+  ///                        t0 % 32 = 0 and t0 <= s0 < t0 + 32 and
+  ///                        t1 % 64 = 0 and t1 <= s1 < t1 + 64}
+  ///
+  ///  Before tiling:
+  ///
+  ///  for (i = 0; i < N; i++)
+  ///    for (j = 0; j < M; j++)
+  ///	S(i,j)
+  ///
+  ///  After tiling:
+  ///
+  ///  for (t_i = 0; t_i < N; i+=32)
+  ///    for (t_j = 0; t_j < M; j+=64)
+  ///	for (i = t_i; i < min(t_i + 32, N); i++)  | Unknown that N % 32 = 0
+  ///	  for (j = t_j; j < t_j + 64; j++)        |   Known that M % 64 = 0
+  ///	    S(i,j)
+  ///
+  static isl_basic_map *getTileMap(isl_ctx *ctx, int scheduleDimensions,
+                                   isl_space *SpaceModel);
+
+  /// @brief Get the schedule for this band.
+  ///
+  /// Polly applies transformations like tiling on top of the isl calculated
+  /// value.  This can influence the number of scheduling dimension. The
+  /// number of schedule dimensions is returned in the parameter 'Dimension'.
+  static isl_union_map *getScheduleForBand(isl_band *Band, int *Dimensions);
+
+  /// @brief Create a map that pre-vectorizes one scheduling dimension.
+  ///
+  /// getPrevectorMap creates a map that maps each input dimension to the same
+  /// output dimension, except for the dimension DimToVectorize.
+  /// DimToVectorize is strip mined by 'VectorWidth' and the newly created
+  /// point loop of DimToVectorize is moved to the innermost level.
+  ///
+  /// Example (DimToVectorize=0, ScheduleDimensions=2, VectorWidth=4):
+  ///
+  /// | Before transformation
+  /// |
+  /// | A[i,j] -> [i,j]
+  /// |
+  /// | for (i = 0; i < 128; i++)
+  /// |    for (j = 0; j < 128; j++)
+  /// |      A(i,j);
+  ///
+  ///   Prevector map:
+  ///   [i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip
+  ///
+  /// | After transformation:
+  /// |
+  /// | A[i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip
+  /// |
+  /// | for (it = 0; it < 128; it+=4)
+  /// |    for (j = 0; j < 128; j++)
+  /// |      for (ip = max(0,it); ip < min(128, it + 3); ip++)
+  /// |        A(ip,j);
+  ///
+  /// The goal of this transformation is to create a trivially vectorizable
+  /// loop.  This means a parallel loop at the innermost level that has a
+  /// constant number of iterations corresponding to the target vector width.
+  ///
+  /// This transformation creates a loop at the innermost level. The loop has
+  /// a constant number of iterations, if the number of loop iterations at
+  /// DimToVectorize can be divided by VectorWidth. The default VectorWidth is
+  /// currently constant and not yet target specific. This function does not
+  /// reason about parallelism.
+  static isl_map *getPrevectorMap(isl_ctx *ctx, int DimToVectorize,
+                                  int ScheduleDimensions, int VectorWidth = 4);
+
+  /// @brief Get the scheduling map for a list of bands.
+  ///
+  /// Walk recursively the forest of bands to combine the schedules of the
+  /// individual bands to the overall schedule. In case tiling is requested,
+  /// the individual bands are tiled.
+  static isl_union_map *getScheduleForBandList(isl_band_list *BandList);
+
+  static isl_union_map *getScheduleMap(isl_schedule *Schedule);
+
+  using llvm::Pass::doFinalization;
+
+  virtual bool doFinalization() {
+    isl_schedule_free(LastSchedule);
+    LastSchedule = nullptr;
+    return true;
+  }
+};
+}
+
+char IslScheduleOptimizer::ID = 0;
+
+void IslScheduleOptimizer::extendScattering(Scop &S, unsigned NewDimensions) {
+  for (ScopStmt *Stmt : S) {
+    unsigned OldDimensions = Stmt->getNumScattering();
+    isl_space *Space;
+    isl_map *Map, *New;
+
+    Space = isl_space_alloc(Stmt->getIslCtx(), 0, OldDimensions, NewDimensions);
+    Map = isl_map_universe(Space);
+
+    for (unsigned i = 0; i < OldDimensions; i++)
+      Map = isl_map_equate(Map, isl_dim_in, i, isl_dim_out, i);
+
+    for (unsigned i = OldDimensions; i < NewDimensions; i++)
+      Map = isl_map_fix_si(Map, isl_dim_out, i, 0);
+
+    Map = isl_map_align_params(Map, S.getParamSpace());
+    New = isl_map_apply_range(Stmt->getScattering(), Map);
+    Stmt->setScattering(New);
+  }
+}
+
+isl_basic_map *IslScheduleOptimizer::getTileMap(isl_ctx *ctx,
+                                                int scheduleDimensions,
+                                                isl_space *SpaceModel) {
+  // We construct
+  //
+  // tileMap := [p0] -> {[s0, s1] -> [t0, t1, p0, p1, a0, a1]:
+  //	                  s0 = a0 * 32 and s0 = p0 and t0 <= p0 < t0 + 64 and
+  //	                  s1 = a1 * 64 and s1 = p1 and t1 <= p1 < t1 + 64}
+  //
+  // and project out the auxilary dimensions a0 and a1.
+  isl_space *Space =
+      isl_space_alloc(ctx, 0, scheduleDimensions, scheduleDimensions * 3);
+  isl_basic_map *tileMap = isl_basic_map_universe(isl_space_copy(Space));
+
+  isl_local_space *LocalSpace = isl_local_space_from_space(Space);
+
+  for (int x = 0; x < scheduleDimensions; x++) {
+    int sX = x;
+    int tX = x;
+    int pX = scheduleDimensions + x;
+    int aX = 2 * scheduleDimensions + x;
+    int tileSize = (int)TileSizes.size() > x ? TileSizes[x] : DefaultTileSize;
+    assert(tileSize > 0 && "Invalid tile size");
+
+    isl_constraint *c;
+
+    // sX = aX * tileSize;
+    c = isl_equality_alloc(isl_local_space_copy(LocalSpace));
+    isl_constraint_set_coefficient_si(c, isl_dim_out, sX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, aX, -tileSize);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
+
+    // pX = sX;
+    c = isl_equality_alloc(isl_local_space_copy(LocalSpace));
+    isl_constraint_set_coefficient_si(c, isl_dim_out, pX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_in, sX, -1);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
+
+    // tX <= pX
+    c = isl_inequality_alloc(isl_local_space_copy(LocalSpace));
+    isl_constraint_set_coefficient_si(c, isl_dim_out, pX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, tX, -1);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
+
+    // pX <= tX + (tileSize - 1)
+    c = isl_inequality_alloc(isl_local_space_copy(LocalSpace));
+    isl_constraint_set_coefficient_si(c, isl_dim_out, tX, 1);
+    isl_constraint_set_coefficient_si(c, isl_dim_out, pX, -1);
+    isl_constraint_set_constant_si(c, tileSize - 1);
+    tileMap = isl_basic_map_add_constraint(tileMap, c);
+  }
+
+  // Project out auxilary dimensions.
+  //
+  // The auxilary dimensions are transformed into existentially quantified ones.
+  // This reduces the number of visible scattering dimensions and allows Cloog
+  // to produces better code.
+  tileMap = isl_basic_map_project_out(
+      tileMap, isl_dim_out, 2 * scheduleDimensions, scheduleDimensions);
+  isl_local_space_free(LocalSpace);
+  return tileMap;
+}
+
+isl_union_map *IslScheduleOptimizer::getScheduleForBand(isl_band *Band,
+                                                        int *Dimensions) {
+  isl_union_map *PartialSchedule;
+  isl_ctx *ctx;
+  isl_space *Space;
+  isl_basic_map *TileMap;
+  isl_union_map *TileUMap;
+
+  PartialSchedule = isl_band_get_partial_schedule(Band);
+  *Dimensions = isl_band_n_member(Band);
+
+  if (DisableTiling)
+    return PartialSchedule;
+
+  // It does not make any sense to tile a band with just one dimension.
+  if (*Dimensions == 1)
+    return PartialSchedule;
+
+  ctx = isl_union_map_get_ctx(PartialSchedule);
+  Space = isl_union_map_get_space(PartialSchedule);
+
+  TileMap = getTileMap(ctx, *Dimensions, Space);
+  TileUMap = isl_union_map_from_map(isl_map_from_basic_map(TileMap));
+  TileUMap = isl_union_map_align_params(TileUMap, Space);
+  *Dimensions = 2 * *Dimensions;
+
+  return isl_union_map_apply_range(PartialSchedule, TileUMap);
+}
+
+isl_map *IslScheduleOptimizer::getPrevectorMap(isl_ctx *ctx, int DimToVectorize,
+                                               int ScheduleDimensions,
+                                               int VectorWidth) {
+  isl_space *Space;
+  isl_local_space *LocalSpace, *LocalSpaceRange;
+  isl_set *Modulo;
+  isl_map *TilingMap;
+  isl_constraint *c;
+  isl_aff *Aff;
+  int PointDimension; /* ip */
+  int TileDimension;  /* it */
+  isl_val *VectorWidthMP;
+
+  assert(0 <= DimToVectorize && DimToVectorize < ScheduleDimensions);
+
+  Space = isl_space_alloc(ctx, 0, ScheduleDimensions, ScheduleDimensions + 1);
+  TilingMap = isl_map_universe(isl_space_copy(Space));
+  LocalSpace = isl_local_space_from_space(Space);
+  PointDimension = ScheduleDimensions;
+  TileDimension = DimToVectorize;
+
+  // Create an identity map for everything except DimToVectorize and map
+  // DimToVectorize to the point loop at the innermost dimension.
+  for (int i = 0; i < ScheduleDimensions; i++) {
+    c = isl_equality_alloc(isl_local_space_copy(LocalSpace));
+    isl_constraint_set_coefficient_si(c, isl_dim_in, i, -1);
+
+    if (i == DimToVectorize)
+      isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, 1);
+    else
+      isl_constraint_set_coefficient_si(c, isl_dim_out, i, 1);
+
+    TilingMap = isl_map_add_constraint(TilingMap, c);
+  }
+
+  // it % 'VectorWidth' = 0
+  LocalSpaceRange = isl_local_space_range(isl_local_space_copy(LocalSpace));
+  Aff = isl_aff_zero_on_domain(LocalSpaceRange);
+  Aff = isl_aff_set_constant_si(Aff, VectorWidth);
+  Aff = isl_aff_set_coefficient_si(Aff, isl_dim_in, TileDimension, 1);
+  VectorWidthMP = isl_val_int_from_si(ctx, VectorWidth);
+  Aff = isl_aff_mod_val(Aff, VectorWidthMP);
+  Modulo = isl_pw_aff_zero_set(isl_pw_aff_from_aff(Aff));
+  TilingMap = isl_map_intersect_range(TilingMap, Modulo);
+
+  // it <= ip
+  c = isl_inequality_alloc(isl_local_space_copy(LocalSpace));
+  isl_constraint_set_coefficient_si(c, isl_dim_out, TileDimension, -1);
+  isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, 1);
+  TilingMap = isl_map_add_constraint(TilingMap, c);
+
+  // ip <= it + ('VectorWidth' - 1)
+  c = isl_inequality_alloc(LocalSpace);
+  isl_constraint_set_coefficient_si(c, isl_dim_out, TileDimension, 1);
+  isl_constraint_set_coefficient_si(c, isl_dim_out, PointDimension, -1);
+  isl_constraint_set_constant_si(c, VectorWidth - 1);
+  TilingMap = isl_map_add_constraint(TilingMap, c);
+
+  return TilingMap;
+}
+
+isl_union_map *
+IslScheduleOptimizer::getScheduleForBandList(isl_band_list *BandList) {
+  int NumBands;
+  isl_union_map *Schedule;
+  isl_ctx *ctx;
+
+  ctx = isl_band_list_get_ctx(BandList);
+  NumBands = isl_band_list_n_band(BandList);
+  Schedule = isl_union_map_empty(isl_space_params_alloc(ctx, 0));
+
+  for (int i = 0; i < NumBands; i++) {
+    isl_band *Band;
+    isl_union_map *PartialSchedule;
+    int ScheduleDimensions;
+    isl_space *Space;
+
+    Band = isl_band_list_get_band(BandList, i);
+    PartialSchedule = getScheduleForBand(Band, &ScheduleDimensions);
+    Space = isl_union_map_get_space(PartialSchedule);
+
+    if (isl_band_has_children(Band)) {
+      isl_band_list *Children;
+      isl_union_map *SuffixSchedule;
+
+      Children = isl_band_get_children(Band);
+      SuffixSchedule = getScheduleForBandList(Children);
+      PartialSchedule =
+          isl_union_map_flat_range_product(PartialSchedule, SuffixSchedule);
+      isl_band_list_free(Children);
+    } else if (PollyVectorizerChoice != VECTORIZER_NONE) {
+      // In case we are at the innermost band, we try to prepare for
+      // vectorization. This means, we look for the innermost parallel loop
+      // and strip mine this loop to the innermost level using a strip-mine
+      // factor corresponding to the number of vector iterations.
+      int NumDims = isl_band_n_member(Band);
+      for (int j = NumDims - 1; j >= 0; j--) {
+        if (isl_band_member_is_coincident(Band, j)) {
+          isl_map *TileMap;
+          isl_union_map *TileUMap;
+
+          TileMap = getPrevectorMap(ctx, ScheduleDimensions - NumDims + j,
+                                    ScheduleDimensions);
+          TileUMap = isl_union_map_from_map(TileMap);
+          TileUMap =
+              isl_union_map_align_params(TileUMap, isl_space_copy(Space));
+          PartialSchedule =
+              isl_union_map_apply_range(PartialSchedule, TileUMap);
+          break;
+        }
+      }
+    }
+
+    Schedule = isl_union_map_union(Schedule, PartialSchedule);
+
+    isl_band_free(Band);
+    isl_space_free(Space);
+  }
+
+  return Schedule;
+}
+
+isl_union_map *IslScheduleOptimizer::getScheduleMap(isl_schedule *Schedule) {
+  isl_band_list *BandList = isl_schedule_get_band_forest(Schedule);
+  isl_union_map *ScheduleMap = getScheduleForBandList(BandList);
+  isl_band_list_free(BandList);
+  return ScheduleMap;
+}
+
+bool IslScheduleOptimizer::runOnScop(Scop &S) {
+  Dependences *D = &getAnalysis<Dependences>();
+
+  if (!D->hasValidDependences())
+    return false;
+
+  isl_schedule_free(LastSchedule);
+  LastSchedule = nullptr;
+
+  // Build input data.
+  int ValidityKinds =
+      Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+  int ProximityKinds;
+
+  if (OptimizeDeps == "all")
+    ProximityKinds =
+        Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+  else if (OptimizeDeps == "raw")
+    ProximityKinds = Dependences::TYPE_RAW;
+  else {
+    errs() << "Do not know how to optimize for '" << OptimizeDeps << "'"
+           << " Falling back to optimizing all dependences.\n";
+    ProximityKinds =
+        Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+  }
+
+  isl_union_set *Domain = S.getDomains();
+
+  if (!Domain)
+    return false;
+
+  isl_union_map *Validity = D->getDependences(ValidityKinds);
+  isl_union_map *Proximity = D->getDependences(ProximityKinds);
+
+  // Simplify the dependences by removing the constraints introduced by the
+  // domains. This can speed up the scheduling time significantly, as large
+  // constant coefficients will be removed from the dependences. The
+  // introduction of some additional dependences reduces the possible
+  // transformations, but in most cases, such transformation do not seem to be
+  // interesting anyway. In some cases this option may stop the scheduler to
+  // find any schedule.
+  if (SimplifyDeps == "yes") {
+    Validity = isl_union_map_gist_domain(Validity, isl_union_set_copy(Domain));
+    Validity = isl_union_map_gist_range(Validity, isl_union_set_copy(Domain));
+    Proximity =
+        isl_union_map_gist_domain(Proximity, isl_union_set_copy(Domain));
+    Proximity = isl_union_map_gist_range(Proximity, isl_union_set_copy(Domain));
+  } else if (SimplifyDeps != "no") {
+    errs() << "warning: Option -polly-opt-simplify-deps should either be 'yes' "
+              "or 'no'. Falling back to default: 'yes'\n";
+  }
+
+  DEBUG(dbgs() << "\n\nCompute schedule from: ");
+  DEBUG(dbgs() << "Domain := "; isl_union_set_dump(Domain); dbgs() << ";\n");
+  DEBUG(dbgs() << "Proximity := "; isl_union_map_dump(Proximity);
+        dbgs() << ";\n");
+  DEBUG(dbgs() << "Validity := "; isl_union_map_dump(Validity);
+        dbgs() << ";\n");
+
+  int IslFusionStrategy;
+
+  if (FusionStrategy == "max") {
+    IslFusionStrategy = ISL_SCHEDULE_FUSE_MAX;
+  } else if (FusionStrategy == "min") {
+    IslFusionStrategy = ISL_SCHEDULE_FUSE_MIN;
+  } else {
+    errs() << "warning: Unknown fusion strategy. Falling back to maximal "
+              "fusion.\n";
+    IslFusionStrategy = ISL_SCHEDULE_FUSE_MAX;
+  }
+
+  int IslMaximizeBands;
+
+  if (MaximizeBandDepth == "yes") {
+    IslMaximizeBands = 1;
+  } else if (MaximizeBandDepth == "no") {
+    IslMaximizeBands = 0;
+  } else {
+    errs() << "warning: Option -polly-opt-maximize-bands should either be 'yes'"
+              " or 'no'. Falling back to default: 'yes'\n";
+    IslMaximizeBands = 1;
+  }
+
+  isl_options_set_schedule_fuse(S.getIslCtx(), IslFusionStrategy);
+  isl_options_set_schedule_maximize_band_depth(S.getIslCtx(), IslMaximizeBands);
+  isl_options_set_schedule_max_constant_term(S.getIslCtx(), MaxConstantTerm);
+  isl_options_set_schedule_max_coefficient(S.getIslCtx(), MaxCoefficient);
+
+  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE);
+
+  isl_schedule_constraints *ScheduleConstraints;
+  ScheduleConstraints = isl_schedule_constraints_on_domain(Domain);
+  ScheduleConstraints =
+      isl_schedule_constraints_set_proximity(ScheduleConstraints, Proximity);
+  ScheduleConstraints = isl_schedule_constraints_set_validity(
+      ScheduleConstraints, isl_union_map_copy(Validity));
+  ScheduleConstraints =
+      isl_schedule_constraints_set_coincidence(ScheduleConstraints, Validity);
+  isl_schedule *Schedule;
+  Schedule = isl_schedule_constraints_compute_schedule(ScheduleConstraints);
+  isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT);
+
+  // In cases the scheduler is not able to optimize the code, we just do not
+  // touch the schedule.
+  if (!Schedule)
+    return false;
+
+  DEBUG(dbgs() << "Schedule := "; isl_schedule_dump(Schedule); dbgs() << ";\n");
+
+  isl_union_map *ScheduleMap = getScheduleMap(Schedule);
+
+  for (ScopStmt *Stmt : S) {
+    isl_map *StmtSchedule;
+    isl_set *Domain = Stmt->getDomain();
+    isl_union_map *StmtBand;
+    StmtBand = isl_union_map_intersect_domain(isl_union_map_copy(ScheduleMap),
+                                              isl_union_set_from_set(Domain));
+    if (isl_union_map_is_empty(StmtBand)) {
+      StmtSchedule = isl_map_from_domain(isl_set_empty(Stmt->getDomainSpace()));
+      isl_union_map_free(StmtBand);
+    } else {
+      assert(isl_union_map_n_map(StmtBand) == 1);
+      StmtSchedule = isl_map_from_union_map(StmtBand);
+    }
+
+    Stmt->setScattering(StmtSchedule);
+  }
+
+  isl_union_map_free(ScheduleMap);
+  LastSchedule = Schedule;
+
+  unsigned MaxScatDims = 0;
+
+  for (ScopStmt *Stmt : S)
+    MaxScatDims = std::max(Stmt->getNumScattering(), MaxScatDims);
+
+  extendScattering(S, MaxScatDims);
+  return false;
+}
+
+void IslScheduleOptimizer::printScop(raw_ostream &OS) const {
+  isl_printer *p;
+  char *ScheduleStr;
+
+  OS << "Calculated schedule:\n";
+
+  if (!LastSchedule) {
+    OS << "n/a\n";
+    return;
+  }
+
+  p = isl_printer_to_str(isl_schedule_get_ctx(LastSchedule));
+  p = isl_printer_print_schedule(p, LastSchedule);
+  ScheduleStr = isl_printer_get_str(p);
+  isl_printer_free(p);
+
+  OS << ScheduleStr << "\n";
+}
+
+void IslScheduleOptimizer::getAnalysisUsage(AnalysisUsage &AU) const {
+  ScopPass::getAnalysisUsage(AU);
+  AU.addRequired<Dependences>();
+}
+
+Pass *polly::createIslScheduleOptimizerPass() {
+  return new IslScheduleOptimizer();
+}
+
+INITIALIZE_PASS_BEGIN(IslScheduleOptimizer, "polly-opt-isl",
+                      "Polly - Optimize schedule of SCoP", false, false);
+INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(ScopInfo);
+INITIALIZE_PASS_END(IslScheduleOptimizer, "polly-opt-isl",
+                    "Polly - Optimize schedule of SCoP", false, false)
diff --git a/rc1/test/CMakeLists.txt b/rc1/test/CMakeLists.txt
new file mode 100644
index 0000000..a31562b
--- /dev/null
+++ b/rc1/test/CMakeLists.txt
@@ -0,0 +1,88 @@
+set(POLLY_TEST_DIRECTORIES
+  "AffineIterator"
+  "ScopInfo"
+  "ScheduleOptimizer"
+  "CodeGen"
+  "Cloog"
+  "OpenMP"
+  "polybench"
+  "vect")
+
+
+set(POLLY_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
+set(POLLY_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..")
+set(LLVM_SHLIBEXT "${CMAKE_SHARED_MODULE_SUFFIX}")
+
+if (NOT DEFINED LLVM_MAIN_SRC_DIR)
+
+  # We are building polly out of tree, adjust the settings.
+  # FIXME: FileCheck is not available in llvm install directory at the moment.
+  set(LLVM_LIT ${LLVM_INSTALL_ROOT}/bin/llvm-lit)
+  set(POLLY_TEST_DEPS LLVMPolly)
+
+  set(LLVM_BINARY_DIR "${LLVM_INSTALL_ROOT}")
+  set(LLVM_TOOLS_DIR "${LLVM_INSTALL_ROOT}/bin")
+  set(LLVM_LIBS_DIR "${LLVM_INSTALL_ROOT}/lib")
+  set(POLLY_LIB_DIR "${POLLY_BINARY_DIR}/lib")
+
+  include(FindPythonInterp)
+  if(PYTHONINTERP_FOUND)
+    option(POLLY_TEST_DISABLE_BAR "Run Polly tests with --no-progress-bar" OFF)
+    set(POLLY_TEST_EXTRA_ARGS)
+    if (MSVC OR XCODE OR POLLY_TEST_DISABLE_BAR)
+      set(POLLY_TEST_EXTRA_ARGS "--no-progress-bar")
+    endif()
+
+    option(POLLY_TEST_USE_VG "Run Polly tests under Valgrind" OFF)
+    if(POLLY_TEST_USE_VG)
+      set(POLLY_TEST_EXTRA_ARGS ${POLLY_TEST_EXTRA_ARGS} "--vg")
+    endif ()
+
+    foreach(testdir ${POLLY_TEST_DIRECTORIES})
+      add_custom_target(polly-test-${testdir}
+        COMMAND ${LLVM_LIT}
+                    --param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+                    --param build_config=${CMAKE_CFG_INTDIR}
+                    -sv ${POLLY_TEST_EXTRA_ARGS}
+                    ${CMAKE_CURRENT_BINARY_DIR}/${testdir}
+                    DEPENDS ${POLLY_TEST_DEPS}
+                    COMMENT "Running Polly regression tests in ${testdir}")
+    endforeach()
+
+    add_custom_target(check-polly
+      COMMAND ${LLVM_LIT}
+                  --param polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+                  --param build_config=${CMAKE_CFG_INTDIR}
+                  -sv ${POLLY_TEST_EXTRA_ARGS}
+                  ${CMAKE_CURRENT_BINARY_DIR}
+                  DEPENDS ${POLLY_TEST_DEPS}
+                  COMMENT "Running Polly regression tests")
+  endif()
+
+else (NOT DEFINED LLVM_MAIN_SRC_DIR)
+
+  set(LLVM_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit)
+  set(POLLY_TEST_DEPS llvm-config opt LLVMPolly FileCheck not)
+
+  set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}")
+  set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}")
+  set(LLVM_LIBS_DIR "${LLVM_BINARY_DIR}/lib")
+  set(POLLY_LIB_DIR "${LLVM_LIBS_DIR}")
+
+  add_lit_testsuite(check-polly "Running polly regression tests"
+    ${CMAKE_CURRENT_BINARY_DIR}
+    PARAMS polly_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
+    DEPENDS ${POLLY_TEST_DEPS}
+    )
+
+  set_target_properties(check-polly PROPERTIES FOLDER "polly tests")
+
+endif (NOT DEFINED LLVM_MAIN_SRC_DIR)
+
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+  ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)
+
+# Add a legacy target spelling: polly-test
+add_custom_target(polly-test)
+add_dependencies(polly-test check-polly)
diff --git a/rc1/test/Cloog/CodeGen/20100617.ll b/rc1/test/Cloog/CodeGen/20100617.ll
new file mode 100644
index 0000000..f9837cc
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100617.ll
@@ -0,0 +1,19 @@
+; 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 @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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100622.ll b/rc1/test/Cloog/CodeGen/20100622.ll
new file mode 100644
index 0000000..f643f84
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100622.ll
@@ -0,0 +1,43 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze  < %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"
+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:
diff --git a/rc1/test/Cloog/CodeGen/20100707.ll b/rc1/test/Cloog/CodeGen/20100707.ll
new file mode 100644
index 0000000..a6fe774
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100707.ll
@@ -0,0 +1,27 @@
+; 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 @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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100707_2.ll b/rc1/test/Cloog/CodeGen/20100707_2.ll
new file mode 100644
index 0000000..557a763
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100707_2.ll
@@ -0,0 +1,115 @@
+; 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"
+
+@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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100708_2.ll b/rc1/test/Cloog/CodeGen/20100708_2.ll
new file mode 100644
index 0000000..2719418
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100708_2.ll
@@ -0,0 +1,28 @@
+; 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 @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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100713.ll b/rc1/test/Cloog/CodeGen/20100713.ll
new file mode 100644
index 0000000..ad014c4
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100713.ll
@@ -0,0 +1,34 @@
+; 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 @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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100713_2.ll b/rc1/test/Cloog/CodeGen/20100713_2.ll
new file mode 100644
index 0000000..a8ad7e1
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100713_2.ll
@@ -0,0 +1,34 @@
+; 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 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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100717.ll b/rc1/test/Cloog/CodeGen/20100717.ll
new file mode 100644
index 0000000..123db6c
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100717.ll
@@ -0,0 +1,39 @@
+; 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 @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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100718-DomInfo-2.ll b/rc1/test/Cloog/CodeGen/20100718-DomInfo-2.ll
new file mode 100644
index 0000000..8dc279b
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100718-DomInfo-2.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -verify-dom-info -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 @getNonAffNeighbour() nounwind {
+entry:
+  br i1 undef, label %bb, label %bb6
+
+bb:                                               ; preds = %entry
+  br i1 false, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  br label %bb16
+
+bb2:                                              ; preds = %bb
+  br i1 false, label %bb3, label %bb4
+
+bb3:                                              ; preds = %bb2
+  br label %bb16
+
+bb4:                                              ; preds = %bb2
+  br label %bb16
+
+bb6:                                              ; preds = %entry
+  br i1 false, label %bb7, label %bb9
+
+bb7:                                              ; preds = %bb6
+  br label %bb16
+
+bb9:                                              ; preds = %bb6
+  br label %bb16
+
+bb16:                                             ; preds = %bb9, %bb7, %bb4, %bb3, %bb1
+  ret void
+}
diff --git a/rc1/test/Cloog/CodeGen/20100718-DomInfo.ll b/rc1/test/Cloog/CodeGen/20100718-DomInfo.ll
new file mode 100644
index 0000000..a036276
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100718-DomInfo.ll
@@ -0,0 +1,28 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -verify-dom-info -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 @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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100720-MultipleConditions.ll b/rc1/test/Cloog/CodeGen/20100720-MultipleConditions.ll
new file mode 100644
index 0000000..c8f31a7
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100720-MultipleConditions.ll
@@ -0,0 +1,97 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze %s
+
+;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];
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; 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: 
diff --git a/rc1/test/Cloog/CodeGen/20100809-IndependentBlock.ll b/rc1/test/Cloog/CodeGen/20100809-IndependentBlock.ll
new file mode 100644
index 0000000..bd440ec
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100809-IndependentBlock.ll
@@ -0,0 +1,31 @@
+; 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
+}
diff --git a/rc1/test/Cloog/CodeGen/20100811-ScalarDependencyBetweenBrAndCnd.ll b/rc1/test/Cloog/CodeGen/20100811-ScalarDependencyBetweenBrAndCnd.ll
new file mode 100644
index 0000000..7421a76
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20100811-ScalarDependencyBetweenBrAndCnd.ll
@@ -0,0 +1,30 @@
+; 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
+}
diff --git a/rc1/test/Cloog/CodeGen/20101030-Overflow.ll b/rc1/test/Cloog/CodeGen/20101030-Overflow.ll
new file mode 100644
index 0000000..e8f1a9a
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20101030-Overflow.ll
@@ -0,0 +1,22 @@
+; 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
+
+}
diff --git a/rc1/test/Cloog/CodeGen/20101103-Overflow3.ll b/rc1/test/Cloog/CodeGen/20101103-Overflow3.ll
new file mode 100644
index 0000000..b56df93
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20101103-Overflow3.ll
@@ -0,0 +1,24 @@
+; 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
+}
diff --git a/rc1/test/Cloog/CodeGen/20101103-signmissmatch.ll b/rc1/test/Cloog/CodeGen/20101103-signmissmatch.ll
new file mode 100644
index 0000000..5821a26
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20101103-signmissmatch.ll
@@ -0,0 +1,38 @@
+; 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
+}
diff --git a/rc1/test/Cloog/CodeGen/20110226-Ignore-Dead-Code.ll b/rc1/test/Cloog/CodeGen/20110226-Ignore-Dead-Code.ll
new file mode 100644
index 0000000..ba90eca
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20110226-Ignore-Dead-Code.ll
@@ -0,0 +1,59 @@
+; 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
+}
diff --git a/rc1/test/Cloog/CodeGen/20110226-PHI-Node-removed.ll b/rc1/test/Cloog/CodeGen/20110226-PHI-Node-removed.ll
new file mode 100644
index 0000000..2263ee4
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20110226-PHI-Node-removed.ll
@@ -0,0 +1,29 @@
+; 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
+}
diff --git a/rc1/test/Cloog/CodeGen/20120316-InvalidCast.ll b/rc1/test/Cloog/CodeGen/20120316-InvalidCast.ll
new file mode 100644
index 0000000..9aa1053
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20120316-InvalidCast.ll
@@ -0,0 +1,20 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %s
+
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32"
+target triple = "hexagon-unknown-linux-gnu"
+
+define void @fixup_gotos(i32* %A, i32* %data) nounwind {
+entry:
+  br label %if
+
+if:
+  %cond = icmp eq i32* %A, null
+  br i1 %cond, label %last, label %then
+
+then:
+  store i32 1, i32* %data, align 4
+  br label %last
+
+last:
+  ret void
+}
diff --git a/rc1/test/Cloog/CodeGen/20120403-RHS-type-mismatch.ll b/rc1/test/Cloog/CodeGen/20120403-RHS-type-mismatch.ll
new file mode 100755
index 0000000..60c06a0
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20120403-RHS-type-mismatch.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly -polly-codegen %s
+
+; We just check that this compilation does not crash.
+
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32"
+target triple = "hexagon-unknown-linux-gnu"
+
+define void @init() nounwind {
+entry:
+  %hi.129.reg2mem = alloca i64
+  br label %for.body
+
+for.cond5.preheader:                              ; preds = %for.body
+  br label %for.body7
+
+for.body:                                         ; preds = %for.body, %entry
+  br i1 undef, label %for.body, label %for.cond5.preheader
+
+for.body7:                                        ; preds = %for.body7, %for.cond5.preheader
+  %i.128 = phi i64 [ 0, %for.cond5.preheader ], [ %inc17, %for.body7 ]
+  %inc17 = add nsw i64 %i.128, 1
+  store i64 undef, i64* %hi.129.reg2mem
+  br i1 false, label %for.body7, label %for.end18
+
+for.end18:                                        ; preds = %for.body7
+  unreachable
+}
diff --git a/rc1/test/Cloog/CodeGen/20140414-vector-codegen.ll b/rc1/test/Cloog/CodeGen/20140414-vector-codegen.ll
new file mode 100644
index 0000000..39255fb
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/20140414-vector-codegen.ll
@@ -0,0 +1,21 @@
+; RUN: opt %loadPolly -polly-codegen -polly-vectorizer=polly < %s
+; PR 19421
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.8.0"
+
+define void @extract_field(i32* %frame, i32 %nb_planes) {
+entry:
+  br i1 undef, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.body, %entry
+  %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
+  %arrayidx2.moved.to.if.end = getelementptr i32* %frame, i64 %indvar
+  %.moved.to.if.end = zext i32 %nb_planes to i64
+  store i32 undef, i32* %arrayidx2.moved.to.if.end
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp ne i64 %indvar.next, %.moved.to.if.end
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body, %entry
+  ret void
+}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/1d_parallel.ll b/rc1/test/Cloog/CodeGen/GPGPU/1d_parallel.ll
new file mode 100644
index 0000000..ae825f8
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/1d_parallel.ll
@@ -0,0 +1,72 @@
+; REQUIRES: nvptx-registered-target
+; RUN: opt %loadPolly -basicaa -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+gpu -enable-polly-gpgpu -polly-gpgpu-triple=nvptx64-unknown-unknown -polly-codegen < %s -S | FileCheck %s
+
+;int A[1024];
+
+;int gpu() {
+;  int i;
+;
+;  for(i = 0; i < 1024; i++)
+;    A[i] = i*128 + 508;
+;
+;  return 0;
+;}
+;
+;int main() {
+;  int b = gpu();
+;  return 0;
+;}
+
+; ModuleID = '1d_parallel.s'
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16
+
+; Function Attrs: nounwind uwtable
+define i32 @gpu() #0 {
+  br label %.split
+
+.split:                                           ; preds = %0
+  br label %1
+
+; <label>:1                                       ; preds = %.split, %1
+  %indvar = phi i64 [ 0, %.split ], [ %indvar.next, %1 ]
+  %2 = mul i64 %indvar, 128
+  %3 = add i64 %2, 508
+  %4 = trunc i64 %3 to i32
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %indvar
+  store i32 %4, i32* %scevgep, align 4
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp ne i64 %indvar.next, 1024
+  br i1 %exitcond, label %1, label %5
+
+; <label>:5                                       ; preds = %1
+  ret i32 0
+}
+
+; Function Attrs: nounwind uwtable
+define i32 @main() #0 {
+  br label %.split
+
+.split:                                           ; preds = %0
+  %1 = tail call i32 @gpu()
+  ret i32 0
+}
+
+; CHECK:  call void @polly_initDevice
+; CHECK:  call void @polly_getPTXModule
+; CHECK:  call void @polly_getPTXKernelEntry
+; CHECK:  call void @polly_allocateMemoryForHostAndDevice
+; CHECK:  call void @polly_setKernelParameters
+; CHECK:  call void @polly_startTimerByCudaEvent
+; CHECK:  call void @polly_launchKernel
+; CHECK:  call void @polly_copyFromDeviceToHost
+; CHECK:  call void @polly_stopTimerByCudaEvent
+; CHECK:  call void @polly_cleanupGPGPUResources
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+
+!0 = metadata !{metadata !"clang version 3.5.0 "}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/2d_innermost_parallel.ll b/rc1/test/Cloog/CodeGen/GPGPU/2d_innermost_parallel.ll
new file mode 100644
index 0000000..d3b2041
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/2d_innermost_parallel.ll
@@ -0,0 +1,83 @@
+; REQUIRES: nvptx-registered-target
+; RUN: opt %loadPolly -basicaa -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+gpu -enable-polly-gpgpu -polly-gpgpu-triple=nvptx64-unknown-unknown -polly-codegen < %s -S | FileCheck %s
+
+;int A[128][128];
+;
+;int gpu_pure() {
+;  int i,j;
+;
+;  for(i = 0; i < 128; i++)
+;    for(j = 0; j < 128; j++)
+;      A[i][j] = i*128 + j;
+;
+;  return 0;
+;}
+;
+;int main() {
+;  int b = gpu_pure();
+;  return 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-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [128 x [128 x i32]] zeroinitializer, align 16
+
+define i32 @gpu_pure() nounwind uwtable {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc6 ], [ 0, %entry ]
+  %lftr.wideiv5 = trunc i64 %indvars.iv2 to i32
+  %exitcond6 = icmp ne i32 %lftr.wideiv5, 128
+  br i1 %exitcond6, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %for.body ]
+  %lftr.wideiv = trunc i64 %indvars.iv to i32
+  %exitcond = icmp ne i32 %lftr.wideiv, 128
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %tmp = shl nsw i64 %indvars.iv2, 7
+  %tmp7 = add nsw i64 %tmp, %indvars.iv
+  %arrayidx5 = getelementptr inbounds [128 x [128 x i32]]* @A, i64 0, i64 %indvars.iv2, i64 %indvars.iv
+  %tmp8 = trunc i64 %tmp7 to i32
+  store i32 %tmp8, i32* %arrayidx5, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %for.end
+  %indvars.iv.next3 = add i64 %indvars.iv2, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  ret i32 0
+}
+
+define i32 @main() nounwind uwtable {
+entry:
+  %call = call i32 @gpu_pure()
+  ret i32 0
+}
+
+; CHECK:  call void @polly_initDevice
+; CHECK:  call void @polly_getPTXModule
+; CHECK:  call void @polly_getPTXKernelEntry
+; CHECK:  call void @polly_allocateMemoryForHostAndDevice
+; CHECK:  call void @polly_setKernelParameters
+; CHECK:  call void @polly_startTimerByCudaEvent
+; CHECK:  call void @polly_launchKernel
+; CHECK:  call void @polly_copyFromDeviceToHost
+; CHECK:  call void @polly_stopTimerByCudaEvent
+; CHECK:  call void @polly_cleanupGPGPUResources
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/3d_innermost_non_parallel.ll b/rc1/test/Cloog/CodeGen/GPGPU/3d_innermost_non_parallel.ll
new file mode 100644
index 0000000..06d282b
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/3d_innermost_non_parallel.ll
@@ -0,0 +1,107 @@
+; REQUIRES: nvptx-registered-target
+; RUN: opt %loadPolly -basicaa -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+gpu -enable-polly-gpgpu -polly-gpgpu-triple=nvptx64-unknown-unknown -polly-codegen < %s -S | FileCheck %s
+
+;int A[128][128];
+;
+;int gpu_no_pure() {
+;  int i,j,k;
+;
+;  for(i = 0; i < 128; i++)
+;    for(j = 0; j < 128; j++)
+;      for(k = 0; k < 256; k++)
+;        A[i][j] += i*123/(k+1)+5-j*k-123;
+;
+;  return 0;
+;}
+;
+;int main() {
+;  int b = gpu_no_pure();
+;  return 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-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [128 x [128 x i32]] zeroinitializer, align 16
+
+define i32 @gpu_no_pure() nounwind uwtable {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc16, %entry
+  %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc16 ], [ 0, %entry ]
+  %lftr.wideiv5 = trunc i64 %indvars.iv2 to i32
+  %exitcond6 = icmp ne i32 %lftr.wideiv5, 128
+  br i1 %exitcond6, label %for.body, label %for.end18
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc13, %for.body
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc13 ], [ 0, %for.body ]
+  %lftr.wideiv = trunc i64 %indvars.iv to i32
+  %exitcond1 = icmp ne i32 %lftr.wideiv, 128
+  br i1 %exitcond1, label %for.body3, label %for.end15
+
+for.body3:                                        ; preds = %for.cond1
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %k.0, 256
+  br i1 %exitcond, label %for.body6, label %for.end
+
+for.body6:                                        ; preds = %for.cond4
+  %tmp = mul nsw i64 %indvars.iv2, 123
+  %add = add nsw i32 %k.0, 1
+  %tmp7 = trunc i64 %tmp to i32
+  %div = sdiv i32 %tmp7, %add
+  %add7 = add nsw i32 %div, 5
+  %tmp8 = trunc i64 %indvars.iv to i32
+  %mul8 = mul nsw i32 %tmp8, %k.0
+  %sub = sub nsw i32 %add7, %mul8
+  %sub9 = add nsw i32 %sub, -123
+  %arrayidx11 = getelementptr inbounds [128 x [128 x i32]]* @A, i64 0, i64 %indvars.iv2, i64 %indvars.iv
+  %tmp9 = load i32* %arrayidx11, align 4
+  %add12 = add nsw i32 %tmp9, %sub9
+  store i32 %add12, i32* %arrayidx11, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body6
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond4
+
+for.end:                                          ; preds = %for.cond4
+  br label %for.inc13
+
+for.inc13:                                        ; preds = %for.end
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  br label %for.cond1
+
+for.end15:                                        ; preds = %for.cond1
+  br label %for.inc16
+
+for.inc16:                                        ; preds = %for.end15
+  %indvars.iv.next3 = add i64 %indvars.iv2, 1
+  br label %for.cond
+
+for.end18:                                        ; preds = %for.cond
+  ret i32 0
+}
+
+define i32 @main() nounwind uwtable {
+entry:
+  %call = call i32 @gpu_no_pure()
+  ret i32 0
+}
+
+; CHECK:  call void @polly_initDevice
+; CHECK:  call void @polly_getPTXModule
+; CHECK:  call void @polly_getPTXKernelEntry
+; CHECK:  call void @polly_allocateMemoryForHostAndDevice
+; CHECK:  call void @polly_setKernelParameters
+; CHECK:  call void @polly_startTimerByCudaEvent
+; CHECK:  call void @polly_launchKernel
+; CHECK:  call void @polly_copyFromDeviceToHost
+; CHECK:  call void @polly_stopTimerByCudaEvent
+; CHECK:  call void @polly_cleanupGPGPUResources
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/gpu___%1---%5.jscop b/rc1/test/Cloog/CodeGen/GPGPU/gpu___%1---%5.jscop
new file mode 100644
index 0000000..146b0c8
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/gpu___%1---%5.jscop
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "%1 => %5",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_1[i0] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_1[i0] : i0 >= 0 and i0 <= 1023 }",
+         "name" : "Stmt_1",
+         "schedule" : "{ Stmt_1[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/gpu___%1---%5.jscop.transformed+gpu b/rc1/test/Cloog/CodeGen/GPGPU/gpu___%1---%5.jscop.transformed+gpu
new file mode 100644
index 0000000..965058b
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/gpu___%1---%5.jscop.transformed+gpu
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "%1 => %5",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_1[i0] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_1[i0] : i0 >= 0 and i0 <= 1023 }",
+         "name" : "Stmt_1",
+         "schedule" : "{ Stmt_1[i0] -> scattering[0, o0, o1, o2, o3] : o0 >= 0 and o0 <= 1 and o1 >= 0 and o1 <= 1 and o2 >= 0 and o2 <= 15 and o3 >= 0 and o3 <= 15 and i0 = 512o0 + 256o1 + 16o2 + o3 }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/gpu_no_pure___%for.cond---%for.end18.jscop b/rc1/test/Cloog/CodeGen/GPGPU/gpu_no_pure___%for.cond---%for.end18.jscop
new file mode 100644
index 0000000..0d7a260
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/gpu_no_pure___%for.cond---%for.end18.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end18",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[128i0 + i1] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[128i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body6[i0, i1, i2] : i0 >= 0 and i0 <= 127 and i1 >= 0 and i1 <= 127 and i2 >= 0 and i2 <= 255 }",
+         "name" : "Stmt_for_body6",
+         "schedule" : "{ Stmt_for_body6[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/gpu_no_pure___%for.cond---%for.end18.jscop.transformed+gpu b/rc1/test/Cloog/CodeGen/GPGPU/gpu_no_pure___%for.cond---%for.end18.jscop.transformed+gpu
new file mode 100644
index 0000000..6f007fa
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/gpu_no_pure___%for.cond---%for.end18.jscop.transformed+gpu
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end18",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[128i0 + i1] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[128i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body6[i0, i1, i2] : i0 >= 0 and i0 <= 127 and i1 >= 0 and i1 <= 127 and i2 >= 0 and i2 <= 255 }",
+         "name" : "Stmt_for_body6",
+         "schedule" : "{ Stmt_for_body6[i0, i1, i2] -> scattering[0, o0, o1, o2, o3, i2, 0] : o0 >= 0 and o0 <= 7 and o1 >= 0 and o1 <= 15 and o2 >= 0 and o2 <= 7 and o3 >= 0 and o3 <= 15 and i0 = 16o0 + o1 and i1 = 16o2 + o3 }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/gpu_pure___%for.cond---%for.end8.jscop b/rc1/test/Cloog/CodeGen/GPGPU/gpu_pure___%for.cond---%for.end8.jscop
new file mode 100644
index 0000000..693c509
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/gpu_pure___%for.cond---%for.end8.jscop
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end8",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[128i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 127 and i1 >= 0 and i1 <= 127 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/gpu_pure___%for.cond---%for.end8.jscop.transformed+gpu b/rc1/test/Cloog/CodeGen/GPGPU/gpu_pure___%for.cond---%for.end8.jscop.transformed+gpu
new file mode 100644
index 0000000..fef6105
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/gpu_pure___%for.cond---%for.end8.jscop.transformed+gpu
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end8",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[128i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 127 and i1 >= 0 and i1 <= 127 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, o0, o1, o2, o3]: o0 >= 0 and o0 <= 7 and o1 >= 0 and o1 <= 15 and o2 >= 0 and o2 <= 7 and o3 >= 0 and o3 <= 15 and i0 = 16o0 + o1 and i1 = 16o2 + o3 }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/GPGPU/lit.local.cfg b/rc1/test/Cloog/CodeGen/GPGPU/lit.local.cfg
new file mode 100644
index 0000000..cc94d23
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/GPGPU/lit.local.cfg
@@ -0,0 +1,5 @@
+config.suffixes = ['.ll']
+
+gpgpu = config.root.enable_gpgpu_codegen
+if gpgpu not in ['TRUE', 'true', 'yes', 'YES']:
+    config.unsupported = True
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset.ll b/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset.ll
new file mode 100644
index 0000000..f19aed3
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset.ll
@@ -0,0 +1,43 @@
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen -instnamer < %s -S | FileCheck %s
+
+;int A[100];
+;
+;int codegen_constant_offset() {
+;  for (int i = 0; i < 12; i++)
+;    A[13] = A[i] + A[i-1];
+;
+;  return 0;
+;}
+
+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 [100 x i32] zeroinitializer, align 4
+
+define i32 @codegen_constant_offset() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %tmp1 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %tmp = add i32 %tmp1, -1
+  %arrayidx4 = getelementptr [100 x i32]* @A, i32 0, i32 %tmp
+  %arrayidx = getelementptr [100 x i32]* @A, i32 0, i32 %tmp1
+  %exitcond = icmp ne i32 %tmp1, 12
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %tmp2 = load i32* %arrayidx, align 4
+  %tmp5 = load i32* %arrayidx4, align 4
+  %add = add nsw i32 %tmp2, %tmp5
+  store i32 %add, i32* getelementptr inbounds ([100 x i32]* @A, i32 0, i32 13), align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %tmp1, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret i32 0
+}
+; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i64 0, i64 10)
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset___%for.cond---%for.end.jscop b/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset___%for.cond---%for.end.jscop
new file mode 100644
index 0000000..bf39e59
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset___%for.cond---%for.end.jscop
@@ -0,0 +1,25 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[-1 + i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[13] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset___%for.cond---%for.end.jscop.transformed b/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset___%for.cond---%for.end.jscop.transformed
new file mode 100644
index 0000000..e41a9d6
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_constant_offset___%for.cond---%for.end.jscop.transformed
@@ -0,0 +1,25 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[10] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[-1 + i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[13] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple.ll b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple.ll
new file mode 100644
index 0000000..3119ed4
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple.ll
@@ -0,0 +1,43 @@
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen -instnamer < %s -S | FileCheck %s
+
+;int A[100];
+;
+;int codegen_simple () {
+;  for (int i = 0; i < 12; i++)
+;    A[13] = A[i] + A[i-1];
+;
+;  return 0;
+;}
+
+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 [100 x i32] zeroinitializer, align 4
+
+define i32 @codegen_simple() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %tmp1 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %tmp = add i32 %tmp1, -1
+  %arrayidx4 = getelementptr [100 x i32]* @A, i32 0, i32 %tmp
+  %arrayidx = getelementptr [100 x i32]* @A, i32 0, i32 %tmp1
+  %exitcond = icmp ne i32 %tmp1, 12
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %tmp2 = load i32* %arrayidx, align 4
+  %tmp5 = load i32* %arrayidx4, align 4
+  %add = add nsw i32 %tmp2, %tmp5
+  store i32 %add, i32* getelementptr inbounds ([100 x i32]* @A, i32 0, i32 13), align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %tmp1, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret i32 0
+}
+; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i64 0, i64 0)
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple___%for.cond---%for.end.jscop b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple___%for.cond---%for.end.jscop
new file mode 100644
index 0000000..bf39e59
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple___%for.cond---%for.end.jscop
@@ -0,0 +1,25 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[-1 + i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[13] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple___%for.cond---%for.end.jscop.transformed b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple___%for.cond---%for.end.jscop.transformed
new file mode 100644
index 0000000..a2bed30
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple___%for.cond---%for.end.jscop.transformed
@@ -0,0 +1,25 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[-1 + i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[13] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md.ll b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md.ll
new file mode 100644
index 0000000..132f70f
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md.ll
@@ -0,0 +1,74 @@
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withconst -polly-codegen < %s -S | FileCheck -check-prefix=WITHCONST %s
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withoutconst -polly-codegen < %s -S | FileCheck -check-prefix=WITHOUTCONST %s
+
+;int A[1040];
+;
+;int codegen_simple_md() {
+;  for (int i = 0; i < 32; ++i)
+;    for (int j = 0; j < 32; ++j)
+;      A[32*i+j] = 100;
+;
+;  return 0;
+;}
+
+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-S128"
+target triple = "i386-pc-linux-gnu"
+
+@A = common global [1040 x i32] zeroinitializer, align 4
+
+define i32 @codegen_simple_md() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %exitcond1 = icmp ne i32 %i.0, 32
+  br i1 %exitcond1, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 32
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %mul = shl nsw i32 %i.0, 5
+  %add = add nsw i32 %mul, %j.0
+  %arrayidx = getelementptr inbounds [1040 x i32]* @A, i32 0, i32 %add
+  store i32 100, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret i32 0
+}
+
+; WITHCONST:  [[REG1:%[0-9]+]] = sext i32 %{{[0-9]+}} to i64
+; WITHCONST:  %p_mul_coeff = mul i64 16, [[REG1]]
+; WITHCONST:  %p_sum_coeff = add i64 5, %p_mul_coeff
+; WITHCONST:  [[REG2:%[0-9]+]] = sext i32 %{{[0-9]+}} to i64
+; WITHCONST:  %p_mul_coeff8 = mul i64 2, [[REG2]]
+; WITHCONST:  %p_sum_coeff9 = add i64 %p_sum_coeff, %p_mul_coeff8
+; WITHCONST:  %p_newarrayidx_ = getelementptr [1040 x i32]* @A, i64 0, i64 %p_sum_coeff9
+; WITHCONST:  store i32 100, i32* %p_newarrayidx_
+
+; WITHOUTCONST:  [[REG1:%[0-9]+]] = sext i32 %{{[0-9]+}} to i64
+; WITHOUTCONST:  %p_mul_coeff = mul i64 16, [[REG1]]
+; WITHOUTCONST:  %p_sum_coeff = add i64 0, %p_mul_coeff
+; WITHOUTCONST:  [[REG2:%[0-9]+]] = sext i32 %{{[0-9]+}} to i64
+; WITHOUTCONST:  %p_mul_coeff8 = mul i64 2, [[REG2]]
+; WITHOUTCONST:  %p_sum_coeff9 = add i64 %p_sum_coeff, %p_mul_coeff8
+; WITHOUTCONST:  %p_newarrayidx_ = getelementptr [1040 x i32]* @A, i64 0, i64 %p_sum_coeff9
+; WITHOUTCONST:  store i32 100, i32* %p_newarrayidx_
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop
new file mode 100644
index 0000000..180c44f
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[32i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 31 and i1 >= 0 and i1 <= 31 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withconst b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withconst
new file mode 100644
index 0000000..0894776
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withconst
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[16i0 + 2i1 + 5] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 31 and i1 >= 0 and i1 <= 31 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withoutconst b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withoutconst
new file mode 100644
index 0000000..e1fa4ed
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/codegen_simple_md___%for.cond---%for.end6.jscop.transformed+withoutconst
@@ -0,0 +1,17 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[16i0 + 2i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 31 and i1 >= 0 and i1 <= 31 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/simple.ll b/rc1/test/Cloog/CodeGen/MemAccess/simple.ll
new file mode 100644
index 0000000..f665652
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/simple.ll
@@ -0,0 +1,66 @@
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -stats < %s 2>&1  | FileCheck %s
+; REQUIRES: asserts
+
+;int A[100];
+;int B[100];
+;
+;int simple()
+;{
+;  int i, j;
+;  for (i = 0; i < 12; i++) {
+;      A[i] = i;
+;  }
+;
+;  for (i = 0; i < 12; i++) {
+;      B[i] = i;
+;  }
+;
+;  return 0;
+;}
+;
+
+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 [100 x i32] zeroinitializer, align 4
+@B = common global [100 x i32] zeroinitializer, align 4
+
+define i32 @simple() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %arrayidx = getelementptr [100 x i32]* @A, i32 0, i32 %0
+  %exitcond1 = icmp ne i32 %0, 12
+  br i1 %exitcond1, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  store i32 %0, i32* %arrayidx
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc11, %for.end
+  %1 = phi i32 [ 0, %for.end ], [ %inc13, %for.inc11 ]
+  %arrayidx10 = getelementptr [100 x i32]* @B, i32 0, i32 %1
+  %exitcond = icmp ne i32 %1, 12
+  br i1 %exitcond, label %for.body7, label %for.end14
+
+for.body7:                                        ; preds = %for.cond4
+  store i32 %1, i32* %arrayidx10
+  br label %for.inc11
+
+for.inc11:                                        ; preds = %for.body7
+  %inc13 = add nsw i32 %1, 1
+  br label %for.cond4
+
+for.end14:                                        ; preds = %for.cond4
+  ret i32 0
+}
+; CHECK: 2 polly-import-jscop
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond---%for.end.jscop b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond---%for.end.jscop
new file mode 100644
index 0000000..ccee1cb
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond---%for.end.jscop
@@ -0,0 +1,17 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond---%for.end.jscop.transformed b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond---%for.end.jscop.transformed
new file mode 100644
index 0000000..a9853bd
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond---%for.end.jscop.transformed
@@ -0,0 +1,17 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond4---%for.end14.jscop b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond4---%for.end14.jscop
new file mode 100644
index 0000000..0794c01
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond4---%for.end14.jscop
@@ -0,0 +1,17 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond4 => for.end14",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body7[i0] -> MemRef_B[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body7[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body7",
+         "schedule" : "{ Stmt_for_body7[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond4---%for.end14.jscop.transformed b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond4---%for.end14.jscop.transformed
new file mode 100644
index 0000000..5df6c36
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/simple___%for.cond4---%for.end14.jscop.transformed
@@ -0,0 +1,17 @@
+{
+   "context" : "{ [] }",
+   "name" : "for.cond4 => for.end14",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body7[i0] -> MemRef_B[0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body7[i0] : i0 >= 0 and i0 <= 11 }",
+         "name" : "Stmt_for_body7",
+         "schedule" : "{ Stmt_for_body7[i0] -> scattering[0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/MemAccess/simple_analyze.ll b/rc1/test/Cloog/CodeGen/MemAccess/simple_analyze.ll
new file mode 100644
index 0000000..f217ff6
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/MemAccess/simple_analyze.ll
@@ -0,0 +1,47 @@
+;RUN: opt %loadPolly -polly-import-jscop -analyze -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed < %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 [100 x i32] zeroinitializer, align 4
+@B = common global [100 x i32] zeroinitializer, align 4
+
+define i32 @simple() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %arrayidx = getelementptr [100 x i32]* @A, i32 0, i32 %0
+  %exitcond1 = icmp ne i32 %0, 12
+  br i1 %exitcond1, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  store i32 %0, i32* %arrayidx
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc11, %for.end
+  %1 = phi i32 [ 0, %for.end ], [ %inc13, %for.inc11 ]
+  %arrayidx10 = getelementptr [100 x i32]* @B, i32 0, i32 %1
+  %exitcond = icmp ne i32 %1, 12
+  br i1 %exitcond, label %for.body7, label %for.end14
+
+for.body7:                                        ; preds = %for.cond4
+  store i32 %1, i32* %arrayidx10
+  br label %for.inc11
+
+for.inc11:                                        ; preds = %for.body7
+  %inc13 = add nsw i32 %1, 1
+  br label %for.cond4
+
+for.end14:                                        ; preds = %for.cond4
+  ret i32 0
+}
+; CHECK: New access function '{ Stmt_for_body7[i0] -> MemRef_B[0] }'detected in JSCOP file
+; CHECK: New access function '{ Stmt_for_body[i0] -> MemRef_A[0] }'detected in JSCOP file
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/20120330-argument-use.ll b/rc1/test/Cloog/CodeGen/OpenMP/20120330-argument-use.ll
new file mode 100644
index 0000000..0962ffc
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/20120330-argument-use.ll
@@ -0,0 +1,68 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen -enable-polly-openmp < %s -S | FileCheck %s
+
+;/*
+; * =============================================================================
+; *
+; *       Filename:  20120330-argument-use.c
+; *
+; *    Description:  Polly OpenMP test case
+; *
+; *                  Test if the OpenMP subfunction uses the argument copy in
+; *                  the OpenMP struct not the original one only available in
+; *                  the original function.
+; *
+; *                  Run with -polly-codegen -enable-polly-openmp
+; *
+; *         Author:  Johannes Doerfert johannes@jdoerfert.de
+; *
+; *        Created:  2012-03-30
+; *       Modified:  2012-03-30
+; *
+; * =============================================================================
+; */
+;
+;void f(int * restrict A, int * restrict B, int n) {
+;  int i;
+;
+;  for (i = 0; i < n; i++) {
+;    A[i] = B[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-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i32* noalias %A, i32* noalias %B, i32 %n) nounwind uwtable {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+  %tmp = trunc i64 %indvars.iv to i32
+  %cmp = icmp slt i32 %tmp, %n
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i32* %B, i64 %indvars.iv
+  %tmp1 = load i32* %arrayidx, align 4
+  %mul = shl nsw i32 %tmp1, 1
+  %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
+  store i32 %mul, i32* %arrayidx2, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
+; CHECK: %omp.userContext1 = bitcast i8* %omp.userContext to { i32, i32*, i32* }*
+; CHECK: %0 = getelementptr inbounds { i32, i32*, i32* }* %omp.userContext1, i32 0, i32 0
+; CHECK: %1 = load i32* %0
+; CHECK: %2 = getelementptr inbounds { i32, i32*, i32* }* %omp.userContext1, i32 0, i32 1
+; CHECK: %3 = load i32** %2
+; CHECK: %4 = getelementptr inbounds { i32, i32*, i32* }* %omp.userContext1, i32 0, i32 2
+; CHECK: %5 = load i32** %4
+
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/add_memref.ll b/rc1/test/Cloog/CodeGen/OpenMP/add_memref.ll
new file mode 100644
index 0000000..d8218bb
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/add_memref.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -disable-verify -S < %s | FileCheck %s
+
+;#define N 10
+;
+;void foo() {
+;  float A[N];
+;
+;  for (int i=0; i < N; i++)
+;    A[i] = 10;
+;
+;  return;
+;}
+
+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]**
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/clastvar_after_parallel_loop.ll b/rc1/test/Cloog/CodeGen/OpenMP/clastvar_after_parallel_loop.ll
new file mode 100644
index 0000000..3e44784
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/clastvar_after_parallel_loop.ll
@@ -0,0 +1,56 @@
+; RUN: opt %loadPolly -basicaa -polly-cloog -analyze -S < %s | FileCheck %s -check-prefix=CLOOG
+; RUN: opt %loadPolly -basicaa -polly-codegen -enable-polly-openmp -S < %s | FileCheck %s
+;
+; Test case that checks that after the parallel loop on j the value for i is
+; taken from the right temporary (in particular, _not_ the temporary used for i
+; in the OpenMP subfunction for the loop on j).
+;
+; void f(long * restrict A) {
+;     long i, j;
+;     for (i=0; i<100; ++i) {
+;         #pragma omp parallel
+;         for (j=0; j<100; ++j)
+;             A[j] += i;
+;         A[i] = 42;
+;     }
+; }
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* noalias nocapture %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ %i.next, %for.end ], [ 0, %entry ]
+  br label %for.j
+
+for.j:                                     ; preds = %for.j, %for.i
+  %j = phi i64 [ 0, %for.i ], [ %j.next, %for.j ]
+  %i.arrayidx = getelementptr inbounds i64* %A, i64 %j
+  %load = load i64* %i.arrayidx
+  %add = add nsw i64 %load, %i
+  store i64 %add, i64* %i.arrayidx
+  %j.next = add i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.next, 100
+  br i1 %j.exitcond, label %for.end, label %for.j
+
+for.end:                                       ; preds = %for.j
+  %j.arrayidx = getelementptr inbounds i64* %A, i64 %i
+  store i64 42, i64* %j.arrayidx
+  %i.next = add i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.next, 100
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:                                         ; preds = %for.end, %entry
+  ret void
+}
+
+; CLOOG: for (c2=0;c2<=99;c2++) {
+; CLOOG:   for (c4=0;c4<=99;c4++) {
+; CLOOG:     Stmt_for_j(c2,c4);
+; CLOOG:   }
+; CLOOG:   Stmt_for_end(c2);
+; CLOOG: }
+
+; CHECK: @f.omp_subfn
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/copy_in_argument.ll b/rc1/test/Cloog/CodeGen/OpenMP/copy_in_argument.ll
new file mode 100644
index 0000000..b7468c6
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/copy_in_argument.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-codegen -enable-polly-openmp -S < %s | FileCheck %s
+;
+; 'arg' has the same type as A[i], i.e., the function argument has to be
+; copied to the function generated for the loop.
+;
+; float A[100];
+; void copy_in_test(float arg) {
+;     long i;
+;     for (i=0; i<100; ++i)
+;         A[i] = arg;
+; }
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [100 x float] zeroinitializer, align 16
+
+define void @copy_in_test(float %arg) nounwind uwtable {
+entry:
+  br label %for.body
+
+for.body:                                         ; preds = %for.body, %entry
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+  %arrayidx = getelementptr inbounds [100 x float]* @A, i64 0, i64 %indvars.iv
+  store float %arg, float* %arrayidx
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  %exitcond = icmp eq i64 %indvars.iv.next, 100
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:                                          ; preds = %for.body
+  ret void
+}
+
+; CHECK: %omp.userContext = alloca { float }
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/copy_in_temporary.ll b/rc1/test/Cloog/CodeGen/OpenMP/copy_in_temporary.ll
new file mode 100644
index 0000000..8da41fa
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/copy_in_temporary.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-codegen -enable-polly-openmp -S < %s | FileCheck %s
+;
+; 'arg' is converted to float before the loop, so the corresponding temporary
+; has to be copied to the function generated for the loop.
+;
+; float A[100];
+; void copy_in_test(long arg) {
+;   long i;
+;   for (i=0; i<100; ++i)
+;     A[i] = arg;
+; }
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [100 x float] zeroinitializer, align 16
+
+define void @copy_in_test(i64 %arg) nounwind uwtable {
+entry:
+  %conv = sitofp i64 %arg to float
+  br label %for.body
+
+for.body:                                         ; preds = %for.body, %entry
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+  %arrayidx = getelementptr inbounds [100 x float]* @A, i64 0, i64 %indvars.iv
+  store float %conv, float* %arrayidx
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  %exitcond = icmp eq i64 %indvars.iv.next, 100
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:                                          ; preds = %for.body
+  ret void
+}
+
+; CHECK: %omp.userContext = alloca { float }
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/extract_memref.ll b/rc1/test/Cloog/CodeGen/OpenMP/extract_memref.ll
new file mode 100644
index 0000000..825eb71
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/extract_memref.ll
@@ -0,0 +1,57 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -S < %s | FileCheck %s
+
+;#define N 10
+;
+;void foo() {
+;  float A[N];
+;  int i = 0;
+;
+;  for (i=0; i < N; i++)
+;    A[i] = 10;
+;
+;  return;
+;}
+;
+;
+;int main()
+;{
+;	foo();
+;}
+
+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: getelementptr inbounds { [10 x float]* }* %omp.userContext, i32 0, i32 0
+; CHECK: store [10 x float]* %A, [10 x float]** %0
+; CHECK: %omp_data = bitcast { [10 x float]* }* %omp.userContext to i8*
+; CHECK: inbounds { [10 x float]* }* %omp.userContext1, i32 0, i32 0
+; CHECK: load [10 x float]**
+
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/invalidate_subfn_scops.ll b/rc1/test/Cloog/CodeGen/OpenMP/invalidate_subfn_scops.ll
new file mode 100644
index 0000000..b4eec09
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/invalidate_subfn_scops.ll
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -analyze < %s 2>&1 | FileCheck %s
+
+;#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;
+;}
+
+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-NOT: Checking region: omp.setup
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/lit.local.cfg b/rc1/test/Cloog/CodeGen/OpenMP/lit.local.cfg
new file mode 100644
index 0000000..e1ac512
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/lit.local.cfg
@@ -0,0 +1,3 @@
+cloog = config.root.cloog_found
+if cloog not in ['TRUE', 'true', 'yes', 'YES'] :
+    config.unsupported = True
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop.ll b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop.ll
new file mode 100644
index 0000000..f81875d
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop.ll
@@ -0,0 +1,208 @@
+; 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=%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=%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=%S -polly-cloog -polly-codegen -enable-polly-openmp -analyze -disable-polly-legality < %s | FileCheck -check-prefix=TILED %s
+
+;#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];
+;}
+
+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
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop
new file mode 100644
index 0000000..b4ce979
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop
@@ -0,0 +1,42 @@
+{
+	"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] }"
+		}]
+	}]
+}
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop.tiled b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop.tiled
new file mode 100644
index 0000000..23c1699
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop___%bb18---%bb50.jscop.tiled
@@ -0,0 +1,42 @@
+{
+	"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] }"
+		}]
+	}]
+}
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop_simple.ll b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop_simple.ll
new file mode 100644
index 0000000..f1b3c7c
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop_simple.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -polly-codegen -enable-polly-openmp -analyze  < %s | FileCheck %s
+
+;#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];
+;}
+
+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
+
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop_simple2.ll b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop_simple2.ll
new file mode 100644
index 0000000..70905e9
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/parallel_loop_simple2.ll
@@ -0,0 +1,80 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -polly-codegen -enable-polly-openmp -analyze  < %s | FileCheck %s
+
+;#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];
+;}
+
+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
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/param_referenced_in_stmt.ll b/rc1/test/Cloog/CodeGen/OpenMP/param_referenced_in_stmt.ll
new file mode 100644
index 0000000..6fbbf68
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/param_referenced_in_stmt.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-codegen < %s -enable-polly-openmp -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+
+; This test case implements the following code:
+;
+; for (i = 0; i < 1024; i++)
+;   A[i] = A[i] * param
+;
+; The problem is that 'param' is not references in any subscript of loop
+; bound, but it must still be forwarded to the OpenMP subfunction.
+
+define void @foo(double %param, [1024 x double]* %A) {
+entry:
+  br label %for.preheader
+
+for.preheader:
+  br label %for.body
+
+for.body:
+  %indvar = phi i64 [ 0, %for.preheader ], [ %indvar.next, %for.inc ]
+  %arrayidx = getelementptr [1024 x double]* %A, i64 0, i64 %indvar
+  %val = load double* %arrayidx
+  %mul = fmul double %param, %val
+  store double %mul, double* %arrayidx, align 8
+  br label %for.inc
+
+for.inc:
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, 1024
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+; CHECK: omp_subfn
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/simple_nested_loop.ll b/rc1/test/Cloog/CodeGen/OpenMP/simple_nested_loop.ll
new file mode 100644
index 0000000..27cecf2
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/simple_nested_loop.ll
@@ -0,0 +1,92 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -verify-dom-info -S < %s | FileCheck %s
+
+;#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;
+;}
+;
+
+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 { i32 }
+; CHECK: getelementptr inbounds { i32 }* %omp.userContext, i32 0, i32 0
+; CHECK: store i32 %polly.indvar, i32* %0
+; CHECK: %omp_data = bitcast { i32 }* %omp.userContext to i8*
+; CHECK: call void @GOMP_parallel_loop_runtime_start(void (i8*)* @loop_openmp.omp_subfn, i8* %omp_data, i32 0, i32 0, i32 10, i32 1)
+; CHECK: call void @loop_openmp.omp_subfn(i8* %omp_data)
+; CHECK: call void @GOMP_parallel_end()
+
+; Verify the new subfunction is annotated such that SCoP detection will skip it.
+; CHECK: @loop_openmp.omp_subfn({{.*}}) [[ATTR:#[0-9]+]]
+; CHECK: attributes [[ATTR]] = {{{[^\}]*}}polly.skip.fn{{[^\}]*}}}
+
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/structnames.ll b/rc1/test/Cloog/CodeGen/OpenMP/structnames.ll
new file mode 100644
index 0000000..d6eeb8b
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/structnames.ll
@@ -0,0 +1,105 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -enable-polly-openmp -S  < %s | FileCheck %s
+
+;#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;
+;}
+;
+
+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: %omp.userContext = alloca {}
+; CHECK: %omp.userContext1 = alloca { i32 }
+
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/two_loop.ll b/rc1/test/Cloog/CodeGen/OpenMP/two_loop.ll
new file mode 100644
index 0000000..4f27dfc
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/two_loop.ll
@@ -0,0 +1,81 @@
+; RUN: opt %loadPolly %defaultOpts -mem2reg -polly-codegen -enable-polly-openmp -S %s
+
+;#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;
+;}
+;
+
+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
diff --git a/rc1/test/Cloog/CodeGen/OpenMP/vector-codegen-in-openmp-subfunc.ll b/rc1/test/Cloog/CodeGen/OpenMP/vector-codegen-in-openmp-subfunc.ll
new file mode 100644
index 0000000..2860506
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/OpenMP/vector-codegen-in-openmp-subfunc.ll
@@ -0,0 +1,48 @@
+; RUN: opt %loadPolly -basicaa -polly-vectorizer=polly -enable-polly-openmp -polly-opt-isl -polly-codegen < %s
+
+; void f(int *A, int a, int b) {
+;   int local = a > b ? a : b;
+;   int i;
+;   for (i = 0; i < 100; i++) {
+;     A[i] += local;
+;   }
+; }
+;
+
+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(i32* %A, i32 %a, i32 %b) {
+entry:
+  %cmp = icmp sgt i32 %a, %b
+  br i1 %cmp, label %cond.true, label %cond.false
+
+cond.true:                                        ; preds = %entry
+  br label %cond.end
+
+cond.false:                                       ; preds = %entry
+  br label %cond.end
+
+cond.end:                                         ; preds = %cond.false, %cond.true
+  %cond = phi i32 [ %a, %cond.true ], [ %b, %cond.false ]
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %cond.end
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %cond.end ]
+  %exitcond = icmp ne i64 %indvars.iv, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i32* %A, i64 %indvars.iv
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %cond
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Cloog/CodeGen/PHIInExit.ll b/rc1/test/Cloog/CodeGen/PHIInExit.ll
new file mode 100644
index 0000000..8b5dfaa
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/PHIInExit.ll
@@ -0,0 +1,104 @@
+; 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"
+
+%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
+}
+
+define i32 @pthread_once(i32*, void ()*) {
+  ret i32 0
+}
+
+define i8* @pthread_getspecific(i32) {
+  ret i8* null
+}
+
+define i32 @pthread_setspecific(i32, i8*) {
+  ret i32 0
+}
+
+define i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) {
+  ret i32 0
+}
+
+define i32 @pthread_cancel(i64) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_lock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_trylock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_unlock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_key_create(i32*, void (i8*)*) {
+  ret i32 0
+}
+
+define i32 @pthread_key_delete(i32) {
+  ret i32 0
+}
+
+define i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32) {
+  ret i32 0
+}
+
+define i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*) {
+  ret i32 0
+}
diff --git a/rc1/test/Cloog/CodeGen/constant_condition.ll b/rc1/test/Cloog/CodeGen/constant_condition.ll
new file mode 100644
index 0000000..87fe678
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/constant_condition.ll
@@ -0,0 +1,56 @@
+;RUN: opt %loadPolly %defaultOpts -polly-detect-scops-in-regions-without-loops -polly-detect-scops-in-functions-without-loops -polly-cloog -analyze < %s | FileCheck %s
+
+;#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];
+;}
+
+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
+}
+
+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();
diff --git a/rc1/test/Cloog/CodeGen/do_pluto_matmult.ll b/rc1/test/Cloog/CodeGen/do_pluto_matmult.ll
new file mode 100644
index 0000000..c20092b
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/do_pluto_matmult.ll
@@ -0,0 +1,303 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+; RUN: opt %loadPolly %defaultOpts -polly-codegen -disable-output %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=%S -polly-cloog -analyze  < %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=%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=%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=%S -polly-cloog -analyze  < %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=%S -polly-codegen -S < %s | FileCheck -check-prefix=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"
+
+%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
+  fence seq_cst
+  %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
+}
+
+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:
+  fence seq_cst
+  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
+  fence seq_cst
+  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.
+
+
+
diff --git a/rc1/test/Cloog/CodeGen/do_pluto_matmult.ll.result b/rc1/test/Cloog/CodeGen/do_pluto_matmult.ll.result
new file mode 100644
index 0000000..7254e4a
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/do_pluto_matmult.ll.result
@@ -0,0 +1,36 @@
+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 
diff --git a/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop b/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop
new file mode 100644
index 0000000..009e895
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop
@@ -0,0 +1,25 @@
+{
+	"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
diff --git a/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.invalid_reverse b/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.invalid_reverse
new file mode 100644
index 0000000..0345bec
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.invalid_reverse
@@ -0,0 +1,25 @@
+{
+	"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
diff --git a/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.valid_reverse b/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.valid_reverse
new file mode 100644
index 0000000..e7f01e0
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/do_pluto_matmult___%do.body---%do.end45.jscop.valid_reverse
@@ -0,0 +1,25 @@
+{
+	"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
diff --git a/rc1/test/Cloog/CodeGen/loop_with_condition.ll b/rc1/test/Cloog/CodeGen/loop_with_condition.ll
new file mode 100644
index 0000000..a7179e4
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/loop_with_condition.ll
@@ -0,0 +1,177 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+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: }
+
diff --git a/rc1/test/Cloog/CodeGen/loop_with_condition_2.ll b/rc1/test/Cloog/CodeGen/loop_with_condition_2.ll
new file mode 100644
index 0000000..392b79b
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/loop_with_condition_2.ll
@@ -0,0 +1,139 @@
+; 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 [1024 x i32] zeroinitializer, align 16
+@B = common global [1024 x i32] zeroinitializer, align 16
+
+define void @loop_with_condition(i32 %m) nounwind {
+entry:
+  fence seq_cst
+  %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
+  fence seq_cst
+  ret void
+}
+
+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: }
+
diff --git a/rc1/test/Cloog/CodeGen/loop_with_condition_ineq.ll b/rc1/test/Cloog/CodeGen/loop_with_condition_ineq.ll
new file mode 100644
index 0000000..dca05e8
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/loop_with_condition_ineq.ll
@@ -0,0 +1,179 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+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: }
+
diff --git a/rc1/test/Cloog/CodeGen/loop_with_condition_nested.ll b/rc1/test/Cloog/CodeGen/loop_with_condition_nested.ll
new file mode 100644
index 0000000..40a1fd8
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/loop_with_condition_nested.ll
@@ -0,0 +1,221 @@
+; RUN: opt %loadPolly -basicaa -polly-cloog -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen -loops -analyze < %s | FileCheck %s -check-prefix=LOOPS
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+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: }
+
+
+; LOOPS: Loop at depth 1 containing: %polly.loop_header<header>,%polly.stmt.,%polly.stmt.3<latch><exiting>
+; LOOPS: Loop at depth 1 containing: %polly.loop_header5<header>,%polly.stmt.11,%polly.stmt.12<latch><exiting>
+; LOOPS: Loop at depth 1 containing: %polly.loop_header15<header>,%polly.stmt.21<latch><exiting>
diff --git a/rc1/test/Cloog/CodeGen/matmul_vec.ll b/rc1/test/Cloog/CodeGen/matmul_vec.ll
new file mode 100644
index 0000000..8a293e8
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/matmul_vec.ll
@@ -0,0 +1,138 @@
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=%S -polly-codegen %vector-opt -S -dce < %s | FileCheck %s
+
+;#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];
+;}
+
+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>
diff --git a/rc1/test/Cloog/CodeGen/matmul_vec___%1---%17.jscop b/rc1/test/Cloog/CodeGen/matmul_vec___%1---%17.jscop
new file mode 100644
index 0000000..a5b1612
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/matmul_vec___%1---%17.jscop
@@ -0,0 +1,25 @@
+{
+	"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] }"
+		}]
+	}]
+}
diff --git a/rc1/test/Cloog/CodeGen/phi_guard.ll b/rc1/test/Cloog/CodeGen/phi_guard.ll
new file mode 100644
index 0000000..242b7a3
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/phi_guard.ll
@@ -0,0 +1,32 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-codegen < %s
+
+; This test case checks that Polly does not break for PHI guard statement.
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @phi_guard() {
+entry:
+  %acc.reg2mem = alloca i32
+  br label %for.preheader
+
+for.preheader:                              ; preds = %for.end, %entry
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.end ]
+  store i32 0, i32* %acc.reg2mem
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.inc, %for.preheader
+  %0 = phi i32 [ 0, %for.preheader ], [ %1, %for.inc ]
+  %1 = add nsw i32 %0, 1
+  store i32 %1, i32* %acc.reg2mem
+  %exitcond = icmp ne i32 %1, 20
+  br i1 %exitcond, label %for.inc, label %for.end
+
+for.end:                                          ; preds = %for.inc
+  %indvar.next = add i64 %indvar, 1
+  %exitcond4 = icmp ne i64 %indvar.next, 20
+  br i1 %exitcond4, label %for.preheader, label %for.end10
+
+for.end10:                                        ; preds = %for.end
+  %res = load i32* %acc.reg2mem, align 4
+  ret i32 %res
+}
diff --git a/rc1/test/Cloog/CodeGen/phi_guard___%for.preheader---%for.end10.jscop b/rc1/test/Cloog/CodeGen/phi_guard___%for.preheader---%for.end10.jscop
new file mode 100644
index 0000000..9c91a75
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/phi_guard___%for.preheader---%for.end10.jscop
@@ -0,0 +1,28 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.preheader => for.end10",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_preheader[i0] -> MemRef_acc_reg2mem[0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_preheader[i0] : i0 >= 0 and i0 <= 19 }",
+         "name" : "Stmt_for_preheader",
+         "schedule" : "{ Stmt_for_preheader[i0] -> [o0, o1, i0, 19i0, 0] : exists (e0 = [(o1)/32], e1 = [(o0)/32]: 32e0 = o1 and 32e1 = o0 and o0 <= i0 and o0 >= -31 + i0 and o1 <= 19i0 and o1 >= -31 + 19i0 and i0 >= 0 and i0 <= 19) }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_inc[i0, i1] -> MemRef_acc_reg2mem[0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_inc[i0, i1] : i0 >= 0 and i0 <= 19 and i1 >= 0 and i1 <= 19 }",
+         "name" : "Stmt_for_inc",
+         "schedule" : "{ Stmt_for_inc[i0, i1] -> [o0, o1, i0, 19i0 + i1, 1] : exists (e0 = [(o1)/32], e1 = [(o0)/32]: 32e0 = o1 and 32e1 = o0 and o0 <= i0 and o0 >= -31 + i0 and o1 <= 19i0 + i1 and o1 >= -31 + 19i0 + i1 and i0 >= 0 and i0 <= 19 and i1 >= 0 and i1 <= 19) }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/pluto_matmult.ll b/rc1/test/Cloog/CodeGen/pluto_matmult.ll
new file mode 100644
index 0000000..e19be65
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/pluto_matmult.ll
@@ -0,0 +1,148 @@
+; 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=%S -polly-cloog -analyze  -S < %s | FileCheck -check-prefix=IMPORT %s
+
+;#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;
+;}
+
+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:
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+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: }
+
diff --git a/rc1/test/Cloog/CodeGen/pluto_matmult___%for.cond---%for.end47.jscop b/rc1/test/Cloog/CodeGen/pluto_matmult___%for.cond---%for.end47.jscop
new file mode 100644
index 0000000..54b3296
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/pluto_matmult___%for.cond---%for.end47.jscop
@@ -0,0 +1,25 @@
+{
+	"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
diff --git a/rc1/test/Cloog/CodeGen/reduced-domain-eliminates-dependences.ll b/rc1/test/Cloog/CodeGen/reduced-domain-eliminates-dependences.ll
new file mode 100644
index 0000000..480f989
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/reduced-domain-eliminates-dependences.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-codegen -polly-vectorizer=polly < %s
+
+; void f(int a[]) {
+;  int i;
+;  for (i = 0; i < 10; ++i)
+;    A[i] = A[i+5];
+; }
+
+; In this test case we import a schedule that limits the iteration domain
+; to 0 <= i < 5, which makes the loop parallel. Previously we crashed in such
+; cases. This test checks that we instead vectorize the loop.
+
+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 @reduced-domain-eliminates-dependences(i64* %a) {
+entry:
+  br label %bb
+
+bb:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %bb ]
+  %add = add i64 %indvar, 5
+  %scevgep.load = getelementptr i64* %a, i64 %add
+  %scevgep.store = getelementptr i64* %a, i64 %indvar
+  %val = load i64* %scevgep.load
+  store i64 %val, i64* %scevgep.store, align 8
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, 10
+  br i1 %exitcond, label %return, label %bb
+
+return:
+  ret void
+}
+
+; CHECK: store <4 x i64> %val_p_vec_full, <4 x i64>* %vector_ptr10
diff --git a/rc1/test/Cloog/CodeGen/reduced-domain-eliminates-dependences___%bb---%return.jscop b/rc1/test/Cloog/CodeGen/reduced-domain-eliminates-dependences___%bb---%return.jscop
new file mode 100644
index 0000000..525ed20
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/reduced-domain-eliminates-dependences___%bb---%return.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "bb => return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_bb[i0] -> MemRef_a[5 + i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_bb[i0] -> MemRef_a[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_bb[i0] : i0 >= 0 and i0 <= 10 }",
+         "name" : "Stmt_bb",
+         "schedule" : "{ Stmt_bb[i0] -> scattering[0, i0, 0]: i0 < 4 }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/CodeGen/reduction_2.ll b/rc1/test/Cloog/CodeGen/reduction_2.ll
new file mode 100644
index 0000000..93e5df4
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/reduction_2.ll
@@ -0,0 +1,94 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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: }
diff --git a/rc1/test/Cloog/CodeGen/sequential_loops.ll b/rc1/test/Cloog/CodeGen/sequential_loops.ll
new file mode 100644
index 0000000..de3afa0
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/sequential_loops.ll
@@ -0,0 +1,138 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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: }
+
diff --git a/rc1/test/Cloog/CodeGen/simple_nonaffine_loop.ll b/rc1/test/Cloog/CodeGen/simple_nonaffine_loop.ll
new file mode 100644
index 0000000..010da12
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_nonaffine_loop.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -polly-cloog -polly-allow-nonaffine -analyze < %s | FileCheck %s
+
+;#include <stdio.h>
+;#include <stdlib.h>
+;#include <math.h>
+;
+;int main()
+;{
+;	int A[1024*1024];
+;	int i;
+;	for (i = 0; i < 1024; i++)
+;		A[i*i] = 2*i;
+;
+;	printf("Random Value: %d", A[rand() % 1024*1024]);
+;
+;	return 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-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
+@.str = private unnamed_addr constant [17 x i8] c"Random Value: %d\00", align 1
+
+define i32 @main() nounwind uwtable ssp {
+entry:
+  %A = alloca [1048576 x i32], align 16
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %0 = phi i32 [ 0, %entry.split ], [ %1, %for.body ]
+  %mul = mul i32 %0, 2
+  %mul1 = mul nsw i32 %0, %0
+  %idxprom1 = zext i32 %mul1 to i64
+  %arrayidx = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom1
+  store i32 %mul, i32* %arrayidx, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  %call = call i32 @rand() nounwind
+  %rem = srem i32 %call, 1024
+  %mul2 = shl nsw i32 %rem, 10
+  %idxprom3 = sext i32 %mul2 to i64
+  %arrayidx4 = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom3
+  %2 = load i32* %arrayidx4, align 16
+  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i64 0, i64 0), i32 %2) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @rand()
+; CHECK: for (c2=0;c2<=1023;c2++) {
+; CHECK:  Stmt_for_body(c2);
+; CHECK: }
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_assign_scalar.ll b/rc1/test/Cloog/CodeGen/simple_vec_assign_scalar.ll
new file mode 100644
index 0000000..9a371dc
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_assign_scalar.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %vector-opt -dce -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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>
+
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_assign_scalar_2.ll b/rc1/test/Cloog/CodeGen/simple_vec_assign_scalar_2.ll
new file mode 100644
index 0000000..0361718
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_assign_scalar_2.ll
@@ -0,0 +1,66 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %vector-opt -dce -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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 %{{[^,]+}}, i32 0
+; CHECK: insertelement <4 x float> %0, float %{{[^,]+}}, i32 1
+; CHECK: insertelement <4 x float> %1, float %{{[^,]+}}, i32 2
+; CHECK: insertelement <4 x float> %2, float %{{[^,]+}}, i32 3
+; CHECK: fadd <4 x float> %tmp_p_vec_full, %3
+
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_call.ll b/rc1/test/Cloog/CodeGen/simple_vec_call.ll
new file mode 100644
index 0000000..93cabf6
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_call.ll
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen %vector-opt -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
+
+declare float @foo(float) readnone
+
+define void @simple_vec_call() nounwind {
+entry:
+  br label %body
+
+body:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar_next, %body ]
+  %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+  %value = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+  %result = tail call float @foo(float %value) nounwind
+  store float %result, float* %scevgep, align 4
+  %indvar_next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar_next, 4
+  br i1 %exitcond, label %return, label %body
+
+return:
+  ret void
+}
+
+; CHECK: %value_p_splat_one = load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*), align 8
+; CHECK: %value_p_splat = shufflevector <1 x float> %value_p_splat_one, <1 x float> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK: %0 = extractelement <4 x float> %value_p_splat, i32 0
+; CHECK: %1 = extractelement <4 x float> %value_p_splat, i32 1
+; CHECK: %2 = extractelement <4 x float> %value_p_splat, i32 2
+; CHECK: %3 = extractelement <4 x float> %value_p_splat, i32 3
+; CHECK: [[RES1:%[a-zA-Z0-9_]+]] = tail call float @foo(float %0) [[NUW:#[0-9]+]]
+; CHECK: [[RES2:%[a-zA-Z0-9_]+]] = tail call float @foo(float %1) [[NUW]]
+; CHECK: [[RES3:%[a-zA-Z0-9_]+]] = tail call float @foo(float %2) [[NUW]]
+; CHECK: [[RES4:%[a-zA-Z0-9_]+]] = tail call float @foo(float %3) [[NUW]]
+; CHECK: %4 = insertelement <4 x float> undef, float [[RES1]], i32 0
+; CHECK: %5 = insertelement <4 x float> %4, float [[RES2]], i32 1
+; CHECK: %6 = insertelement <4 x float> %5, float [[RES3]], i32 2
+; CHECK: %7 = insertelement <4 x float> %6, float [[RES4]], i32 3
+; CHECK:  store <4 x float> %7
+
+; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_call_2.ll b/rc1/test/Cloog/CodeGen/simple_vec_call_2.ll
new file mode 100644
index 0000000..a5bf14d
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_call_2.ll
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen %vector-opt -polly-codegen-scev=false -dce -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen %vector-opt -polly-codegen-scev=true -dce -S < %s | FileCheck %s -check-prefix=CHECK-SCEV
+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
+
+declare float** @foo(float) readnone
+
+define void @simple_vec_call() nounwind {
+entry:
+  br label %body
+
+body:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar_next, %body ]
+  %scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 %indvar
+  %value = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+  %result = tail call float** @foo(float %value) nounwind
+  store float** %result, float*** %scevgep, align 4
+  %indvar_next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar_next, 4
+  br i1 %exitcond, label %return, label %body
+
+return:
+  ret void
+}
+
+; CHECK: %p_scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 0
+; CHECK: %value_p_splat_one = load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*), align 8
+; CHECK: %value_p_splat = shufflevector <1 x float> %value_p_splat_one, <1 x float> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK: %0 = extractelement <4 x float> %value_p_splat, i32 0
+; CHECK: %1 = extractelement <4 x float> %value_p_splat, i32 1
+; CHECK: %2 = extractelement <4 x float> %value_p_splat, i32 2
+; CHECK: %3 = extractelement <4 x float> %value_p_splat, i32 3
+; CHECK: [[RES1:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %0) [[NUW:#[0-9]+]]
+; CHECK: [[RES2:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %1) [[NUW]]
+; CHECK: [[RES3:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %2) [[NUW]]
+; CHECK: [[RES4:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %3) [[NUW]]
+; CHECK: %4 = insertelement <4 x float**> undef, float** %p_result, i32 0
+; CHECK: %5 = insertelement <4 x float**> %4, float** %p_result4, i32 1
+; CHECK: %6 = insertelement <4 x float**> %5, float** %p_result5, i32 2
+; CHECK: %7 = insertelement <4 x float**> %6, float** %p_result6, i32 3
+; CHECK: %vector_ptr = bitcast float*** %p_scevgep to <4 x float**>*
+; CHECK: store <4 x float**> %7, <4 x float**>* %vector_ptr, align 8
+; CHECK: attributes [[NUW]] = { nounwind }
+
+; CHECK-SCEV: %value_p_splat_one = load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*), align 8
+; CHECK-SCEV: %value_p_splat = shufflevector <1 x float> %value_p_splat_one, <1 x float> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK-SCEV: %0 = extractelement <4 x float> %value_p_splat, i32 0
+; CHECK-SCEV: %1 = extractelement <4 x float> %value_p_splat, i32 1
+; CHECK-SCEV: %2 = extractelement <4 x float> %value_p_splat, i32 2
+; CHECK-SCEV: %3 = extractelement <4 x float> %value_p_splat, i32 3
+; CHECK-SCEV: [[RES1:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %0) [[NUW:#[0-9]+]]
+; CHECK-SCEV: [[RES2:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %1) [[NUW]]
+; CHECK-SCEV: [[RES3:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %2) [[NUW]]
+; CHECK-SCEV: [[RES4:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %3) [[NUW]]
+; CHECK-SCEV: %4 = insertelement <4 x float**> undef, float** %p_result, i32 0
+; CHECK-SCEV: %5 = insertelement <4 x float**> %4, float** %p_result1, i32 1
+; CHECK-SCEV: %6 = insertelement <4 x float**> %5, float** %p_result2, i32 2
+; CHECK-SCEV: %7 = insertelement <4 x float**> %6, float** %p_result3, i32 3
+; CHECK-SCEV: store <4 x float**> %7, <4 x float**>* bitcast ([1024 x float**]* @B to <4 x float**>*), align 
+; CHECK-SCEV: attributes [[NUW]] = { nounwind }
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_cast.ll b/rc1/test/Cloog/CodeGen/simple_vec_cast.ll
new file mode 100644
index 0000000..8080dda
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_cast.ll
@@ -0,0 +1,33 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen %vector-opt -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 double] zeroinitializer, align 16
+
+define void @simple_vec_const() nounwind {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb3, %bb
+  %indvar = phi i64 [ %indvar.next, %bb3 ], [ 0, %bb ]
+  %scevgep = getelementptr [1024 x double]* @B, i64 0, i64 %indvar
+  %exitcond = icmp ne i64 %indvar, 4
+  br i1 %exitcond, label %bb2, label %bb4
+
+bb2:                                              ; preds = %bb1
+  %tmp = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+  %tmp2 = fpext float %tmp to double
+  store double %tmp2, double* %scevgep, align 4
+  br label %bb3
+
+bb3:                                              ; preds = %bb2
+  %indvar.next = add i64 %indvar, 1
+  br label %bb1
+
+bb4:                                              ; preds = %bb1
+  ret void
+}
+
+; CHECK:  fpext <4 x float> %tmp_p_splat to <4 x double>
+
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_const.ll b/rc1/test/Cloog/CodeGen/simple_vec_const.ll
new file mode 100644
index 0000000..a2e0fba
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_const.ll
@@ -0,0 +1,58 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %vector-opt -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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
+
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_large_width.ll b/rc1/test/Cloog/CodeGen/simple_vec_large_width.ll
new file mode 100644
index 0000000..df02ae3
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_large_width.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %vector-opt -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: [[VEC1:%[a-zA-Z0-9_]+_full]] = load <15 x float>*
+; CHECK: store <15 x float> [[VEC1]]
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll b/rc1/test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll
new file mode 100644
index 0000000..d295be7
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_ptr_ptr_ty.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen %vector-opt -S -polly-codegen-scev=false < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen %vector-opt -S -polly-codegen-scev=true < %s | FileCheck %s -check-prefix=CHECK-SCEV
+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
+
+declare float @foo(float) readnone
+
+define void @simple_vec_call() nounwind {
+entry:
+  br label %body
+
+body:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar_next, %body ]
+  %scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 %indvar
+  %value = load float*** getelementptr inbounds ([1024 x float**]* @A, i64 0, i64 0), align 16
+  store float** %value, float*** %scevgep, align 4
+  %indvar_next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar_next, 4
+  br i1 %exitcond, label %return, label %body
+
+return:
+  ret void
+}
+
+; CHECK: %p_scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 0
+; CHECK: %p_scevgep1 = getelementptr [1024 x float**]* @B, i64 0, i64 1
+; CHECK: %p_scevgep2 = getelementptr [1024 x float**]* @B, i64 0, i64 2
+; CHECK: %p_scevgep3 = getelementptr [1024 x float**]* @B, i64 0, i64 3
+; CHECK: %value_p_splat_one = load <1 x float**>* bitcast ([1024 x float**]* @A to <1 x float**>*), align 8
+; CHECK: %value_p_splat = shufflevector <1 x float**> %value_p_splat_one, <1 x float**> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK: %vector_ptr = bitcast float*** %p_scevgep to <4 x float**>*
+; CHECK: store <4 x float**> %value_p_splat, <4 x float**>* %vector_ptr
+
+
+; CHECK-SCEV: %value_p_splat_one = load <1 x float**>* bitcast ([1024 x float**]* @A to <1 x float**>*), align 8
+; CHECK-SCEV: %value_p_splat = shufflevector <1 x float**> %value_p_splat_one, <1 x float**> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK-SCEV: store <4 x float**> %value_p_splat, <4 x float**>* bitcast ([1024 x float**]* @B to <4 x float**>*), align 8
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_stride_one.ll b/rc1/test/Cloog/CodeGen/simple_vec_stride_one.ll
new file mode 100644
index 0000000..8050924
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_stride_one.ll
@@ -0,0 +1,76 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %vector-opt -dce -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen -polly-vectorizer=unroll-only -S < %s | FileCheck -check-prefix=UNROLL %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=%S -polly-cloog -analyze   < %s | FileCheck -check-prefix=IMPORT %s
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop -polly-import-jscop-dir=%S -polly-codegen  < %s -S  %vector-opt | FileCheck -check-prefix=CODEGEN %s
+
+;#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];
+;}
+
+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: [[LOAD1:%[a-zA-Z0-9_]+]] = load <4 x float>*
+; CHECK: store <4 x float> [[LOAD1]]
+
+; 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>
+
+; UNROLL: [[LOAD1:%[a-zA-Z0-9_]+_scalar.*]] = load float*
+; UNROLL: [[LOAD2:%[a-zA-Z0-9_]+_scalar.*]] = load float*
+; UNROLL: [[LOAD3:%[a-zA-Z0-9_]+_scalar.*]] = load float*
+; UNROLL: [[LOAD4:%[a-zA-Z0-9_]+_scalar.*]] = load float*
+; UNROLL: store float [[LOAD1]]
+; UNROLL: store float [[LOAD2]]
+; UNROLL: store float [[LOAD3]]
+; UNROLL: store float [[LOAD4]]
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_stride_one___%1---%5.jscop b/rc1/test/Cloog/CodeGen/simple_vec_stride_one___%1---%5.jscop
new file mode 100644
index 0000000..dec45ba
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_stride_one___%1---%5.jscop
@@ -0,0 +1,17 @@
+{
+	"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] }"
+		}]
+	}]
+}
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_stride_x.ll b/rc1/test/Cloog/CodeGen/simple_vec_stride_x.ll
new file mode 100644
index 0000000..30e1bf8
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_stride_x.ll
@@ -0,0 +1,73 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %vector-opt  -dce -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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: [[LOAD1:%[a-zA-Z0-9_]+_scalar_]] = load float*
+; CHECK: [[VEC1:%[a-zA-Z0-9_]+]] = insertelement <4 x float> undef, float [[LOAD1]], i32 0
+; CHECK: [[LOAD2:%[a-zA-Z0-9_]+]] = load float*
+; CHECK: [[VEC2:%[a-zA-Z0-9_]+]] = insertelement <4 x float> [[VEC1]], float [[LOAD2]], i32 1
+; CHECK: [[LOAD3:%[a-zA-Z0-9_]+]] = load float*
+; CHECK: [[VEC3:%[a-zA-Z0-9_]+]] = insertelement <4 x float> [[VEC2]], float [[LOAD3]], i32 2
+; CHECK: [[LOAD4:%[a-zA-Z0-9_]+]] = load float*
+; CHECK: [[VEC4:%[a-zA-Z0-9_]+]] = insertelement <4 x float> [[VEC3]], float [[LOAD4]], i32 3
+; CHECK: [[EL1:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 0
+; CHECK: store float [[EL1]]
+; CHECK: [[EL2:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 1
+; CHECK: store float [[EL2]]
+; CHECK: [[EL3:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 2
+; CHECK: store float [[EL3]]
+; CHECK: [[EL4:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 3
+; CHECK: store float [[EL4]]
diff --git a/rc1/test/Cloog/CodeGen/simple_vec_two_stmts.ll b/rc1/test/Cloog/CodeGen/simple_vec_two_stmts.ll
new file mode 100644
index 0000000..dbbd620
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/simple_vec_two_stmts.ll
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen %vector-opt -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: [[LOAD1:%[a-zA-Z0-9_]+_full]] = load <4 x float>*
+; CHECK: store <4 x float> [[LOAD1]]
+; CHECK: [[LOAD2:%[a-zA-Z0-9_]+_full]] = load <4 x float>*
+; CHECK: store <4 x float> [[LOAD2]]
+
diff --git a/rc1/test/Cloog/CodeGen/single_do_loop_int_max_iterations.ll b/rc1/test/Cloog/CodeGen/single_do_loop_int_max_iterations.ll
new file mode 100644
index 0000000..85cc106
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_do_loop_int_max_iterations.ll
@@ -0,0 +1,91 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze  -S < %s | FileCheck %s
+
+;#define N 20
+;#include "limits.h"
+;#include <stdio.h>
+;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;
+;}
+
+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:
+  fence seq_cst
+  br label %do.body
+
+do.body:                                          ; preds = %do.cond, %entry
+  %0 = phi i32 [ 0, %entry ], [ %inc, %do.cond ]  ; <i32> [#uses=2]
+  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
+  fence seq_cst
+  ret void
+}
+
+define i32 @main() nounwind {
+entry:
+  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 = 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 = 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++) {
diff --git a/rc1/test/Cloog/CodeGen/single_do_loop_ll_max_iterations.ll b/rc1/test/Cloog/CodeGen/single_do_loop_ll_max_iterations.ll
new file mode 100644
index 0000000..6fdcdb0
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_do_loop_ll_max_iterations.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze  -S < %s | FileCheck %s
+; RUN: opt %loadPolly %defaultOpts -polly-codegen < %s
+
+;#define N 20
+;#include "limits.h"
+;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;
+;}
+
+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:
+  store i64 0, i64* getelementptr inbounds ([20 x i64]* @A, i32 0, i32 0)
+  fence seq_cst
+  br label %do.body
+
+do.body:                                          ; preds = %do.cond, %entry
+  %0 = phi i64 [ 0, %entry ], [ %inc, %do.cond ]  ; <i64> [#uses=2]
+  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
+  fence seq_cst
+  %tmp3 = 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
+}
+
+; CHECK:for (c2=0;c2<=9223372036854775806;c2++) {
+
diff --git a/rc1/test/Cloog/CodeGen/single_do_loop_scev_replace.ll b/rc1/test/Cloog/CodeGen/single_do_loop_scev_replace.ll
new file mode 100644
index 0000000..8d8f6f4
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_do_loop_scev_replace.ll
@@ -0,0 +1,95 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#define N 20
+;#include "limits.h"
+;#include <stdio.h>
+;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;
+;}
+
+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:
+  fence seq_cst
+  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
+  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
+  fence seq_cst
+  ret void
+}
+
+define i32 @main() nounwind {
+entry:
+  call void @single_do_loop_scev_replace()
+  %tmp = load %struct._IO_FILE** @stdout          ; <%struct._IO_FILE*> [#uses=1]
+  %tmp1 = 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 = 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:   }
+
diff --git a/rc1/test/Cloog/CodeGen/single_loop.ll b/rc1/test/Cloog/CodeGen/single_loop.ll
new file mode 100644
index 0000000..2d72ade
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_loop.ll
@@ -0,0 +1,86 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#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;
+;}
+;
+
+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:}
diff --git a/rc1/test/Cloog/CodeGen/single_loop_int_max_iterations.ll b/rc1/test/Cloog/CodeGen/single_loop_int_max_iterations.ll
new file mode 100644
index 0000000..ba304c8
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_loop_int_max_iterations.ll
@@ -0,0 +1,71 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze  -S < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK:for (c2=0;c2<=2147483646;c2++) {
diff --git a/rc1/test/Cloog/CodeGen/single_loop_ll_max_iterations.ll b/rc1/test/Cloog/CodeGen/single_loop_ll_max_iterations.ll
new file mode 100644
index 0000000..7b4b84a
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_loop_ll_max_iterations.ll
@@ -0,0 +1,71 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze  -S < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK:for (c2=0;c2<=9223372036854775806;c2++) {
diff --git a/rc1/test/Cloog/CodeGen/single_loop_one_iteration.ll b/rc1/test/Cloog/CodeGen/single_loop_one_iteration.ll
new file mode 100644
index 0000000..abdbbf3
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_loop_one_iteration.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK: Stmt_for_body(0);
diff --git a/rc1/test/Cloog/CodeGen/single_loop_param.ll b/rc1/test/Cloog/CodeGen/single_loop_param.ll
new file mode 100644
index 0000000..c293b2b
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_loop_param.ll
@@ -0,0 +1,74 @@
+; 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-pc-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=3]
+
+define void @bar(i64 %n) nounwind {
+bb:
+  fence seq_cst
+  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
+  fence seq_cst
+  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 @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
+
+; CHECK: if (n >= 1) {
+; CHECK:     for (c2=0;c2<=n-1;c2++) {
+; CHECK:           Stmt_bb2(c2);
+; CHECK:             }
+; CHECK: }
+
diff --git a/rc1/test/Cloog/CodeGen/single_loop_zero_iterations.ll b/rc1/test/Cloog/CodeGen/single_loop_zero_iterations.ll
new file mode 100644
index 0000000..6956fdd
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/single_loop_zero_iterations.ll
@@ -0,0 +1,70 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze  -S < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK: for region: 'for.cond => for.end.region' in function 'main':
+; CHECK-NEXT: main():
+; CHECK-NOT:   Stmt_for_body(0);
diff --git a/rc1/test/Cloog/CodeGen/split_edges.ll b/rc1/test/Cloog/CodeGen/split_edges.ll
new file mode 100644
index 0000000..bfc6bc7
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/split_edges.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-codegen -verify-region-info -verify-dom-info -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-pc-linux-gnu"
+
+define void @loop_with_condition() nounwind {
+bb0:
+  fence seq_cst
+  br label %bb1
+
+bb1:
+  br i1 true, label %bb2, label %bb3
+
+bb2:
+  %ind1 = phi i32 [0, %bb1], [ %inc1, %bb2]
+  %inc1 = add i32 %ind1, 1
+  %cond1 = icmp eq i32 %ind1, 32
+  br i1 %cond1, label %bb4, label %bb2
+
+bb3:
+  %ind2 = phi i32 [0, %bb1], [ %inc2, %bb3]
+  %inc2 = add i32 %ind2, 1
+  br i1 true, label %bb4, label %bb3
+
+bb4:
+  br label %bb5
+
+bb5:
+  fence seq_cst
+  ret void
+
+}
+
+; CHECK: polly.split_new_and_old
+; CHECK: polly.merge_new_and_old
diff --git a/rc1/test/Cloog/CodeGen/split_edges_2.ll b/rc1/test/Cloog/CodeGen/split_edges_2.ll
new file mode 100644
index 0000000..e7501c3
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/split_edges_2.ll
@@ -0,0 +1,33 @@
+; RUN: opt %loadPolly -polly-codegen -verify-region-info -verify-dom-info -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-pc-linux-gnu"
+
+define void @loop_with_condition() nounwind {
+bb0:
+  fence seq_cst
+  br label %bb1
+
+bb1:
+  br label %bb2
+
+bb2:
+  %ind1 = phi i32 [0, %bb1], [ %inc1, %bb2]
+  %inc1 = add i32 %ind1, 1
+  %cond1 = icmp eq i32 %ind1, 32
+  br i1 %cond1, label %bb4, label %bb2
+
+bb4:
+  br label %bb5
+
+bb5:
+  fence seq_cst
+  ret void
+
+}
+
+; CHECK: polly.split_new_and_old
+; CHECK: polly.merge_new_and_old
+
+
+
diff --git a/rc1/test/Cloog/CodeGen/vector_load_from_bitcast.ll b/rc1/test/Cloog/CodeGen/vector_load_from_bitcast.ll
new file mode 100644
index 0000000..bee5657
--- /dev/null
+++ b/rc1/test/Cloog/CodeGen/vector_load_from_bitcast.ll
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -tbaa -polly-codegen -polly-vectorizer=polly -S < %s | FileCheck %s
+
+target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"
+target triple = "i386-apple-macosx10.8.0"
+
+define void @foo(float** %tone)  {
+preheader:
+  br label %for
+
+for:
+  %indvar = phi i32 [ %indvar.next, %for ], [ 0, %preheader ]
+  %ptr1 = getelementptr inbounds float** %tone, i32 0
+  %val = load float** %ptr1, align 4, !tbaa !2817
+  %ptr2 = getelementptr float* %val, i32 %indvar
+  %re115 = bitcast float* %ptr2 to float*
+; CHECK: %val_p_vec_p = bitcast float** %p_ptr1 to <1 x float*>*
+
+  %scevgep3 = getelementptr float* %val, i32 %indvar
+  %scevgep162163 = bitcast float* %scevgep3 to float*
+  %ptr5 = load float* %scevgep162163, !tbaa !2816
+; CHECK: load <4 x float>
+  %add = fadd float undef, %ptr5
+  store float %add, float* %re115, !tbaa !2816
+; CHECK: store <4 x float>
+
+  %indvar.next = add nsw i32 %indvar, 1
+  %exitcond = icmp ne i32 %indvar.next, 4
+  br i1 %exitcond, label %for, label %end
+
+end:
+  unreachable
+}
+
+!2814 = metadata !{metadata !"Simple C/C++ TBAA"}
+!2813 = metadata !{metadata !"omnipotent char", metadata !2814, i64 0}
+!2816 = metadata !{metadata !"int", metadata !2813, i64 0}
+!2817 = metadata !{metadata !"short", metadata !2813, i64 0}
diff --git a/rc1/test/Cloog/ScheduleOptimizer/2011-08-25-crash_in_vectorizer.ll b/rc1/test/Cloog/ScheduleOptimizer/2011-08-25-crash_in_vectorizer.ll
new file mode 100644
index 0000000..785b5f7
--- /dev/null
+++ b/rc1/test/Cloog/ScheduleOptimizer/2011-08-25-crash_in_vectorizer.ll
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -polly-opt-isl -polly-cloog -analyze < %s -S | FileCheck %s
+; RUN: opt %loadPolly -polly-opt-isl -polly-cloog -analyze %vector-opt < %s -S | FileCheck %s -check-prefix=VECTOR
+
+
+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 @f(i32* nocapture %A, i32 %N, i32 %C) nounwind {
+bb:
+  %tmp1 = icmp sgt i32 %N, 0
+  br i1 %tmp1, label %.lr.ph, label %._crit_edge
+
+.lr.ph:                                           ; preds = %bb
+  %tmp = zext i32 %N to i64
+  br label %bb2
+
+bb2:                                              ; preds = %bb2, %.lr.ph
+  %indvar = phi i64 [ 0, %.lr.ph ], [ %indvar.next, %bb2 ]
+  %scevgep = getelementptr i32* %A, i64 %indvar
+  %tmp3 = load i32* %scevgep, align 4
+  %tmp4 = add nsw i32 %tmp3, %C
+  store i32 %tmp4, i32* %scevgep, align 4
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %tmp
+  br i1 %exitcond, label %._crit_edge, label %bb2
+
+._crit_edge:                                      ; preds = %bb2, %bb
+  ret void
+}
+
+; CHECK: if (p_0 >= 1) {
+; CHECK:     for (c1=0;c1<=p_0-1;c1++) {
+; CHECK:         Stmt_bb2(c1);
+; CHECK:     }
+; CHECK: }
+
+; VECTOR: if (p_0 >= 1) {
+; VECTOR:   for (c1=0;c1<=p_0-1;c1+=4) {
+; VECTOR:     for (c2=c1;c2<=min(c1+3,p_0-1);c2++) {
+; VECTOR:       Stmt_bb2(c2);
+; VECTOR:     }
+; VECTOR:   }
+; VECTOR: }
diff --git a/rc1/test/Cloog/ScopDetection/single_function_only.ll b/rc1/test/Cloog/ScopDetection/single_function_only.ll
new file mode 100644
index 0000000..527a5ed
--- /dev/null
+++ b/rc1/test/Cloog/ScopDetection/single_function_only.ll
@@ -0,0 +1,122 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog -analyze -polly-only-func=bar < %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 i32 @foo() 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
+}
+
+define i32 @bar() 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-NOT: foo()
+; CHECK:bar()
+; CHECK:for (c2=0;c2<=1023;c2++) {
+; CHECK:    Stmt_for_body(c2);
+; CHECK:}
diff --git a/rc1/test/Cloog/ambigous_schedule.ll b/rc1/test/Cloog/ambigous_schedule.ll
new file mode 100644
index 0000000..23f6e12
--- /dev/null
+++ b/rc1/test/Cloog/ambigous_schedule.ll
@@ -0,0 +1,118 @@
+; RUN: opt %loadPolly %defaultOpts -polly-import-jscop-dir=%S -polly-import-jscop -polly-cloog -analyze < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [100 x [100 x double]] zeroinitializer, align 16
+@B = common global [100 x [100 x double]] zeroinitializer, align 16
+
+define void @ambigous_schedule() nounwind uwtable {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+  %cmp = icmp slt i32 %i.0, 100
+  br i1 %cmp, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %cmp2 = icmp slt i32 %j.0, 100
+  br i1 %cmp2, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %add = add nsw i32 %i.0, %j.0
+  %conv = sitofp i32 %add to double
+  %idxprom = sext i32 %j.0 to i64
+  %idxprom4 = sext i32 %i.0 to i64
+  %arrayidx = getelementptr inbounds [100 x [100 x double]]* @A, i32 0, i64 %idxprom4
+  %arrayidx5 = getelementptr inbounds [100 x double]* %arrayidx, i32 0, i64 %idxprom
+  store double %conv, double* %arrayidx5, align 8
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %for.end
+  %inc7 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  br label %for.cond10
+
+for.cond10:                                       ; preds = %for.inc28, %for.end8
+  %i9.0 = phi i32 [ 0, %for.end8 ], [ %inc29, %for.inc28 ]
+  %cmp11 = icmp slt i32 %i9.0, 100
+  br i1 %cmp11, label %for.body13, label %for.end30
+
+for.body13:                                       ; preds = %for.cond10
+  br label %for.cond15
+
+for.cond15:                                       ; preds = %for.inc25, %for.body13
+  %j14.0 = phi i32 [ 0, %for.body13 ], [ %inc26, %for.inc25 ]
+  %cmp16 = icmp slt i32 %j14.0, 100
+  br i1 %cmp16, label %for.body18, label %for.end27
+
+for.body18:                                       ; preds = %for.cond15
+  %add19 = add nsw i32 %i9.0, %j14.0
+  %conv20 = sitofp i32 %add19 to double
+  %idxprom21 = sext i32 %j14.0 to i64
+  %idxprom22 = sext i32 %i9.0 to i64
+  %arrayidx23 = getelementptr inbounds [100 x [100 x double]]* @B, i32 0, i64 %idxprom22
+  %arrayidx24 = getelementptr inbounds [100 x double]* %arrayidx23, i32 0, i64 %idxprom21
+  store double %conv20, double* %arrayidx24, align 8
+  br label %for.inc25
+
+for.inc25:                                        ; preds = %for.body18
+  %inc26 = add nsw i32 %j14.0, 1
+  br label %for.cond15
+
+for.end27:                                        ; preds = %for.cond15
+  br label %for.inc28
+
+for.inc28:                                        ; preds = %for.end27
+  %inc29 = add nsw i32 %i9.0, 1
+  br label %for.cond10
+
+for.end30:                                        ; preds = %for.cond10
+  ret void
+}
+
+; CHECK: for (c2=0;c2<=99;c2++) {
+; CHECK:   for (c3=0;c3<=99;c3++) {
+; CHECK:     Stmt_for_body3(c2,c3);
+; CHECK:     Stmt_for_body18(c3,c2);
+; CHECK:   }
+; CHECK: }
+
+; This check makes sure CLooG stops splitting for ambigious schedules as
+; they may be generated by the isl/PoCC/Pluto schedule optimizers.
+;
+; Previously we created such code:
+;
+; for (c2=0;c2<=99;c2++) {
+;   for (c3=0;c3<=99;c3++) {
+;     if (c2 == c3) {
+;       Stmt_for_body3(c2,c2);
+;       Stmt_for_body18(c2,c2);
+;     }
+;     if (c2 <= c3-1) {
+;       Stmt_for_body3(c2,c3);
+;     }
+;     if (c2 <= c3-1) {
+;       Stmt_for_body18(c3,c2);
+;     }
+;     if (c2 >= c3+1) {
+;       Stmt_for_body18(c3,c2);
+;     }
+;     if (c2 >= c3+1) {
+;       Stmt_for_body3(c2,c3);
+;     }
+;   }
+; }
diff --git a/rc1/test/Cloog/ambigous_schedule___%for.cond---%for.end30.jscop b/rc1/test/Cloog/ambigous_schedule___%for.cond---%for.end30.jscop
new file mode 100644
index 0000000..ec9f89c
--- /dev/null
+++ b/rc1/test/Cloog/ambigous_schedule___%for.cond---%for.end30.jscop
@@ -0,0 +1,28 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end30",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[100i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 99 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, i1, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body18[i0, i1] -> MemRef_B[100i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body18[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 99 }",
+         "name" : "Stmt_for_body18",
+         "schedule" : "{ Stmt_for_body18[i0, i1] -> scattering[0, i1, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Cloog/lit.local.cfg b/rc1/test/Cloog/lit.local.cfg
new file mode 100644
index 0000000..e1ac512
--- /dev/null
+++ b/rc1/test/Cloog/lit.local.cfg
@@ -0,0 +1,3 @@
+cloog = config.root.cloog_found
+if cloog not in ['TRUE', 'true', 'yes', 'YES'] :
+    config.unsupported = True
diff --git a/rc1/test/CodePreparation/if_condition.ll b/rc1/test/CodePreparation/if_condition.ll
new file mode 100644
index 0000000..fde60a2
--- /dev/null
+++ b/rc1/test/CodePreparation/if_condition.ll
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -polly-prepare -S < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-prepare -S -polly-codegen-scev < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;   for (i = 0; i < N; ++i)
+;     A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br label %for.i
+; CHECK: entry:
+; CHECK: %value.reg2mem = alloca i64
+; CHECK: br label %entry.split
+
+for.i:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %merge ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  %cmp = icmp eq i64 %indvar, 3
+  br i1 %cmp, label %then, label %else
+
+then:
+  %add_two = add i64 %indvar, 2
+  br label %merge
+; CHECK: then:
+; CHECK:   %add_two = add i64 %indvar, 2
+; CHECK:   store i64 %add_two, i64* %value.reg2mem
+; CHECK:   br label %merge
+
+else:
+  %add_three = add i64 %indvar, 4
+  br label %merge
+; CHECK: else:
+; CHECK:   %add_three = add i64 %indvar, 4
+; CHECK:   store i64 %add_three, i64* %value.reg2mem
+; CHECK:   br label %merge
+
+merge:
+  %value = phi i64 [ %add_two, %then ], [ %add_three, %else ]
+  store i64 %value, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
diff --git a/rc1/test/CodePreparation/multiple_loops_trivial_phis.ll b/rc1/test/CodePreparation/multiple_loops_trivial_phis.ll
new file mode 100644
index 0000000..f8964ae
--- /dev/null
+++ b/rc1/test/CodePreparation/multiple_loops_trivial_phis.ll
@@ -0,0 +1,56 @@
+; RUN: opt %loadPolly -S -polly-prepare < %s | FileCheck %s
+; ModuleID = 'multiple_loops_trivial_phis.ll'
+;
+; int f(int * __restrict__ A) {
+;   int i, j, sum = 0;
+;   for (i = 0; i < 100; i++) {
+;     sum *= 2;
+;     for (j = 0; j < 100; j++) {
+;       sum += A[i+j];
+;     }
+;   }
+;   return sum;
+; }
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define i32 @f(i32* noalias %A) #0 {
+entry:
+  br label %for.body
+
+for.body:                                         ; preds = %entry, %for.inc5
+  %sum.04 = phi i32 [ 0, %entry ], [ %add4.lcssa, %for.inc5 ]
+  %indvars.iv23 = phi i64 [ 0, %entry ], [ %2, %for.inc5 ]
+  %mul = shl nsw i32 %sum.04, 1
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body, %for.inc
+  %sum.12 = phi i32 [ %mul, %for.body ], [ %add4, %for.inc ]
+  %indvars.iv1 = phi i64 [ 0, %for.body ], [ %1, %for.inc ]
+  %0 = add i64 %indvars.iv23, %indvars.iv1
+  %arrayidx = getelementptr i32* %A, i64 %0
+  %tmp5 = load i32* %arrayidx, align 4
+  %add4 = add nsw i32 %tmp5, %sum.12
+  %1 = add nuw nsw i64 %indvars.iv1, 1
+  %exitcond5 = icmp eq i64 %1, 100
+  br i1 %exitcond5, label %for.inc5, label %for.inc
+
+for.inc5:                                         ; preds = %for.inc
+  %add4.lcssa = phi i32 [ %add4, %for.inc ]
+  %2 = add nuw nsw i64 %indvars.iv23, 1
+  %exitcond = icmp eq i64 %2, 100
+  br i1 %exitcond, label %for.end7, label %for.body
+
+for.end7:                                         ; preds = %for.inc5
+  %add4.lcssa.lcssa = phi i32 [ %add4.lcssa, %for.inc5 ]
+  ret i32 %add4.lcssa.lcssa
+}
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+; Verify that only two allocas are created. (instead of 4!)
+; CHECK: alloca
+; CHECK: alloca
+; CHECK-NOT: alloca
diff --git a/rc1/test/CodePreparation/single_loop_trivial_phi.ll b/rc1/test/CodePreparation/single_loop_trivial_phi.ll
new file mode 100644
index 0000000..e404da5
--- /dev/null
+++ b/rc1/test/CodePreparation/single_loop_trivial_phi.ll
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly -S -polly-prepare < %s | FileCheck %s
+; ModuleID = 'single_loop_trivial_phi.ll'
+;
+; int f(int *A, int N) {
+;   int i, sum = 0;
+;   for (i = 0; i < N; i++)
+;     sum += A[i];
+;   return sum;
+; }
+; ModuleID = 'stack-slots.ll'
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define i32 @f(i32* %A, i32 %N) #0 {
+entry:
+  %cmp1 = icmp sgt i32 %N, 0
+  br i1 %cmp1, label %for.inc.lr.ph, label %for.end
+
+for.inc.lr.ph:                                    ; preds = %entry
+  %0 = zext i32 %N to i64
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.inc.lr.ph, %for.inc
+  %sum.03 = phi i32 [ 0, %for.inc.lr.ph ], [ %add, %for.inc ]
+  %indvars.iv2 = phi i64 [ 0, %for.inc.lr.ph ], [ %indvars.iv.next, %for.inc ]
+  %arrayidx = getelementptr i32* %A, i64 %indvars.iv2
+  %tmp1 = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp1, %sum.03
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv2, 1
+  %exitcond = icmp ne i64 %indvars.iv.next, %0
+  br i1 %exitcond, label %for.inc, label %for.cond.for.end_crit_edge
+
+for.cond.for.end_crit_edge:                       ; preds = %for.inc
+  %add.lcssa = phi i32 [ %add, %for.inc ]
+  br label %for.end
+
+for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
+  %sum.0.lcssa = phi i32 [ %add.lcssa, %for.cond.for.end_crit_edge ], [ 0, %entry ]
+  ret i32 %sum.0.lcssa
+}
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+; Verify that only two allocas are created.
+; Both are needed for the %sum.0 PHI node and none should be created for the
+; %sum.0.lcssa PHI node
+; CHECK: alloca
+; CHECK: alloca
+; CHECK-NOT: alloca
diff --git a/rc1/test/DeadCodeElimination/chained_iterations.ll b/rc1/test/DeadCodeElimination/chained_iterations.ll
new file mode 100644
index 0000000..5df2a59
--- /dev/null
+++ b/rc1/test/DeadCodeElimination/chained_iterations.ll
@@ -0,0 +1,62 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dependences-analysis-type=value-based -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt -S %loadPolly -basicaa -polly-dependences-analysis-type=value-based -polly-dce -polly-ast -analyze < %s | FileCheck %s -check-prefix=CHECK-DCE
+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"
+;
+; for(i = 0; i < 200; i++ )
+;   A[i] = 2;
+;
+; for (i = 0; i < 200; i++ )
+;   A[i]  = 5;
+;
+; for (i = 0; i < 200; i++ )
+;   A[i] = 5;
+define void @main() nounwind uwtable {
+entry:
+  %A = alloca [200 x i32], align 16
+  br label %for.body.1
+
+for.body.1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %for.body.1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1, align 4
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 200
+  br i1 %exitcond.1, label %for.body.1, label %exit.1
+
+exit.1:
+  br label %for.body.2
+
+for.body.2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %for.body.2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2, align 4
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 200
+  br i1 %exitcond.2, label %for.body.2, label %exit.2
+
+exit.2:
+  br label %for.body.3
+
+for.body.3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %for.body.3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  store i32 7, i32* %arrayidx.3, align 4
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %for.body.3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK:   Stmt_for_body_1(c1);
+; CHECK: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK:   Stmt_for_body_2(c1);
+; CHECK: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK:   Stmt_for_body_3(c1);
+
+; CHECK-DCE: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK-DCE:   Stmt_for_body_3(c1);
+
diff --git a/rc1/test/DeadCodeElimination/chained_iterations_2.ll b/rc1/test/DeadCodeElimination/chained_iterations_2.ll
new file mode 100644
index 0000000..5c84057
--- /dev/null
+++ b/rc1/test/DeadCodeElimination/chained_iterations_2.ll
@@ -0,0 +1,66 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dependences-analysis-type=value-based -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt -S %loadPolly -basicaa -polly-dependences-analysis-type=value-based -polly-dce -polly-ast -analyze < %s | FileCheck %s -check-prefix=CHECK-DCE
+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"
+;
+; for(i = 0; i < 200; i++ )
+;   A[i] = 2;
+;
+; for (i = 0; i < 200; i++ )
+;   B[i] = A[i];
+;
+; for (i = 0; i < 200; i++ )
+;   B[i] = A[i] = 5;
+define void @main() nounwind uwtable {
+entry:
+  %A = alloca [200 x i32], align 16
+  %B = alloca [200 x i32], align 16
+  br label %for.body.1
+
+for.body.1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %for.body.1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1, align 4
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 200
+  br i1 %exitcond.1, label %for.body.1, label %exit.1
+
+exit.1:
+  br label %for.body.2
+
+for.body.2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %for.body.2 ]
+  %arrayidx.2.a = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  %val = load i32* %arrayidx.2.a, align 4
+  %arrayidx.2.b = getelementptr [200 x i32]* %B, i64 0, i64 %indvar.2
+  store i32 %val, i32* %arrayidx.2.b, align 4
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 200
+  br i1 %exitcond.2, label %for.body.2, label %exit.2
+
+exit.2:
+  br label %for.body.3
+
+for.body.3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %for.body.3 ]
+  %arrayidx.3.a = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  %arrayidx.3.b = getelementptr [200 x i32]* %B, i64 0, i64 %indvar.3
+  store i32 5, i32* %arrayidx.3.a, align 4
+  store i32 5, i32* %arrayidx.3.b, align 4
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %for.body.3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK:   Stmt_for_body_1(c1);
+; CHECK: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK:   Stmt_for_body_2(c1);
+; CHECK: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK:   Stmt_for_body_3(c1);
+
+; CHECK-DCE: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK-DCE:   Stmt_for_body_3(c1);
diff --git a/rc1/test/DeadCodeElimination/computeout.ll b/rc1/test/DeadCodeElimination/computeout.ll
new file mode 100644
index 0000000..a908c4e
--- /dev/null
+++ b/rc1/test/DeadCodeElimination/computeout.ll
@@ -0,0 +1,64 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dce -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt -S %loadPolly -basicaa -polly-dce -polly-ast -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
+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"
+
+;     for(i = 0; i < 100; i++ )
+; S1:   A[i] = 2;
+;
+;     for (i = 0; i < 10; i++ )
+; S2:   A[i]  = 5;
+;
+;     for (i = 0; i < 200; i++ )
+; S3:   A[i] = 5;
+
+define void @sequential_writes() {
+entry:
+  %A = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  br label %S3
+
+S3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  store i32 7, i32* %arrayidx.3
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; CHECK-NOT: Stmt_S
+; CHECK: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK: Stmt_S3(c1);
+
+; TIMEOUT: for (int c1 = 0; c1 <= 99; c1 += 1)
+; TIMEOUT: Stmt_S1(c1);
+; TIMEOUT: for (int c1 = 0; c1 <= 9; c1 += 1)
+; TIMEOUT: Stmt_S2(c1);
+; TIMEOUT: for (int c1 = 0; c1 <= 199; c1 += 1)
+; TIMEOUT: Stmt_S3(c1);
+
diff --git a/rc1/test/DeadCodeElimination/dead_iteration_elimination.ll b/rc1/test/DeadCodeElimination/dead_iteration_elimination.ll
new file mode 100644
index 0000000..8549a0c
--- /dev/null
+++ b/rc1/test/DeadCodeElimination/dead_iteration_elimination.ll
@@ -0,0 +1,79 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dependences-analysis-type=value-based -polly-dce -polly-dce-precise-steps=2 -polly-ast -analyze < %s | FileCheck %s -check-prefix=CHECK
+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"
+;
+; for(i = 0; i < 200; i++ )
+;   A[i] = 2;
+;
+; for (i = 0; i < 50; i++ )
+;   A[i]  = 5;
+;
+; for (i = 0; i < 70; i++ )
+;   A[i] = A[i] + 5;
+;
+; for (i = 100; i < 110; i++ )
+;   A[i] = i;
+;
+define void @main() nounwind uwtable {
+entry:
+  %A = alloca [200 x i32], align 16
+  br label %for.body.1
+
+for.body.1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %for.body.1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1, align 4
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 200
+  br i1 %exitcond.1, label %for.body.1, label %exit.1
+
+exit.1:
+  br label %for.body.2
+
+for.body.2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %for.body.2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2, align 4
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 50
+  br i1 %exitcond.2, label %for.body.2, label %exit.2
+
+exit.2:
+  br label %for.body.3
+
+for.body.3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %for.body.3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  %val = load i32* %arrayidx.3, align 4
+  %add = add nsw i32 %val, 5
+  store i32 %add, i32* %arrayidx.3, align 4
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 70
+  br i1 %exitcond.3, label %for.body.3 , label %exit.3
+
+exit.3:
+  br label %for.body.4
+
+for.body.4:
+  %indvar.4 = phi i64 [ 0, %exit.3 ], [ %indvar.next.4, %for.body.4 ]
+  %indvar.plus = add i64 %indvar.4, 100
+  %trunc = trunc i64 %indvar.plus to i32
+  %arrayidx.4 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.plus
+  store i32 %trunc, i32* %arrayidx.4, align 4
+  %indvar.next.4 = add i64 %indvar.4, 1
+  %exitcond.4 = icmp ne i64 %indvar.next.4, 10
+  br i1 %exitcond.4, label %for.body.4, label %exit.4
+
+exit.4:
+  ret void
+}
+
+; CHECK: for (int c1 = 50; c1 <= 99; c1 += 1)
+; CHECK:   Stmt_for_body_1(c1);
+; CHECK: for (int c1 = 110; c1 <= 199; c1 += 1)
+; CHECK:   Stmt_for_body_1(c1);
+; CHECK: for (int c1 = 0; c1 <= 49; c1 += 1)
+; CHECK:   Stmt_for_body_2(c1);
+; CHECK: for (int c1 = 0; c1 <= 69; c1 += 1)
+; CHECK:   Stmt_for_body_3(c1);
+; CHECK: for (int c1 = 0; c1 <= 9; c1 += 1)
diff --git a/rc1/test/DeadCodeElimination/non-affine-affine-mix.ll b/rc1/test/DeadCodeElimination/non-affine-affine-mix.ll
new file mode 100644
index 0000000..24b04a1
--- /dev/null
+++ b/rc1/test/DeadCodeElimination/non-affine-affine-mix.ll
@@ -0,0 +1,60 @@
+; RUN: opt %loadPolly -polly-allow-nonaffine -polly-dce -polly-ast -analyze < %s | FileCheck %s
+;
+;    void f(int *A) {
+;      for (int i = 0; i < 1024; i++)
+; S1:    A[i % 2] = i;
+;      for (int i = 0; i < 1024; i++)
+; S2:    A[i2] = i;
+;    }
+
+; We unfortunately do need to execute all iterations of S1, as we do not know
+; the size of A and as a result S1 may write for example to A[1024], which
+; is not overwritten by S2.
+
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:   Stmt_S1(c1);
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:   Stmt_S2(c1);
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %S1, label %next
+
+S1:
+  %rem = srem i32 %i.0, 2
+  %arrayidx = getelementptr inbounds i32* %A, i32 %rem
+  store i32 %i.0, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+next:
+ br label %for.cond.2
+
+for.cond.2:
+  %i.2 = phi i32 [ 0, %next ], [ %inc.2, %for.inc.2 ]
+  %exitcond.2 = icmp ne i32 %i.2, 1024
+  br i1 %exitcond.2, label %S2, label %for.end
+
+S2:
+  %arrayidx.2 = getelementptr inbounds i32* %A, i32 %i.2
+  store i32 %i.2, i32* %arrayidx.2, align 4
+  br label %for.inc.2
+
+for.inc.2:
+  %inc.2 = add nsw i32 %i.2, 1
+  br label %for.cond.2
+
+for.end:
+  ret void
+}
+
diff --git a/rc1/test/DeadCodeElimination/non-affine.ll b/rc1/test/DeadCodeElimination/non-affine.ll
new file mode 100644
index 0000000..fff9353
--- /dev/null
+++ b/rc1/test/DeadCodeElimination/non-affine.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-allow-nonaffine -polly-dce -polly-ast -analyze < %s | FileCheck %s
+;
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+;
+;    void f(int *A) {
+;      for (int i = 0; i < 1024; i++)
+;        A[i % 2] = i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %rem = srem i32 %i.0, 2
+  %arrayidx = getelementptr inbounds i32* %A, i32 %rem
+  store i32 %i.0, i32* %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
+  ret void
+}
+
diff --git a/rc1/test/DeadCodeElimination/null_schedule.ll b/rc1/test/DeadCodeElimination/null_schedule.ll
new file mode 100644
index 0000000..106eac2
--- /dev/null
+++ b/rc1/test/DeadCodeElimination/null_schedule.ll
@@ -0,0 +1,57 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dependences-analysis-type=value-based -polly-dce -polly-ast -analyze < %s | FileCheck %s -check-prefix=CHECK-DCE
+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[0] = 1;
+;
+; for(i = 0; i < 100; i++ )
+;   A[i+1] = A[i] * 2;
+;
+; for (i = 0; i < 200; i++ )
+;   A[i] = B[i] * 2;
+
+define void @main() nounwind uwtable {
+
+entry:
+  %A = alloca [200 x i32], align 16
+  %B = alloca [200 x i32], align 16
+
+  %A.zero = getelementptr [200 x i32]* %A, i64 0, i64 0
+  store i32 1, i32* %A.zero, align 4
+
+  br label %for.body.1
+
+for.body.1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %for.body.1 ]
+  %indvar.next.1 = add i64 %indvar.1, 1
+
+  %A.current.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  %val1.1 = load i32* %A.current.1, align 4
+  %val2.1 = mul i32 %val1.1, 2
+  %A.next.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.next.1
+  store i32 %val2.1, i32* %A.next.1, align 4
+
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %for.body.1, label %exit.1
+
+exit.1:
+  br label %for.body.2
+
+for.body.2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %for.body.2 ]
+
+  %B.current.2 = getelementptr [200 x i32]* %B, i64 0, i64 %indvar.2
+  %val1.2 = load i32* %B.current.2, align 4
+  %val2.2 = mul i32 %val1.2, 2
+  %A.current.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 %val2.2, i32* %A.current.2, align 4
+
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 200
+  br i1 %exitcond.2, label %for.body.2, label %exit.3
+
+exit.3:
+  ret void
+}
+
+; CHECK-DCE: for (int c1 = 0; c1 <= 199; c1 += 1)
+; CHECK-DCE:   Stmt_for_body_2(c1);
diff --git a/rc1/test/Dependences/computeout.ll b/rc1/test/Dependences/computeout.ll
new file mode 100644
index 0000000..c2339d2
--- /dev/null
+++ b/rc1/test/Dependences/computeout.ll
@@ -0,0 +1,72 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
+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"
+
+;     for(i = 0; i < 100; i++ )
+; S1:   A[i] = 2;
+;
+;     for (i = 0; i < 10; i++ )
+; S2:   A[i]  = 5;
+;
+;     for (i = 0; i < 200; i++ )
+; S3:   A[i] = 5;
+
+define void @sequential_writes() {
+entry:
+  %A = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  br label %S3
+
+S3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  store i32 7, i32* %arrayidx.3
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'sequential_writes':
+; VALUE:   RAW dependences:
+; VALUE:     {  }
+; VALUE:   WAR dependences:
+; VALUE:     {  }
+; VALUE:   WAW dependences:
+; VALUE:     {
+; VALUE:       Stmt_S1[i0] -> Stmt_S2[i0] : i0 >= 0 and i0 <= 9;
+; VALUE:       Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9;
+; VALUE:       Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 10 and i0 <= 99
+; VALUE:     }
+
+; TIMEOUT: region: 'S1 => exit.3' in function 'sequential_writes':
+; TIMEOUT:   RAW dependences:
+; TIMEOUT:     n/a
+; TIMEOUT:   WAR dependences:
+; TIMEOUT:     n/a
+; TIMEOUT:   WAW dependences:
+; TIMEOUT:     n/a
diff --git a/rc1/test/Dependences/do_pluto_matmult.ll b/rc1/test/Dependences/do_pluto_matmult.ll
new file mode 100644
index 0000000..7d9799e
--- /dev/null
+++ b/rc1/test/Dependences/do_pluto_matmult.ll
@@ -0,0 +1,80 @@
+; RUN: opt %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=value-based < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=memory-based -polly-delinearize < %s | FileCheck %s -check-prefix=MEMORY
+
+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]
+
+define void @do_pluto_matmult() nounwind {
+entry:
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+; VALUE: RAW dependences:
+; VALUE:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 34 }
+; VALUE: WAR dependences:
+; VALUE:  {  }
+; VALUE: WAW dependences:
+; VALUE:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 34 }
+
+; MEMORY: RAW dependences:
+; MEMORY:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 >= 0 and o2 >= 1 + i2 and o2 <= 35 and o2 >= 0 }
+; MEMORY: WAR dependences:
+; MEMORY:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 >= 0 and o2 >= 1 + i2 and o2 <= 35 and o2 >= 0 }
+; MEMORY: WAW dependences:
+; MEMORY:  { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 >= 0 and o2 >= 1 + i2 and o2 <= 35 and o2 >= 0 }
diff --git a/rc1/test/Dependences/reduction_complex_location.ll b/rc1/test/Dependences/reduction_complex_location.ll
new file mode 100644
index 0000000..8ed46b7
--- /dev/null
+++ b/rc1/test/Dependences/reduction_complex_location.ll
@@ -0,0 +1,59 @@
+; RUN: opt -basicaa %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK:   { Stmt_for_body3[i0, i1] -> Stmt_for_body3[2 + i0, -1 + i1] : i0 <= 97 and i0 >= 0 and i1 <= 99 and i1 >= 1 }
+;
+; void f(int *sum) {
+;   for (int i = 0; i < 100; i++)
+;     for (int j = 0; j < 100; j++)
+;       sum[i+j*2] += j * i;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+  %exitcond1 = icmp ne i32 %i.0, 100
+  br i1 %exitcond1, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 100
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %mul = mul nsw i32 %j.0, %i.0
+  %mul4 = shl nsw i32 %j.0, 1
+  %add = add nsw i32 %i.0, %mul4
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %add
+  %tmp = load i32* %arrayidx, align 4
+  %add5 = add nsw i32 %tmp, %mul
+  store i32 %add5, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %for.end
+  %inc7 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_dependences_equal_non_reduction_dependences.ll b/rc1/test/Dependences/reduction_dependences_equal_non_reduction_dependences.ll
new file mode 100644
index 0000000..ef79880
--- /dev/null
+++ b/rc1/test/Dependences/reduction_dependences_equal_non_reduction_dependences.ll
@@ -0,0 +1,62 @@
+; RUN: opt %loadPolly -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; This loopnest contains a reduction which imposes the same dependences as the
+; accesses to the array A. We need to ensure we keep the dependences of A.
+;
+; CHECK: RAW dependences:
+; CHECK:   { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 >= 0 and i0 <= 1022 }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 >= 0 and i0 <= 1022 }
+; CHECK: Reduction dependences:
+; CHECK:   { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 <= 1022 and i0 >= 0 }
+;
+;
+;    void AandSum(int *restrict sum, int *restrict A) {
+;      for (int i = 0; i < 1024; i++) {
+;        A[i] = A[i] + A[i - 1];
+;        A[i - 1] = A[i] + A[i - 2];
+;        *sum += i;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @AandSum(i32* noalias %sum, i32* noalias %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %sub = add nsw i32 %i.0, -1
+  %arrayidx1 = getelementptr inbounds i32* %A, i32 %sub
+  %tmp1 = load i32* %arrayidx1, align 4
+  %add = add nsw i32 %tmp, %tmp1
+  %arrayidx2 = getelementptr inbounds i32* %A, i32 %i.0
+  store i32 %add, i32* %arrayidx2, align 4
+  %sub4 = add nsw i32 %i.0, -2
+  %arrayidx5 = getelementptr inbounds i32* %A, i32 %sub4
+  %tmp2 = load i32* %arrayidx5, align 4
+  %add6 = add nsw i32 %add, %tmp2
+  %sub7 = add nsw i32 %i.0, -1
+  %arrayidx8 = getelementptr inbounds i32* %A, i32 %sub7
+  store i32 %add6, i32* %arrayidx8, align 4
+  %tmp3 = load i32* %sum, align 4
+  %add9 = add nsw i32 %tmp3, %i.0
+  store i32 %add9, i32* %sum, 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
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_mixed_reduction_and_non_reduction_dependences.ll b/rc1/test/Dependences/reduction_mixed_reduction_and_non_reduction_dependences.ll
new file mode 100644
index 0000000..b114fe6
--- /dev/null
+++ b/rc1/test/Dependences/reduction_mixed_reduction_and_non_reduction_dependences.ll
@@ -0,0 +1,60 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_for_body3[i0, 1] -> Stmt_for_body3[1 + i0, o1] : i0 <= 1022 and i0 >= 0 and o1 <= 511 and o1 >= 1
+; CHECK-DAG: Stmt_for_body3[i0, 0] -> Stmt_for_body3[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 511 and o1 >= 1
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[1 + i0, -1 + i1] : i0 <= 1022 and i0 >= 0 and i1 <= 511 and i1 >= 2
+; CHECK-DAG: Stmt_for_body3[i0, 2] -> Stmt_for_body3[2 + i0, 0] : i0 <= 1021 and i0 >= 0
+; CHECK: Reduction dependences:
+; CHECK:   { Stmt_for_body3[i0, 1] -> Stmt_for_body3[1 + i0, 0] : i0 <= 1022 and i0 >= 0 }
+;
+; void f(int *sum) {
+;   for (int i = 0; i < 1024; i++)
+;     for (int j = 0; j < 512; j++)
+;       sum[i + j] = sum[i] + 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+  %exitcond1 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond1, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 512
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 3
+  %add4 = add nsw i32 %i.0, %j.0
+  %arrayidx5 = getelementptr inbounds i32* %sum, i32 %add4
+  store i32 %add, i32* %arrayidx5, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %for.end
+  %inc7 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_multiple_loops_array_sum.ll b/rc1/test/Dependences/reduction_multiple_loops_array_sum.ll
new file mode 100644
index 0000000..20903fb
--- /dev/null
+++ b/rc1/test/Dependences/reduction_multiple_loops_array_sum.ll
@@ -0,0 +1,77 @@
+; RUN: opt -basicaa %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; Verify that only the inner reduction like accesses cause reduction dependences
+;
+; CHECK: Reduction dependences:
+; CHECK:   { Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0 }
+;
+; void f(int * restrict A, int * restrict sum) {
+;   int i, j, k;
+;   for (i = 0; i < 100; i++) {
+;     *sum *= 7;
+;     for (j = 0; j < 100; j++) {
+;       *sum += A[i+j];
+;       for (k = 0; k< 100; k++) {}
+;     }
+;   }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %A, i32* noalias %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc11, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc12, %for.inc11 ]
+  %exitcond2 = icmp ne i32 %i.0, 100
+  br i1 %exitcond2, label %for.body, label %for.end13
+
+for.body:                                         ; preds = %for.cond
+  %tmp = load i32* %sum, align 4
+  %mul = mul nsw i32 %tmp, 7
+  store i32 %mul, i32* %sum, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc8, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc9, %for.inc8 ]
+  %exitcond1 = icmp ne i32 %j.0, 100
+  br i1 %exitcond1, label %for.body3, label %for.end10
+
+for.body3:                                        ; preds = %for.cond1
+  %add = add nsw i32 %i.0, %j.0
+  %arrayidx = getelementptr inbounds i32* %A, i32 %add
+  %tmp3 = load i32* %arrayidx, align 4
+  %tmp4 = load i32* %sum, align 4
+  %add4 = add nsw i32 %tmp4, %tmp3
+  store i32 %add4, i32* %sum, align 4
+  br label %for.cond5
+
+for.cond5:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %k.0, 100
+  br i1 %exitcond, label %for.body7, label %for.end
+
+for.body7:                                        ; preds = %for.cond5
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body7
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond5
+
+for.end:                                          ; preds = %for.cond5
+  br label %for.inc8
+
+for.inc8:                                         ; preds = %for.end
+  %inc9 = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end10:                                        ; preds = %for.cond1
+  br label %for.inc11
+
+for.inc11:                                        ; preds = %for.end10
+  %inc12 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end13:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_multiple_loops_array_sum_2.ll b/rc1/test/Dependences/reduction_multiple_loops_array_sum_2.ll
new file mode 100644
index 0000000..3398292
--- /dev/null
+++ b/rc1/test/Dependences/reduction_multiple_loops_array_sum_2.ll
@@ -0,0 +1,79 @@
+; RUN: opt %loadPolly -polly-dependences -analyze -basicaa < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0
+; CHECK-DAG: Stmt_for_body3[i0, 99] -> Stmt_for_body3[1 + i0, 0] : i0 <= 98 and i0 >= 0
+;
+; int f(int * restrict A, int * restrict sum) {
+;   int i, j, k;
+;   for (i = 0; i < 100; i++) {
+;     for (j = 0; j < 100; j++) {
+;       sum += A[i+j];
+;       for (k = 0; k< 100; k++) {}
+;     }
+;   }
+;   return sum;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %A, i32* noalias %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc11, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc12, %for.inc11 ]
+  %exitcond2 = icmp ne i32 %i.0, 100
+  br i1 %exitcond2, label %for.body, label %for.end13
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc8, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc9, %for.inc8 ]
+  %exitcond1 = icmp ne i32 %j.0, 100
+  br i1 %exitcond1, label %for.body3, label %for.end10
+
+for.body3:                                        ; preds = %for.cond1
+  %add = add nsw i32 %i.0, %j.0
+  %arrayidx = getelementptr inbounds i32* %A, i32 %add
+  %tmp3 = load i32* %arrayidx, align 4
+  %tmp4 = load i32* %sum, align 4
+  %add4 = add nsw i32 %tmp4, %tmp3
+  store i32 %add4, i32* %sum, align 4
+  br label %for.cond5
+
+for.cond5:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %k.0, 100
+  br i1 %exitcond, label %for.body7, label %for.end
+
+for.body7:                                        ; preds = %for.cond5
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body7
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond5
+
+for.end:                                          ; preds = %for.cond5
+  br label %for.inc8
+
+for.inc8:                                         ; preds = %for.end
+  %inc9 = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end10:                                        ; preds = %for.cond1
+  br label %for.inc11
+
+for.inc11:                                        ; preds = %for.end10
+  %inc12 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end13:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_multiple_loops_array_sum_3.ll b/rc1/test/Dependences/reduction_multiple_loops_array_sum_3.ll
new file mode 100644
index 0000000..4b699a1
--- /dev/null
+++ b/rc1/test/Dependences/reduction_multiple_loops_array_sum_3.ll
@@ -0,0 +1,73 @@
+; RUN: opt %loadPolly -polly-dependences -analyze -basicaa < %s | FileCheck %s
+;
+; CHECK: Reduction dependences:
+; CHECK:   { Stmt_for_inc[i0, i1] -> Stmt_for_inc[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0 }
+;
+; int f(int * __restrict__ A) {
+;   int i, j, sum = 0;
+;   for (k = 0; k < 37; k = g(k)) {
+;     for (i = 0; i < 100; i++) {
+;       sum *= 2;
+;       for (j = 0; j < 100; j++) {
+;         sum += A[i+j];
+;       }
+;     }
+;   }
+;   return sum;
+; }
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+declare i64 @g(i64)
+
+define i32 @f(i32* noalias %A) {
+entry:
+  %sum.04.reg2mem = alloca i32
+  %sum.12.reg2mem = alloca i32
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  store i32 0, i32* %sum.04.reg2mem
+  br label %for.body_outer_split
+
+for.body_outer_split:                             ; preds = %entry.split, %for.inc5
+  %indvars.ivK = phi i64 [ 0, %entry.split ], [ %incK, %for.bos2 ]
+  br label %for.body_outer
+
+for.body_outer:                                   ; preds = %for.body_outer_split
+  %incK = call i64 @g(i64 %indvars.ivK)
+  %exitcondK = icmp eq i64 %incK, 100
+  br i1 %exitcondK, label %for.end7, label %for.body
+
+for.body:                                         ; preds = %for.inc5, %for.body_outer
+  %indvars.iv23 = phi i64 [ 0, %for.body_outer ], [ %3, %for.inc5 ]
+  %sum.04.reload = load i32* %sum.04.reg2mem
+  %mul = shl nsw i32 %sum.04.reload, 1
+  store i32 %mul, i32* %sum.12.reg2mem
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.inc, %for.body
+  %indvars.iv1 = phi i64 [ 0, %for.body ], [ %1, %for.inc ]
+  %sum.12.reload = load i32* %sum.12.reg2mem
+  %0 = add i64 %indvars.iv23, %indvars.iv1
+  %arrayidx = getelementptr i32* %A, i64 %0
+  %tmp5 = load i32* %arrayidx, align 4
+  %add4 = add nsw i32 %tmp5, %sum.12.reload
+  %1 = add nuw nsw i64 %indvars.iv1, 1
+  %exitcond1 = icmp eq i64 %1, 100
+  store i32 %add4, i32* %sum.12.reg2mem
+  br i1 %exitcond1, label %for.inc5, label %for.inc
+
+for.inc5:                                         ; preds = %for.inc
+  %2 = load i32* %sum.12.reg2mem
+  %3 = add nuw nsw i64 %indvars.iv23, 1
+  %exitcond2 = icmp eq i64 %3, 100
+  store i32 %2, i32* %sum.04.reg2mem
+  br i1 %exitcond2, label %for.bos2, label %for.body
+
+for.bos2:
+  br label %for.body_outer_split
+
+for.end7:                                         ; preds = %for.inc5
+  %4 = load i32* %sum.04.reg2mem
+  ret i32 %4
+}
diff --git a/rc1/test/Dependences/reduction_multiple_reductions.ll b/rc1/test/Dependences/reduction_multiple_reductions.ll
new file mode 100644
index 0000000..461f9e4
--- /dev/null
+++ b/rc1/test/Dependences/reduction_multiple_reductions.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; Verify we do not have dependences between the if and the else clause
+;
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_if_then[i0] -> Stmt_if_then[1 + i0] : i0 <= 510 and i0 >= 0
+; CHECK-DAG: Stmt_if_else[i0] -> Stmt_if_else[1 + i0] : i0 <= 1022 and i0 >= 512
+;
+; void f(int *restrict sum, int *restrict prod) {
+;   for (int i = 0; i < 1024; i++)
+;     if (i < 512)
+;       *sum += i;
+;     else
+;       *prod *= i;
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %sum, i32* noalias %prod)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %cmp1 = icmp slt i32 %i.0, 512
+  br i1 %cmp1, label %if.then, label %if.else
+
+if.then:                                          ; preds = %for.body
+  %tmp = load i32* %sum, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %sum, align 4
+  br label %if.end
+
+if.else:                                          ; preds = %for.body
+  %tmp1 = load i32* %prod, align 4
+  %mul = mul nsw i32 %tmp1, %i.0
+  store i32 %mul, i32* %prod, align 4
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  br label %for.inc
+
+for.inc:                                          ; preds = %if.end
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_multiple_reductions_2.ll b/rc1/test/Dependences/reduction_multiple_reductions_2.ll
new file mode 100644
index 0000000..6d1053b
--- /dev/null
+++ b/rc1/test/Dependences/reduction_multiple_reductions_2.ll
@@ -0,0 +1,110 @@
+; RUN: opt %loadPolly -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[i0] : i0 <= 1023 and i0 >= 0 and i1 <= 1023 and i1 >= 0
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 1022
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; These are the important RAW dependences, as they need to originate/end in only one iteration:
+; CHECK-DAG: Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[i0] : i0 <= 1023 and i0 >= 0 and i1 <= 1023 and i1 >= 0
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 1022
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; These are the important WAW dependences, as they need to originate/end in only one iteration:
+; CHECK-DAG: Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+; CHECK: Reduction dependences:
+; CHECK-DAG:  Stmt_S1[i0, i1] -> Stmt_S1[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+; CHECK-DAG:  Stmt_S2[i0, i1] -> Stmt_S2[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+;
+;    void f(int *restrict red) {
+;      for (int j = 0; j < 1024; j++) {
+; S0:    *red = 42 + *red * 5;
+;        for (int i = 0; i < 1024; i++)
+; S1:      *red *= i;
+;        for (int i = 0; i < 1024; i++)
+; S2:      *red += i;
+; S3:    *red = 42 + *red * 7;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %red)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc15, %entry
+  %j.0 = phi i32 [ 0, %entry ], [ %inc16, %for.inc15 ]
+  %exitcond2 = icmp ne i32 %j.0, 1024
+  br i1 %exitcond2, label %for.body, label %for.end17
+
+for.body:                                         ; preds = %for.cond
+  br label %S0
+
+S0:                                               ; preds = %for.body
+  %tmp = load i32* %red, align 4
+  %mul = mul nsw i32 %tmp, 5
+  %add = add nsw i32 %mul, 42
+  store i32 %add, i32* %red, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %S0
+  %i.0 = phi i32 [ 0, %S0 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  br label %S1
+
+S1:                                               ; preds = %for.body3
+  %tmp3 = load i32* %red, align 4
+  %mul4 = mul nsw i32 %tmp3, %i.0
+  store i32 %mul4, i32* %red, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S1
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.cond6
+
+for.cond6:                                        ; preds = %for.inc10, %for.end
+  %i5.0 = phi i32 [ 0, %for.end ], [ %inc11, %for.inc10 ]
+  %exitcond1 = icmp ne i32 %i5.0, 1024
+  br i1 %exitcond1, label %for.body8, label %for.end12
+
+for.body8:                                        ; preds = %for.cond6
+  br label %S2
+
+S2:                                               ; preds = %for.body8
+  %tmp4 = load i32* %red, align 4
+  %add9 = add nsw i32 %tmp4, %i5.0
+  store i32 %add9, i32* %red, align 4
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %S2
+  %inc11 = add nsw i32 %i5.0, 1
+  br label %for.cond6
+
+for.end12:                                        ; preds = %for.cond6
+  br label %S3
+
+S3:                                               ; preds = %for.end12
+  %tmp5 = load i32* %red, align 4
+  %mul13 = mul nsw i32 %tmp5, 7
+  %add14 = add nsw i32 %mul13, 42
+  store i32 %add14, i32* %red, align 4
+  br label %for.inc15
+
+for.inc15:                                        ; preds = %S3
+  %inc16 = add nsw i32 %j.0, 1
+  br label %for.cond
+
+for.end17:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_only_reduction_like_access.ll b/rc1/test/Dependences/reduction_only_reduction_like_access.ll
new file mode 100644
index 0000000..c12949a
--- /dev/null
+++ b/rc1/test/Dependences/reduction_only_reduction_like_access.ll
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; FIXME: Change the comment once we allow different pointers
+; The statement is "almost" reduction like but should not yield any reduction dependences
+;
+; We are limited to binary reductions at the moment and this is not one.
+; There are never at least two iterations which read __and__ write to the same
+; location, thus we won't find the RAW and WAW dependences of a reduction,
+; thus we should not find Reduction dependences.
+;
+; CHECK:  Reduction dependences:
+; CHECK:    {  }
+;
+; void f(int *sum) {
+;   for (int i = 0; i < 100; i++)
+;     sum[i] = sum[99-i] + i;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %sub = sub nsw i32 99, %i.0
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %sub
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  %arrayidx1 = getelementptr inbounds i32* %sum, i32 %i.0
+  store i32 %add, i32* %arrayidx1, 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
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_partially_escaping_intermediate_in_other_stmt.ll b/rc1/test/Dependences/reduction_partially_escaping_intermediate_in_other_stmt.ll
new file mode 100644
index 0000000..c48d8f0
--- /dev/null
+++ b/rc1/test/Dependences/reduction_partially_escaping_intermediate_in_other_stmt.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly -polly-dependences -analyze -basicaa < %s | FileCheck %s
+;
+; CHECK: Reduction dependences:
+; CHECK:   [N] -> { Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0 and i1 >= 1024 - N + i0 }
+;
+; void f(int N, int * restrict sums, int * restrict escape) {
+;   for (int i = 0; i < 1024; i++) {
+;     for (int j = 0; j < 1024; j++) {
+;       sums[i] += 5;
+;       if (N - i + j < 1024)
+;         escape[N - i + j] = sums[i];
+;     }
+;   }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32 %N, i32* noalias %sums, i32* noalias %escape) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond1 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond1, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %sums, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 5
+  store i32 %add, i32* %arrayidx, align 4
+  %sub = sub nsw i32 %N, %i.0
+  %add4 = add nsw i32 %sub, %j.0
+  %cmp5 = icmp slt i32 %add4, 1024
+  br i1 %cmp5, label %if.then, label %if.end
+
+if.then:                                          ; preds = %for.body3
+  %arrayidx6 = getelementptr inbounds i32* %sums, i32 %i.0
+  %tmp2 = load i32* %arrayidx6, align 4
+  %sub7 = sub nsw i32 %N, %i.0
+  %add8 = add nsw i32 %sub7, %j.0
+  %arrayidx9 = getelementptr inbounds i32* %escape, i32 %add8
+  store i32 %tmp2, i32* %arrayidx9, align 4
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %for.body3
+  br label %for.inc
+
+for.inc:                                          ; preds = %if.end
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_privatization_deps.ll b/rc1/test/Dependences/reduction_privatization_deps.ll
new file mode 100644
index 0000000..a4f0895
--- /dev/null
+++ b/rc1/test/Dependences/reduction_privatization_deps.ll
@@ -0,0 +1,114 @@
+; RUN: opt %loadPolly -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK:      RAW dependences:
+; CHECK-DAG:    Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and o0 >= 0 and o0 <= i0
+; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S2[-1 + i0 + i1] : i0 >= 0 and i1 >= 1 and i0 <= 1022 and i1 <= 1024 - i0 and i1 <= 1023
+; CHECK-DAG:    Stmt_S1[1023, i1] -> Stmt_S2[1022 + i1] : i1 <= 1 and i1 >= 0
+; CHECK-DAG:    Stmt_S1[i0, 0] -> Stmt_S2[-1 + i0] : i0 <= 1022 and i0 >= 1
+; CHECK:      WAR dependences:
+; CHECK-DAG:    Stmt_S2[i0] -> Stmt_S2[1 + i0] : i0 <= 1022 and i0 >= 0
+; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i0 >= 0 and i1 <= 1023 - i0 and i1 >= 1
+; CHECK-DAG:    Stmt_S1[i0, 0] -> Stmt_S2[i0] : i0 <= 1023 and i0 >= 1
+; CHECK:      WAW dependences:
+; CHECK-DAG:    Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and o0 >= 0 and o0 <= i0
+; CHECK-DAG:    Stmt_S1[0, 0] -> Stmt_S2[0]
+; CHECK:      Reduction dependences:
+; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S1[1 + i0, -1 + i1] : i0 <= 1022 and i0 >= 0 and i1 <= 1023 and i1 >= 1
+;
+;    void f(int *sum) {
+;      for (int i = 0; i < 1024; i++)
+; S0:    sum[i] = 0;
+;      for (int i = 0; i < 1024; i++)
+;        for (int j = 0; j < 1024; j++)
+; S1:      sum[i + j] += i;
+;      for (int i = 0; i < 1024; i++)
+; S2:    sum[i] = sum[i + 1] * 3;
+;    }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond3 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond3, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  br label %S0
+
+S0:                                               ; preds = %for.body
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %i.0
+  store i32 0, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S0
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  br label %for.cond2
+
+for.cond2:                                        ; preds = %for.inc13, %for.end
+  %i1.0 = phi i32 [ 0, %for.end ], [ %inc14, %for.inc13 ]
+  %exitcond2 = icmp ne i32 %i1.0, 1024
+  br i1 %exitcond2, label %for.body4, label %for.end15
+
+for.body4:                                        ; preds = %for.cond2
+  br label %for.cond5
+
+for.cond5:                                        ; preds = %for.inc10, %for.body4
+  %j.0 = phi i32 [ 0, %for.body4 ], [ %inc11, %for.inc10 ]
+  %exitcond1 = icmp ne i32 %j.0, 1024
+  br i1 %exitcond1, label %for.body7, label %for.end12
+
+for.body7:                                        ; preds = %for.cond5
+  br label %S1
+
+S1:                                               ; preds = %for.body7
+  %add = add nsw i32 %i1.0, %j.0
+  %arrayidx8 = getelementptr inbounds i32* %sum, i32 %add
+  %tmp = load i32* %arrayidx8, align 4
+  %add9 = add nsw i32 %tmp, %i1.0
+  store i32 %add9, i32* %arrayidx8, align 4
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %S1
+  %inc11 = add nsw i32 %j.0, 1
+  br label %for.cond5
+
+for.end12:                                        ; preds = %for.cond5
+  br label %for.inc13
+
+for.inc13:                                        ; preds = %for.end12
+  %inc14 = add nsw i32 %i1.0, 1
+  br label %for.cond2
+
+for.end15:                                        ; preds = %for.cond2
+  br label %for.cond17
+
+for.cond17:                                       ; preds = %for.inc23, %for.end15
+  %i16.0 = phi i32 [ 0, %for.end15 ], [ %inc24, %for.inc23 ]
+  %exitcond = icmp ne i32 %i16.0, 1024
+  br i1 %exitcond, label %for.body19, label %for.end25
+
+for.body19:                                       ; preds = %for.cond17
+  br label %S2
+
+S2:                                               ; preds = %for.body19
+  %add20 = add nsw i32 %i16.0, 1
+  %arrayidx21 = getelementptr inbounds i32* %sum, i32 %add20
+  %tmp4 = load i32* %arrayidx21, align 4
+  %mul = mul nsw i32 %tmp4, 3
+  %arrayidx22 = getelementptr inbounds i32* %sum, i32 %i16.0
+  store i32 %mul, i32* %arrayidx22, align 4
+  br label %for.inc23
+
+for.inc23:                                        ; preds = %S2
+  %inc24 = add nsw i32 %i16.0, 1
+  br label %for.cond17
+
+for.end25:                                        ; preds = %for.cond17
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_privatization_deps_2.ll b/rc1/test/Dependences/reduction_privatization_deps_2.ll
new file mode 100644
index 0000000..979b0ea
--- /dev/null
+++ b/rc1/test/Dependences/reduction_privatization_deps_2.ll
@@ -0,0 +1,86 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; We have privatization dependences from a textually later statement to a
+; textually earlier one, but the dependences still go forward in time.
+;
+;  CHECK: RAW dependences:
+;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[1 + i0, o1] : i0 <= 97 and i0 >= 0 and o1 <= 99 and o1 >= 0
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+;  CHECK: WAR dependences:
+;  CHECK:   {  }
+;  CHECK: WAW dependences:
+;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[1 + i0, o1] : i0 <= 97 and i0 >= 0 and o1 <= 99 and o1 >= 0
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+;  CHECK: Reduction dependences:
+;  CHECK:   { Stmt_S2[i0, i1] -> Stmt_S2[i0, 1 + i1] : i0 <= 98 and i0 >= 0 and i1 <= 98 and i1 >= 0 }
+;
+;    void f(int *sum) {
+;      int i, j;
+;      for (i = 0; i < 99; i++) {
+; S1:    sum[i + 1] += 42;
+;        for (j = 0; j < 100; j++)
+; S2:      sum[i] += i * j;
+; S3:    sum[i + 1] += 7;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond1 = icmp ne i32 %i.0, 99
+  br i1 %exitcond1, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %S1
+
+S1:                                               ; preds = %for.body
+  %add = add nsw i32 %i.0, 1
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %add
+  %tmp = load i32* %arrayidx, align 4
+  %add1 = add nsw i32 %tmp, 42
+  store i32 %add1, i32* %arrayidx, align 4
+  br label %for.cond2
+
+for.cond2:                                        ; preds = %for.inc, %S1
+  %j.0 = phi i32 [ 0, %S1 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 100
+  br i1 %exitcond, label %for.body4, label %for.end
+
+for.body4:                                        ; preds = %for.cond2
+  br label %S2
+
+S2:                                               ; preds = %for.body4
+  %mul = mul nsw i32 %i.0, %j.0
+  %arrayidx5 = getelementptr inbounds i32* %sum, i32 %i.0
+  %tmp2 = load i32* %arrayidx5, align 4
+  %add6 = add nsw i32 %tmp2, %mul
+  store i32 %add6, i32* %arrayidx5, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S2
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond2
+
+for.end:                                          ; preds = %for.cond2
+  br label %S3
+
+S3:                                               ; preds = %for.end
+  %add7 = add nsw i32 %i.0, 1
+  %arrayidx8 = getelementptr inbounds i32* %sum, i32 %add7
+  %tmp3 = load i32* %arrayidx8, align 4
+  %add9 = add nsw i32 %tmp3, 7
+  store i32 %add9, i32* %arrayidx8, align 4
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %S3
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_privatization_deps_3.ll b/rc1/test/Dependences/reduction_privatization_deps_3.ll
new file mode 100644
index 0000000..83449be
--- /dev/null
+++ b/rc1/test/Dependences/reduction_privatization_deps_3.ll
@@ -0,0 +1,89 @@
+; RUN: opt %loadPolly -polly-dependences -polly-codegen-scev -analyze < %s | FileCheck %s
+;
+;  CHECK: RAW dependences:
+;  CHECK-DAG:  Stmt_S2[0, 0] -> Stmt_S3[1]
+;  CHECK-DAG:  Stmt_S2[i0, 1 - i0] -> Stmt_S3[i0] : i0 <= 1 and i0 >= 0
+;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 >= 0 and i0 <= 96
+;  CHECK: WAR dependences:
+;  CHECK:   {  }
+;  CHECK: WAW dependences:
+;  CHECK-DAG:  Stmt_S2[0, 0] -> Stmt_S3[1]
+;  CHECK-DAG:  Stmt_S2[i0, 1 - i0] -> Stmt_S3[i0] : i0 <= 1 and i0 >= 0
+;  CHECK-DAG:  Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+;  CHECK-DAG:  Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 >= 0 and i0 <= 96
+;  CHECK: Reduction dependences:
+;  CHECK-DAG:  Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : i0 <= 97 and i0 >= 0 and i1 <= 98 - i0 and i1 >= 0 and i1 >= 2 - i0
+;  CHECK-DAG:  Stmt_S2[0, 0] -> Stmt_S2[1, 0]
+;
+;    void f(int *sum) {
+;      int i, j;
+;      for (i = 0; i < 99; i++) {
+; S1:    sum[i + 1] += 42;
+;        for (j = i; j < 100; j++)
+; S2:      sum[i - j] += i * j;
+; S3:    sum[i - 1] += 7;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond1 = icmp ne i32 %i.0, 99
+  br i1 %exitcond1, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %S1
+
+S1:                                               ; preds = %for.body
+  %add = add nsw i32 %i.0, 1
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %add
+  %tmp = load i32* %arrayidx, align 4
+  %add1 = add nsw i32 %tmp, 42
+  store i32 %add1, i32* %arrayidx, align 4
+  br label %for.cond2
+
+for.cond2:                                        ; preds = %for.inc, %S1
+  %j.0 = phi i32 [ %i.0, %S1 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 100
+  br i1 %exitcond, label %for.body4, label %for.end
+
+for.body4:                                        ; preds = %for.cond2
+  br label %S2
+
+S2:                                               ; preds = %for.body4
+  %mul = mul nsw i32 %i.0, %j.0
+  %sub = sub nsw i32 %i.0, %j.0
+  %arrayidx5 = getelementptr inbounds i32* %sum, i32 %sub
+  %tmp2 = load i32* %arrayidx5, align 4
+  %add6 = add nsw i32 %tmp2, %mul
+  store i32 %add6, i32* %arrayidx5, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S2
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond2
+
+for.end:                                          ; preds = %for.cond2
+  br label %S3
+
+S3:                                               ; preds = %for.end
+  %sub7 = add nsw i32 %i.0, -1
+  %arrayidx8 = getelementptr inbounds i32* %sum, i32 %sub7
+  %tmp3 = load i32* %arrayidx8, align 4
+  %add9 = add nsw i32 %tmp3, 7
+  store i32 %add9, i32* %arrayidx8, align 4
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %S3
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_privatization_deps_4.ll b/rc1/test/Dependences/reduction_privatization_deps_4.ll
new file mode 100644
index 0000000..5f44815
--- /dev/null
+++ b/rc1/test/Dependences/reduction_privatization_deps_4.ll
@@ -0,0 +1,84 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK:     RAW dependences:
+; CHECK-DAG:   Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= 98
+; CHECK-DAG:   Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+; CHECK:     WAR dependences:
+; CHECK-DAG:    {  }
+; CHECK:     WAW dependences:
+; CHECK-DAG:   Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= 98
+; CHECK-DAG:   Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 98
+; CHECK-DAG:   Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+; CHECK:     Reduction dependences:
+; CHECK-DAG:    { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : (i0 <= 97 and i1 >= 0 and i1 <= -1 + i0) or (i0 >= 0 and i1 >= 2 + i0 and i1 <= 99) }
+;
+;    void f(int *sum) {
+;      for (int i = 0; i < 99; i++) {
+; S1:    sum[i] += 42;
+;        for (int j = 0; j < 100; j++)
+; S2:      sum[j] += i * j;
+; S3:    sum[i] += 7;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc8, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc9, %for.inc8 ]
+  %exitcond1 = icmp ne i32 %i.0, 99
+  br i1 %exitcond1, label %for.body, label %for.end10
+
+for.body:                                         ; preds = %for.cond
+  br label %S1
+
+S1:                                               ; preds = %for.body
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 42
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %S1
+  %j.0 = phi i32 [ 0, %S1 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 100
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  br label %S2
+
+S2:                                               ; preds = %for.body3
+  %mul = mul nsw i32 %i.0, %j.0
+  %arrayidx4 = getelementptr inbounds i32* %sum, i32 %j.0
+  %tmp2 = load i32* %arrayidx4, align 4
+  %add5 = add nsw i32 %tmp2, %mul
+  store i32 %add5, i32* %arrayidx4, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S2
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %S3
+
+S3:                                               ; preds = %for.end
+  %arrayidx6 = getelementptr inbounds i32* %sum, i32 %i.0
+  %tmp3 = load i32* %arrayidx6, align 4
+  %add7 = add nsw i32 %tmp3, 7
+  store i32 %add7, i32* %arrayidx6, align 4
+  br label %for.inc8
+
+for.inc8:                                         ; preds = %S3
+  %inc9 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end10:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_privatization_deps_5.ll b/rc1/test/Dependences/reduction_privatization_deps_5.ll
new file mode 100644
index 0000000..b6b4dbd
--- /dev/null
+++ b/rc1/test/Dependences/reduction_privatization_deps_5.ll
@@ -0,0 +1,88 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK:     RAW dependences:
+; CHECK-DAG:   Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 >= 0 and i0 <= 97
+; CHECK-DAG:   Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 >= 0 and i0 <= 98
+; CHECK:     WAR dependences:
+; CHECK-DAG:   {  }
+; CHECK:     WAW dependences:
+; CHECK-DAG:   Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 >= 0 and i0 <= 97
+; CHECK-DAG:   Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 >= 0 and i0 <= 98
+; CHECK:     Reduction dependences:
+; CHECK-DAG:   { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : i0 <= 97 and i0 >= 0 and i1 <= 99 and i1 >= 1 }
+;
+;    void f(int *sum) {
+;      for (int i = 0; i < 99; i++) {
+;        for (int j = 0; j < 1; j++)
+; S1:      sum[j] += 42;
+;        for (int j = 0; j < 100; j++)
+; S2:      sum[j] += i * j;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc12, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc13, %for.inc12 ]
+  %exitcond2 = icmp ne i32 %i.0, 99
+  br i1 %exitcond2, label %for.body, label %for.end14
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  br label %S1
+
+S1:                                               ; preds = %for.body3
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %j.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 42
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S1
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc9, %for.end
+  %j.1 = phi i32 [ 0, %for.end ], [ %inc10, %for.inc9 ]
+  %exitcond1 = icmp ne i32 %j.1, 100
+  br i1 %exitcond1, label %for.body6, label %for.end11
+
+for.body6:                                        ; preds = %for.cond4
+  br label %S2
+
+S2:                                               ; preds = %for.body6
+  %mul = mul nsw i32 %i.0, %j.1
+  %arrayidx7 = getelementptr inbounds i32* %sum, i32 %j.1
+  %tmp3 = load i32* %arrayidx7, align 4
+  %add8 = add nsw i32 %tmp3, %mul
+  store i32 %add8, i32* %arrayidx7, align 4
+  br label %for.inc9
+
+for.inc9:                                         ; preds = %S2
+  %inc10 = add nsw i32 %j.1, 1
+  br label %for.cond4
+
+for.end11:                                        ; preds = %for.cond4
+  br label %for.inc12
+
+for.inc12:                                        ; preds = %for.end11
+  %inc13 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end14:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_simple_iv.ll b/rc1/test/Dependences/reduction_simple_iv.ll
new file mode 100644
index 0000000..1dd9d51
--- /dev/null
+++ b/rc1/test/Dependences/reduction_simple_iv.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK:  RAW dependences:
+; CHECK:    {  }
+; CHECK:  WAR dependences:
+; CHECK:    {  }
+; CHECK:  WAW dependences:
+; CHECK:    {  }
+; CHECK:  Reduction dependences:
+; CHECK:    { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 <= 99 and i0 >= 0 }
+;
+; void f(int* sum) {
+;   for (int i = 0; i <= 100; i++)
+;     sum += i * 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %entry.split1
+
+entry.split1:                                     ; preds = %entry
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry.split1
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.cond, %entry.split
+  %i1.0 = phi i32 [ 0, %entry.split ], [ %inc, %for.cond ]
+  %sum.reload = load i32* %sum
+  %mul = mul nsw i32 %i1.0, 3
+  %add = add nsw i32 %sum.reload, %mul
+  %inc = add nsw i32 %i1.0, 1
+  store i32 %add, i32* %sum
+  %cmp = icmp slt i32 %i1.0, 100
+  br i1 %cmp, label %for.cond, label %for.end
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll b/rc1/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll
new file mode 100644
index 0000000..2982f9e
--- /dev/null
+++ b/rc1/test/Dependences/reduction_simple_iv_debug_wrapped_dependences.ll
@@ -0,0 +1,81 @@
+; RUN: opt %loadPolly -polly-dependences -analyze -debug-only=polly-dependence 2>&1 < %s | FileCheck %s
+;
+; REQUIRES: asserts
+;
+; CHECK: Read: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> MemRef_sum[0] : i0 >= 0 and i0 <= 100 }
+; CHECK: Write: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> MemRef_sum[0] : i0 >= 0 and i0 <= 100 }
+; CHECK: Schedule: { Stmt_for_cond[i0] -> scattering[0, i0, 0]; [Stmt_for_cond[i0] -> MemRef_sum[0]] -> scattering[0, i0, 0] : i0 <= 100 and i0 >= 0 }
+; CHECK: Wrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK:   { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 >= 0 and i0 <= 99 }
+; CHECK: Reduction dependences:
+; CHECK:   n/a
+; CHECK: Final Wrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK:   { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
+; CHECK: Zipped Dependences:
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK:   { [Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0]] -> [MemRef_sum[0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
+; CHECK: Unwrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK:   { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 <= 99 and i0 >= 0 }
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK:   { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 <= 99 and i0 >= 0 }
+;
+; void f(int* sum) {
+;   for (int i = 0; i <= 100; i++)
+;     sum += i * 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %entry.split1
+
+entry.split1:                                     ; preds = %entry
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry.split1
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.cond, %entry.split
+  %i1.0 = phi i32 [ 0, %entry.split ], [ %inc, %for.cond ]
+  %sum.reload = load i32* %sum
+  %mul = mul nsw i32 %i1.0, 3
+  %add = add nsw i32 %sum.reload, %mul
+  %inc = add nsw i32 %i1.0, 1
+  store i32 %add, i32* %sum
+  %cmp = icmp slt i32 %i1.0, 100
+  br i1 %cmp, label %for.cond, label %for.end
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_simple_privatization_deps_2.ll b/rc1/test/Dependences/reduction_simple_privatization_deps_2.ll
new file mode 100644
index 0000000..46b32c0
--- /dev/null
+++ b/rc1/test/Dependences/reduction_simple_privatization_deps_2.ll
@@ -0,0 +1,79 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK:      RAW dependences:
+; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S2[i0] : i0 <= 99 and i0 >= 0 and i1 <= 99 and i1 >= 0
+; CHECK-DAG:    Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 99 and i0 >= 0 and o1 <= 99 and o1 >= 0
+; CHECK-DAG:    Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 98
+; CHECK:      WAR dependences:
+; CHECK-DAG:     {  }
+; CHECK:      WAW dependences:
+; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S2[i0] : i0 <= 99 and i0 >= 0 and i1 <= 99 and i1 >= 0
+; CHECK-DAG:    Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 99 and i0 >= 0 and o1 <= 99 and o1 >= 0
+; CHECK-DAG:    Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 >= 0 and i0 <= 98
+; CHECK:      Reduction dependences:
+; CHECK-DAG:    Stmt_S1[i0, i1] -> Stmt_S1[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0
+;
+;    void f(int *sum) {
+;      for (int i = 0; i < 100; i++) {
+; S0:    *sum *= 42;
+;        for (int j = 0; j < 100; j++)
+; S1:      *sum += i * j;
+; S2:    *sum *= 7;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+  %exitcond1 = icmp ne i32 %i.0, 100
+  br i1 %exitcond1, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  br label %S0
+
+S0:                                               ; preds = %for.body
+  %tmp = load i32* %sum, align 4
+  %mul = mul nsw i32 %tmp, 42
+  store i32 %mul, i32* %sum, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %S0
+  %j.0 = phi i32 [ 0, %S0 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 100
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  br label %S1
+
+S1:                                               ; preds = %for.body3
+  %mul4 = mul nsw i32 %i.0, %j.0
+  %tmp2 = load i32* %sum, align 4
+  %add = add nsw i32 %tmp2, %mul4
+  store i32 %add, i32* %sum, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S1
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %S2
+
+S2:                                               ; preds = %for.end
+  %tmp3 = load i32* %sum, align 4
+  %mul5 = mul nsw i32 %tmp3, 7
+  store i32 %mul5, i32* %sum, align 4
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %S2
+  %inc7 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_simple_privatization_deps_w_parameter.ll b/rc1/test/Dependences/reduction_simple_privatization_deps_w_parameter.ll
new file mode 100644
index 0000000..f223619
--- /dev/null
+++ b/rc1/test/Dependences/reduction_simple_privatization_deps_w_parameter.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK:      RAW dependences:
+; CHECK-DAG:    Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and o0 <= 1023 and o0 >= 0
+; CHECK-DAG:    Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and i0 <= 1023 and i0 >= 0
+; CHECK:      WAR dependences:
+; CHECK:       [N] -> {  }
+; CHECK:      WAW dependences:
+; CHECK-DAG:    Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and o0 <= 1023 and o0 >= 0
+; CHECK-DAG:    Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and i0 <= 1023 and i0 >= 0
+; CHECK:   Reduction dependences:
+; CHECK:        Stmt_S1[i0] -> Stmt_S1[1 + i0] : N >= 11 and i0 <= 1022 and i0 >= 0
+;
+;    void f(int *sum, int N) {
+;      if (N >= 10) {
+; S0:    *sum = 0;
+;        for (int i = 0; i < 1024; i++)
+; S1:      *sum += i;
+; S2:    *sum = *sum * 3;
+;      }
+;    }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum, i32 %N) {
+entry:
+  br label %entry.1
+
+entry.1:
+  %excond = icmp sgt i32 %N, 10
+  br i1 %excond, label %S0, label %f.end
+
+S0:
+  store i32 0, i32* %sum, align 4
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %S0
+  %i.0 = phi i32 [ 0, %S0 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %S1, label %S2
+
+S1:                                               ; preds = %for.cond
+  %tmp = load i32* %sum, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %sum, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S1
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+S2:                                               ; preds = %for.cond
+  %tmp1 = load i32* %sum, align 4
+  %mul = mul nsw i32 %tmp1, 3
+  store i32 %mul, i32* %sum, align 4
+  br label %f.end
+
+f.end:
+  ret void
+}
diff --git a/rc1/test/Dependences/reduction_two_reductions_different_rloops.ll b/rc1/test/Dependences/reduction_two_reductions_different_rloops.ll
new file mode 100644
index 0000000..4470e4e
--- /dev/null
+++ b/rc1/test/Dependences/reduction_two_reductions_different_rloops.ll
@@ -0,0 +1,73 @@
+; RUN: opt %loadPolly -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK:   {  }
+; CHECK: WAR dependences:
+; CHECK:   {  }
+; CHECK: WAW dependences:
+; CHECK:   {  }
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[1 + i0, i1] : i0 <= 1022 and i0 >= 0 and i1 <= 1023 and i1 >= 0
+;
+; void f(int *restrict A, int *restrict B, int *restrict Values) {
+;   for (int i = 0; i < 1024; i++) {
+;     for (int j = 0; j < 1024; j++) {
+;       A[i] += Values[i + j - 1];
+;       B[j] += Values[i + j + 42];
+;     }
+;   }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %A, i32* noalias %B, i32* noalias %Values)  {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc11, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc12, %for.inc11 ]
+  %exitcond1 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond1, label %for.body, label %for.end13
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %add = add nsw i32 %i.0, %j.0
+  %sub = add nsw i32 %add, -1
+  %arrayidx = getelementptr inbounds i32* %Values, i32 %sub
+  %tmp = load i32* %arrayidx, align 4
+  %arrayidx4 = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp2 = load i32* %arrayidx4, align 4
+  %add5 = add nsw i32 %tmp2, %tmp
+  store i32 %add5, i32* %arrayidx4, align 4
+  %add6 = add nsw i32 %i.0, %j.0
+  %add7 = add nsw i32 %add6, 42
+  %arrayidx8 = getelementptr inbounds i32* %Values, i32 %add7
+  %tmp3 = load i32* %arrayidx8, align 4
+  %arrayidx9 = getelementptr inbounds i32* %B, i32 %j.0
+  %tmp4 = load i32* %arrayidx9, align 4
+  %add10 = add nsw i32 %tmp4, %tmp3
+  store i32 %add10, i32* %arrayidx9, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc11
+
+for.inc11:                                        ; preds = %for.end
+  %inc12 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end13:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Dependences/sequential_loops.ll b/rc1/test/Dependences/sequential_loops.ll
new file mode 100644
index 0000000..c6ef964
--- /dev/null
+++ b/rc1/test/Dependences/sequential_loops.ll
@@ -0,0 +1,296 @@
+; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=value-based < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt -S %loadPolly -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=memory-based < %s | FileCheck %s -check-prefix=MEMORY
+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"
+
+;     for(i = 0; i < 100; i++ )
+; S1:   A[i] = 2;
+;
+;     for (i = 0; i < 10; i++ )
+; S2:   A[i]  = 5;
+;
+;     for (i = 0; i < 200; i++ )
+; S3:   A[i] = 5;
+
+define void @sequential_writes() {
+entry:
+  %A = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  br label %S3
+
+S3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  store i32 7, i32* %arrayidx.3
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'sequential_writes':
+; VALUE:   RAW dependences:
+; VALUE:     {  }
+; VALUE:   WAR dependences:
+; VALUE:     {  }
+; VALUE:   WAW dependences:
+; VALUE:     {
+; VALUE:       Stmt_S1[i0] -> Stmt_S2[i0] : i0 >= 0 and i0 <= 9;
+; VALUE:       Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9;
+; VALUE:       Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 10 and i0 <= 99
+; VALUE:     }
+
+; MEMORY: region: 'S1 => exit.3' in function 'sequential_writes':
+; MEMORY:   RAW dependences:
+; MEMORY:     {  }
+; MEMORY:   WAR dependences:
+; MEMORY:     {  }
+; MEMORY:   WAW dependences:
+; MEMORY:     {
+; MEMORY:       Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY:       Stmt_S2[i0] -> Stmt_S3[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY:       Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 0
+; MEMORY:     }
+
+;     for(i = 0; i < 100; i++ )
+; S1:   A[i] = 2;
+;
+;     for (i = 0; i < 10; i++ )
+; S2:   A[i]  = 5;
+;
+;     for (i = 0; i < 200; i++ )
+; S3:   B[i] = A[i];
+
+define void @read_after_writes() {
+entry:
+  %A = alloca [200 x i32]
+  %B = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  br label %S3
+
+S3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+  %arrayidx.3.a = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  %arrayidx.3.b = getelementptr [200 x i32]* %B, i64 0, i64 %indvar.3
+  %val = load i32* %arrayidx.3.a
+  store i32 %val, i32* %arrayidx.3.b
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'read_after_writes':
+; VALUE:   RAW dependences:
+; VALUE:     {
+; VALUE:       Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9;
+; VALUE:       Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 10 and i0 <= 99
+; VALUE:     }
+; VALUE:   WAR dependences:
+; VALUE:     {  }
+; VALUE:   WAW dependences:
+; VALUE:     {
+; VALUE:       Stmt_S1[i0] -> Stmt_S2[i0] : i0 >= 0 and i0 <= 9
+; VALUE:     }
+
+; MEMORY: region: 'S1 => exit.3' in function 'read_after_writes':
+; MEMORY:   RAW dependences:
+; MEMORY:     {
+; MEMORY:       Stmt_S2[i0] -> Stmt_S3[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY:       Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 0
+; MEMORY:     }
+; MEMORY:   WAR dependences:
+; MEMORY:     {  }
+; MEMORY:   WAW dependences:
+; MEMORY:     {
+; MEMORY:       Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0
+; MEMORY:     }
+
+;     for(i = 0; i < 100; i++ )
+; S1:   B[i] = A[i];
+;
+;     for (i = 0; i < 10; i++ )
+; S2:   A[i]  = 5;
+;
+;     for (i = 0; i < 200; i++ )
+; S3:   A[i]  = 10;
+
+define void @write_after_read() {
+entry:
+  %A = alloca [200 x i32]
+  %B = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1.a = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  %arrayidx.1.b = getelementptr [200 x i32]* %B, i64 0, i64 %indvar.1
+  %val = load i32* %arrayidx.1.a
+  store i32 %val, i32* %arrayidx.1.b
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  br label %S3
+
+S3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  store i32 10, i32* %arrayidx.3
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'write_after_read':
+; VALUE:   RAW dependences:
+; VALUE:     {
+; VALUE:     }
+; VALUE:   WAR dependences:
+; VALUE:     {
+; VALUE:       Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0;
+; VALUE:       Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 10
+; VALUE:     }
+; VALUE:   WAW dependences:
+; VALUE:     {
+; VALUE:       Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9
+; VALUE:     }
+
+; MEMORY: region: 'S1 => exit.3' in function 'write_after_read':
+; MEMORY:   RAW dependences:
+; MEMORY:     {
+; MEMORY:     }
+; MEMORY:   WAR dependences:
+; MEMORY:     {
+; MEMORY:        Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY:        Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 0
+; MEMORY:     }
+; MEMORY:   WAW dependences:
+; MEMORY:     {
+; MEMORY:        Stmt_S2[i0] -> Stmt_S3[i0] : i0 <= 9 and i0 >= 0
+; MEMORY:     }
+
+;     for(i = 0; i < 100; i++ )
+; S1:   A[i] = 10
+;
+;     for(i = 0; i < 100; i++ )
+; S2:   B[i] = A[i + p];
+
+define void @parametric_offset(i64 %p) {
+entry:
+  %A = alloca [200 x i32]
+  %B = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 10, i32* %arrayidx.1
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %sum = add i64 %indvar.2, %p
+  %arrayidx.2.a = getelementptr [200 x i32]* %A, i64 0, i64 %sum
+  %arrayidx.2.b = getelementptr [200 x i32]* %B, i64 0, i64 %indvar.2
+  %val = load i32* %arrayidx.2.a
+  store i32 %val, i32* %arrayidx.2.b
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  ret void
+}
+
+; VALUE: region: 'S1 => exit.2' in function 'parametric_offset':
+; VALUE:   RAW dependences:
+; VALUE:     [p] -> {
+; VALUE:       Stmt_S1[i0] -> Stmt_S2[-p + i0] :
+; VALUE:           i0 >= p and i0 <= 9 + p and i0 >= 0 and i0 <= 99
+; VALUE:     }
+; VALUE:   WAR dependences:
+; VALUE:     [p] -> {
+; VALUE:     }
+; VALUE:   WAW dependences:
+; VALUE:     [p] -> {
+; VALUE:     }
+
+; MEMORY: region: 'S1 => exit.2' in function 'parametric_offset':
+; MEMORY:   RAW dependences:
+; MEMORY:     [p] -> {
+; MEMORY:       Stmt_S1[i0] -> Stmt_S2[-p + i0] :
+; MEMORY:           i0 >= p and i0 <= 99 and i0 >= 0 and i0 <= 9 + p
+; MEMORY:     }
+; MEMORY:   WAR dependences:
+; MEMORY:     [p] -> {
+; MEMORY:     }
+; MEMORY:   WAW dependences:
+; MEMORY:     [p] -> {
+; MEMORY:     }
diff --git a/rc1/test/IndependentBlocks/inter_bb_scalar_dep.ll b/rc1/test/IndependentBlocks/inter_bb_scalar_dep.ll
new file mode 100644
index 0000000..5a6014d
--- /dev/null
+++ b/rc1/test/IndependentBlocks/inter_bb_scalar_dep.ll
@@ -0,0 +1,58 @@
+; RUN: opt %loadPolly -basicaa -polly-independent -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -polly-codegen-scev -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -disable-polly-intra-scop-scalar-to-array -S < %s | FileCheck %s -check-prefix=SCALARACCESS
+; RUN: opt %loadPolly -basicaa -polly-independent -polly-codegen-scev -disable-polly-intra-scop-scalar-to-array -S < %s | FileCheck %s -check-prefix=SCALARACCESS
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     init = *init_ptr;
+;     for (i = 0; i < N; ++i) {
+;       A[i] = init + 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* noalias %A, i64 %N, i64* noalias %init_ptr) nounwind {
+entry:
+
+; CHECK: entry
+; CHECK: %init.s2a = alloca i64
+; CHECK: br label %for.i
+
+; SCALARACCESS-NOT: alloca
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:
+  %init = load i64* %init_ptr
+; SCALARACCESS-NOT: store
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %init_plus_two = add i64 %init, 2
+; CHECK: %init.loadarray = load i64* %init.s2a
+; CHECK: %init_plus_two = add i64 %init.loadarray, 2
+; SCALARACCESS: %init_plus_two = add i64 %init, 2
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_plus_two, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:
+  ret void
+}
diff --git a/rc1/test/IndependentBlocks/intra_and_inter_bb_scalar_dep.ll b/rc1/test/IndependentBlocks/intra_and_inter_bb_scalar_dep.ll
new file mode 100644
index 0000000..bd512f5
--- /dev/null
+++ b/rc1/test/IndependentBlocks/intra_and_inter_bb_scalar_dep.ll
@@ -0,0 +1,67 @@
+; RUN: opt %loadPolly -basicaa -polly-independent -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -polly-codegen-scev -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -disable-polly-intra-scop-scalar-to-array -S < %s | FileCheck %s -check-prefix=SCALARACCESS
+; RUN: opt %loadPolly -basicaa -polly-independent -disable-polly-intra-scop-scalar-to-array -polly-codegen-scev -S < %s | FileCheck %s -check-prefix=SCALARACCESS
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     init = *init_ptr;
+;     for (i = 0; i < N; ++i) {
+;       init2 = *init_ptr;
+;       A[i] = init + init2;
+;     }
+;   }
+; }
+
+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* noalias %A, i64 %N, i64* noalias %init_ptr) nounwind {
+entry:
+
+; CHECK: entry
+; CHECK: %init.s2a = alloca i64
+; CHECK: br label %for.i
+
+; SCALARACCESS-NOT: alloca
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:
+  %init = load i64* %init_ptr
+; SCALARACCESS-NOT: store
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %init_2 = load i64* %init_ptr
+  %init_sum = add i64 %init, %init_2
+; CHECK: %init_2 = load i64* %init_ptr
+; CHECK: %init.loadarray = load i64* %init.s2a
+; CHECK: %init_sum = add i64 %init.loadarray, %init_2
+
+; The SCEV of %init_sum is (%init + %init_2). It is referring to both an
+; UnknownValue in the same and in a different basic block. We want only the
+; reference to the different basic block to be replaced.
+
+; SCALARACCESS: %init_2 = load i64* %init_ptr
+; SCALARACCESS: %init_sum = add i64 %init, %init_2
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_sum, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:
+  ret void
+}
diff --git a/rc1/test/IndependentBlocks/intra_bb_scalar_dep.ll b/rc1/test/IndependentBlocks/intra_bb_scalar_dep.ll
new file mode 100644
index 0000000..8e3fff1
--- /dev/null
+++ b/rc1/test/IndependentBlocks/intra_bb_scalar_dep.ll
@@ -0,0 +1,54 @@
+; RUN: opt %loadPolly -basicaa -polly-independent -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -polly-codegen-scev -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -disable-polly-intra-scop-scalar-to-array -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -disable-polly-intra-scop-scalar-to-array -polly-codegen-scev -S < %s | FileCheck %s
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     for (i = 0; i < N; ++i) {
+;       init = *init_ptr;
+;       A[i] = init + 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* noalias %A, i64 %N, i64* noalias %init_ptr) nounwind {
+entry:
+
+; CHECK: entry
+; CHECK: br label %for.i
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %init = load i64* %init_ptr
+  %init_plus_two = add i64 %init, 2
+; The scalar evolution of %init_plus_two is (2 + %init). So we have a
+; non-trivial scalar evolution referring to a value in the same basic block.
+; We want to ensure that this scalar is not translated into a memory copy.
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_plus_two, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:
+  ret void
+}
diff --git a/rc1/test/IndependentBlocks/phi_outside_scop.ll b/rc1/test/IndependentBlocks/phi_outside_scop.ll
new file mode 100644
index 0000000..2172fab
--- /dev/null
+++ b/rc1/test/IndependentBlocks/phi_outside_scop.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -basicaa -polly-independent -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -polly-codegen-scev -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-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @phi_nodes_outside() {
+entry:
+  br label %for.i.1
+
+for.i.1:
+  %i.1 = phi i32 [ %i.1.next, %for.i.1 ], [ 0, %entry ]
+  %i.1.next = add nsw i32 %i.1, 1
+  br i1 false, label %for.i.1 , label %for.i.2.preheader
+
+for.i.2.preheader:
+  br label %for.i.2
+
+for.i.2:
+; The value of %i.1.next is used outside of the scop in a PHI node.
+  %i.2 = phi i32 [ %i.2.next , %for.i.2 ], [ %i.1.next, %for.i.2.preheader ]
+  %i.2.next = add nsw i32 %i.2, 1
+  fence seq_cst
+  br i1 false, label %for.i.2, label %cleanup
+
+cleanup:
+  ret void
+}
+
+; CHECK:  store i32 %i.1.next, i32* %i.1.next.s2a
+
+; CHECK: for.i.2.preheader:
+; CHECK:    %i.1.next.loadoutside = load i32* %i.1.next.s2a
+
+; CHECK: for.i.2:
+; CHECK:    %i.2 = phi i32 [ %i.2.next, %for.i.2 ], [ %i.1.next.loadoutside, %for.i.2.preheader ]
+
diff --git a/rc1/test/IndependentBlocks/scalar_to_array.ll b/rc1/test/IndependentBlocks/scalar_to_array.ll
new file mode 100644
index 0000000..3018172
--- /dev/null
+++ b/rc1/test/IndependentBlocks/scalar_to_array.ll
@@ -0,0 +1,270 @@
+; RUN: opt %loadPolly -basicaa -polly-independent < %s -S | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -polly-codegen-scev < %s -S | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-independent -disable-polly-intra-scop-scalar-to-array -S < %s | FileCheck %s -check-prefix=SCALARACCESS
+; RUN: opt %loadPolly -basicaa -polly-independent -disable-polly-intra-scop-scalar-to-array -polly-codegen-scev < %s -S | FileCheck %s -check-prefix=SCALARACCESS
+
+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 8
+
+define i32 @empty() nounwind {
+entry:
+  fence seq_cst
+  br label %for.cond
+
+for.cond:
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body, label %return
+
+for.body:
+  br label %for.inc
+
+for.inc:
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:
+  fence seq_cst
+  ret i32 0
+}
+
+
+; CHECK: @array_access()
+define i32 @array_access() nounwind {
+entry:
+  fence seq_cst
+  br label %for.cond
+; CHECK: entry:
+; CHECK-NOT: alloca
+; SCALARACCESS: entry:
+; SCALARACCESS-NOT: alloca
+
+for.cond:
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body, label %return
+
+for.body:
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %float = uitofp i64 %indvar to float
+  store float %float, float* %arrayidx
+  br label %for.inc
+
+; CHECK: for.body:
+; CHECK: %float = uitofp i64 %indvar to float
+; CHECK: store float %float, float* %arrayidx
+; SCALARACCESS: for.body:
+; SCALARACCESS: %float = uitofp i64 %indvar to float
+; SCALARACCESS: store float %float, float* %arrayidx
+
+for.inc:
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:
+  fence seq_cst
+  ret i32 0
+}
+
+; CHECK: @intra_scop_dep()
+define i32 @intra_scop_dep() nounwind {
+entry:
+  fence seq_cst
+  br label %for.cond
+
+; CHECK: entry:
+; CHECK: %scalar.s2a = alloca float
+; CHECK: fence
+; SCALARACCESS: entry:
+; SCALARACCESS-NOT: alloca
+; SCALARACCESS: fence
+
+for.cond:
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body.a, label %return
+
+for.body.a:
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %scalar = load float* %arrayidx
+  br label %for.body.b
+
+; CHECK: for.body.a:
+; CHECK: %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+; CHECK: %scalar = load float* %arrayidx
+; CHECK: store float %scalar, float* %scalar.s2a
+; CHECK: br label %for.body.b
+
+; SCALARACCESS: for.body.a:
+; SCALARACCESS: %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+; SCALARACCESS: %scalar = load float* %arrayidx
+; SCALARACCESS-NOT: store
+; SCALARACCESS: br label %for.body.b
+
+for.body.b:
+  %arrayidx2 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %float = uitofp i64 %indvar to float
+  %sum = fadd float %scalar, %float
+  store float %sum, float* %arrayidx2
+  br label %for.inc
+
+; CHECK: for.body.b:
+; CHECK: %arrayidx2 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+; CHECK: %float = uitofp i64 %indvar to float
+; CHECK: %scalar.loadarray = load float* %scalar.s2a
+; CHECK: %sum = fadd float %scalar.loadarray, %float
+; CHECK: store float %sum, float* %arrayidx2
+; CHECK: br label %for.inc
+
+; SCALARACCESS: for.body.b:
+; SCALARACCESS: %arrayidx2 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+; SCALARACCESS: %float = uitofp i64 %indvar to float
+; SCALARACCESS-NOT: load
+; SCALARACCESS: %sum = fadd float %scalar, %float
+; SCALARACCESS: store float %sum, float* %arrayidx2
+; SCALARACCESS: br label %for.inc
+
+for.inc:
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:
+  fence seq_cst
+  ret i32 0
+}
+
+; It is not possible to have a scop which accesses a scalar element that is
+; a global variable. All global variables are pointers containing possibly
+; a single element. Hence they do not need to be handled anyways.
+; Please note that this is still required when scalar to array rewritting is
+; disabled.
+
+; CHECK: @use_after_scop()
+define i32 @use_after_scop() nounwind {
+entry:
+  fence seq_cst
+  br label %for.head
+; CHECK: entry:
+; CHECK: %scalar.s2a = alloca float
+; CHECK: fence
+
+; SCALARACCESS: entry:
+; SCALARACCESS: %scalar.s2a = alloca float
+; SCALARACCESS: fence
+
+for.head:
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  br label %for.body
+
+for.body:
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %scalar = load float* %arrayidx
+  br label %for.inc
+
+; CHECK: for.body:
+; CHECK: %scalar = load float* %arrayidx
+; CHECK: store float %scalar, float* %scalar.s2a
+
+; SCALARACCESS: for.body:
+; SCALARACCESS: %scalar = load float* %arrayidx
+; SCALARACCESS: store float %scalar, float* %scalar.s2a
+
+for.inc:
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.head, label %for.after
+
+for.after:
+  fence seq_cst
+  %return_value = fptosi float %scalar to i32
+  br label %return
+
+; CHECK: for.after:
+; CHECK: %scalar.loadoutside = load float* %scalar.s2a
+; CHECK: fence seq_cst
+; CHECK: %return_value = fptosi float %scalar.loadoutside to i32
+
+; SCALARACCESS: for.after:
+; SCALARACCESS: %scalar.loadoutside = load float* %scalar.s2a
+; SCALARACCESS: fence seq_cst
+; SCALARACCESS: %return_value = fptosi float %scalar.loadoutside to i32
+
+return:
+  ret i32 %return_value
+}
+
+; We currently do not transform scalar references, that have only read accesses
+; in the scop. There are two reasons for this:
+;
+;  o We don't introduce additional memory references which may yield to compile
+;    time overhead.
+;  o For integer values, such a translation may block the use of scalar
+;    evolution on those values.
+;
+; CHECK: @before_scop()
+define i32 @before_scop() nounwind {
+entry:
+  br label %preheader
+
+preheader:
+  %scalar = fadd float 4.0, 5.0
+  fence seq_cst
+  br label %for.cond
+
+for.cond:
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %preheader ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body, label %return
+
+for.body:
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  store float %scalar, float* %arrayidx
+  br label %for.inc
+
+; CHECK: for.body:
+; CHECK: store float %scalar, float* %arrayidx
+
+; SCALARACCESS: for.body:
+; SCALARACCESS: store float %scalar, float* %arrayidx
+
+for.inc:
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:
+  fence seq_cst
+  ret i32 0
+}
+
+; Currently not working
+; CHECK: @param_before_scop(
+define i32 @param_before_scop(float %scalar) nounwind {
+entry:
+  fence seq_cst
+  br label %for.cond
+; CHECK: entry:
+; CHECK: fence
+
+for.cond:
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body, label %return
+
+for.body:
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  store float %scalar, float* %arrayidx
+  br label %for.inc
+
+; CHECK: for.body:
+; CHECK: store float %scalar, float* %arrayidx
+
+for.inc:
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:
+  fence seq_cst
+  ret i32 0
+}
diff --git a/rc1/test/IndependentBlocks/scev-invalidated.ll b/rc1/test/IndependentBlocks/scev-invalidated.ll
new file mode 100644
index 0000000..18d888f
--- /dev/null
+++ b/rc1/test/IndependentBlocks/scev-invalidated.ll
@@ -0,0 +1,22 @@
+; RUN: opt %loadPolly -polly-codegen-scev -polly-independent < %s
+target datalayout ="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @arc_either() {
+entry:
+  %ang2.2.reg2mem = alloca i64
+  br i1 undef, label %return, label %if.then6
+
+if.then6:
+  %rem7 = srem i64 undef, 1474560
+  br i1 false, label %if.else, label %return
+
+if.else:
+  %add16 = add nsw i64 %rem7, 1474560
+  %rem7.add16 = select i1 undef, i64 %rem7, i64 %add16
+  store i64 %rem7.add16, i64* %ang2.2.reg2mem
+  br label %return
+
+return:
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/OpenMP/nested_loop_both_parallel.ll b/rc1/test/Isl/Ast/OpenMP/nested_loop_both_parallel.ll
new file mode 100644
index 0000000..bba34cc
--- /dev/null
+++ b/rc1/test/Isl/Ast/OpenMP/nested_loop_both_parallel.ll
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -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-pc-linux-gnu"
+
+; for (i = 0; i < 1024; i++)
+;   for (j = 0; j < 1024; j++)
+;     A[i][j] = 1;
+
+@A = common global [1024 x [1024 x i32]] zeroinitializer
+define void @bar() {
+start:
+  fence seq_cst
+  br label %loop.i
+
+loop.i:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.i.backedge ]
+  %exitcond.i = icmp ne i64 %i, 1024
+  br i1 %exitcond.i, label %loop.j, label %ret
+
+loop.j:
+  %j = phi i64 [ 0, %loop.i], [ %j.next, %loop.j.backedge ]
+  %exitcond.j = icmp ne i64 %j, 1024
+  br i1 %exitcond.j, label %loop.body, label %loop.i.backedge
+
+loop.body:
+  %scevgep = getelementptr [1024 x [1024 x i32] ]* @A, i64 0, i64 %j, i64 %i
+  store i32 1, i32* %scevgep
+  br label %loop.j.backedge
+
+loop.j.backedge:
+  %j.next = add nsw i64 %j, 1
+  br label %loop.j
+
+loop.i.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.i
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: #pragma omp parallel for
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:   for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:     Stmt_loop_body(c1, c3);
diff --git a/rc1/test/Isl/Ast/OpenMP/nested_loop_both_parallel_parametric.ll b/rc1/test/Isl/Ast/OpenMP/nested_loop_both_parallel_parametric.ll
new file mode 100644
index 0000000..23f4c24
--- /dev/null
+++ b/rc1/test/Isl/Ast/OpenMP/nested_loop_both_parallel_parametric.ll
@@ -0,0 +1,60 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -analyze -polly-delinearize < %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-pc-linux-gnu"
+; int A[1024][1024];
+; void bar(int n) {
+;   for (i = 0; i < n; i++)
+;     for (j = 0; j < n; j++)
+;       A[i][j] = 1;
+; }
+@A = common global [1024 x [1024 x i32]] zeroinitializer
+define void @bar(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.i
+
+loop.i:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.i.backedge ]
+  %exitcond.i = icmp ne i64 %i, %n
+  br i1 %exitcond.i, label %loop.j, label %ret
+
+loop.j:
+  %j = phi i64 [ 0, %loop.i], [ %j.next, %loop.j.backedge ]
+  %exitcond.j = icmp ne i64 %j, %n
+  br i1 %exitcond.j, label %loop.body, label %loop.i.backedge
+
+loop.body:
+  %scevgep = getelementptr [1024 x [1024 x i32] ]* @A, i64 0, i64 %j, i64 %i
+  store i32 1, i32* %scevgep
+  br label %loop.j.backedge
+
+loop.j.backedge:
+  %j.next = add nsw i64 %j, 1
+  br label %loop.j
+
+loop.i.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.i
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; At the first look both loops seem parallel, however due to the linearization
+; of memory access functions, we get the following dependences:
+;    [n] -> { loop_body[i0, i1] -> loop_body[1024 + i0, -1 + i1]:
+;                                           0 <= i0 < n - 1024  and 1 <= i1 < n}
+; They cause the outer loop to be non-parallel.  We can only prove their
+; absence, if we know that n < 1024. This information is currently not available
+; to polly. However, we should be able to obtain it due to the out of bounds
+; memory accesses, that would happen if n >= 1024.
+
+; Note that we do not delinearize this access function because it is considered
+; to already be affine: {{0,+,4}<%loop.i>,+,4096}<%loop.j>.
+
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   #pragma simd
+; CHECK:   #pragma omp parallel for
+; CHECK:   for (int c3 = 0; c3 < n; c3 += 1)
+; CHECK:     Stmt_loop_body(c1, c3);
diff --git a/rc1/test/Isl/Ast/OpenMP/nested_loop_inner_parallel.ll b/rc1/test/Isl/Ast/OpenMP/nested_loop_inner_parallel.ll
new file mode 100644
index 0000000..c92fb1d
--- /dev/null
+++ b/rc1/test/Isl/Ast/OpenMP/nested_loop_inner_parallel.ll
@@ -0,0 +1,47 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -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-pc-linux-gnu"
+
+; for (i = 0; i < n; i++)
+;   for (j = 0; j < n; j++)
+;     A[j] = 1;
+
+@A = common global [1024 x i32] zeroinitializer
+define void @bar(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.i
+
+loop.i:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.i.backedge ]
+  %exitcond.i = icmp ne i64 %i, %n
+  br i1 %exitcond.i, label %loop.j, label %ret
+
+loop.j:
+  %j = phi i64 [ 0, %loop.i], [ %j.next, %loop.j.backedge ]
+  %exitcond.j = icmp ne i64 %j, %n
+  br i1 %exitcond.j, label %loop.body, label %loop.i.backedge
+
+loop.body:
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %j
+  store i32 1, i32* %scevgep
+  br label %loop.j.backedge
+
+loop.j.backedge:
+  %j.next = add nsw i64 %j, 1
+  br label %loop.j
+
+loop.i.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.i
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   #pragma simd
+; CHECK:   #pragma omp parallel for
+; CHECK:   for (int c3 = 0; c3 < n; c3 += 1)
+; CHECK:     Stmt_loop_body(c1, c3);
diff --git a/rc1/test/Isl/Ast/OpenMP/nested_loop_outer_parallel.ll b/rc1/test/Isl/Ast/OpenMP/nested_loop_outer_parallel.ll
new file mode 100644
index 0000000..8ca4b1a
--- /dev/null
+++ b/rc1/test/Isl/Ast/OpenMP/nested_loop_outer_parallel.ll
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -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-pc-linux-gnu"
+
+; for (i = 0; i < n; i++)
+;   for (j = 0; j < n; j++)
+;     A[i] = 1;
+
+@A = common global [1024 x i32] zeroinitializer
+define void @bar(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.i
+
+loop.i:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.i.backedge ]
+  %exitcond.i = icmp ne i64 %i, %n
+  br i1 %exitcond.i, label %loop.j, label %ret
+
+loop.j:
+  %j = phi i64 [ 0, %loop.i], [ %j.next, %loop.j.backedge ]
+  %exitcond.j = icmp ne i64 %j, %n
+  br i1 %exitcond.j, label %loop.body, label %loop.i.backedge
+
+loop.body:
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %i
+  store i32 1, i32* %scevgep
+  br label %loop.j.backedge
+
+loop.j.backedge:
+  %j.next = add nsw i64 %j, 1
+  br label %loop.j
+
+loop.i.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.i
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: #pragma omp parallel for
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   for (int c3 = 0; c3 < n; c3 += 1)
+; CHECK:     Stmt_loop_body(c1, c3);
diff --git a/rc1/test/Isl/Ast/OpenMP/single_loop_param_non_parallel.ll b/rc1/test/Isl/Ast/OpenMP/single_loop_param_non_parallel.ll
new file mode 100644
index 0000000..9a3e18c
--- /dev/null
+++ b/rc1/test/Isl/Ast/OpenMP/single_loop_param_non_parallel.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -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-pc-linux-gnu"
+
+; for (i = 0; i < n; i++)
+;   A[0] = i;
+
+@A = common global [1024 x i32] zeroinitializer
+define void @bar(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.backedge ]
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 0
+  %exitcond = icmp ne i64 %i, %n
+  br i1 %exitcond, label %loop.body, label %ret
+
+loop.body:
+  store i32 1, i32* %scevgep
+  br label %loop.backedge
+
+loop.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.header
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   Stmt_loop_body(c1)
diff --git a/rc1/test/Isl/Ast/OpenMP/single_loop_param_parallel.ll b/rc1/test/Isl/Ast/OpenMP/single_loop_param_parallel.ll
new file mode 100644
index 0000000..cbe48d8
--- /dev/null
+++ b/rc1/test/Isl/Ast/OpenMP/single_loop_param_parallel.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -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-pc-linux-gnu"
+
+; for (i = 0; i < n; i++)
+;   A[i] = 1;
+
+@A = common global [1024 x i32] zeroinitializer
+define void @bar(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.backedge ]
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %i
+  %exitcond = icmp ne i64 %i, %n
+  br i1 %exitcond, label %loop.body, label %ret
+
+loop.body:
+  store i32 1, i32* %scevgep
+  br label %loop.backedge
+
+loop.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.header
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: #pragma simd
+; CHECK: #pragma omp parallel for
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   Stmt_loop_body(c1)
diff --git a/rc1/test/Isl/Ast/OpenMP/single_loop_param_parallel_computeout.ll b/rc1/test/Isl/Ast/OpenMP/single_loop_param_parallel_computeout.ll
new file mode 100644
index 0000000..1199aca
--- /dev/null
+++ b/rc1/test/Isl/Ast/OpenMP/single_loop_param_parallel_computeout.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -polly-dependences-computeout=1 -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-pc-linux-gnu"
+
+; for (i = 0; i < n; i++)
+;   A[i] = 1;
+
+@A = common global [1024 x i32] zeroinitializer
+define void @bar(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.backedge ]
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %i
+  %exitcond = icmp ne i64 %i, %n
+  br i1 %exitcond, label %loop.body, label %ret
+
+loop.body:
+  store i32 1, i32* %scevgep
+  br label %loop.backedge
+
+loop.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.header
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK-NOT: #pragma simd
+; CHECK-NOT: #pragma omp parallel for
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   Stmt_loop_body(c1)
diff --git a/rc1/test/Isl/Ast/reduction_dependences_equal_non_reduction_dependences.ll b/rc1/test/Isl/Ast/reduction_dependences_equal_non_reduction_dependences.ll
new file mode 100644
index 0000000..b6527fb
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_dependences_equal_non_reduction_dependences.ll
@@ -0,0 +1,56 @@
+; RUN: opt %loadPolly -basicaa -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; This loopnest contains a reduction which imposes the same dependences as the
+; accesses to the array A. We need to ensure we do __not__ parallelize anything
+; here.
+;
+; CHECK-NOT: pragma
+; CHECK-NOT: reduction
+;
+;    void AandSum(int *restrict sum, int *restrict A) {
+;      for (int i = 0; i < 1024; i++) {
+;        A[i] = A[i] + A[i - 1];
+;        A[i - 1] = A[i] + A[i - 2];
+;        *sum += i;
+;      }
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @AandSum(i32* noalias %sum, i32* noalias %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %sub = add nsw i32 %i.0, -1
+  %arrayidx1 = getelementptr inbounds i32* %A, i32 %sub
+  %tmp1 = load i32* %arrayidx1, align 4
+  %add = add nsw i32 %tmp, %tmp1
+  %arrayidx2 = getelementptr inbounds i32* %A, i32 %i.0
+  store i32 %add, i32* %arrayidx2, align 4
+  %sub4 = add nsw i32 %i.0, -2
+  %arrayidx5 = getelementptr inbounds i32* %A, i32 %sub4
+  %tmp2 = load i32* %arrayidx5, align 4
+  %add6 = add nsw i32 %add, %tmp2
+  %sub7 = add nsw i32 %i.0, -1
+  %arrayidx8 = getelementptr inbounds i32* %A, i32 %sub7
+  store i32 %add6, i32* %arrayidx8, align 4
+  %tmp3 = load i32* %sum, align 4
+  %add9 = add nsw i32 %tmp3, %i.0
+  store i32 %add9, i32* %sum, 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
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_in_one_dimension.ll b/rc1/test/Isl/Ast/reduction_in_one_dimension.ll
new file mode 100644
index 0000000..24bbd9f
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_in_one_dimension.ll
@@ -0,0 +1,57 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; Verify that we won't privatize anything in the outer dimension
+;
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 < 2 * n; c1 += 1)
+; CHECK:      #pragma simd reduction
+; CHECK:      for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:        Stmt_for_body3(c1, c3);
+;
+;    void foo(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+;        for (long j = 0; j < 1024; j++)
+;          A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @foo(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_loop_reversal.ll b/rc1/test/Isl/Ast/reduction_loop_reversal.ll
new file mode 100644
index 0000000..25ee3d7
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_loop_reversal.ll
@@ -0,0 +1,66 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK-NOT: #pragma simd{{\s*$}}
+; CHECK: #pragma simd reduction
+; CHECK: Stmt_S0(n - c1)
+; CHECK: #pragma simd{{\s*$}}
+; CHECK: Stmt_S1(n - c1)
+;
+;    void rlr(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+; S0:    A[0] += i;
+;      for (long i = 0; i < 2 * n; i++)
+; S1:    A[i + 1] = 1;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rlr(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  br label %S0
+
+S0:                                               ; preds = %for.body
+  %tmp = load i32* %A, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %A, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S0
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  br label %for.cond2
+
+for.cond2:                                        ; preds = %for.inc8, %for.end
+  %i1.0 = phi i32 [ 0, %for.end ], [ %inc9, %for.inc8 ]
+  %mul3 = shl nsw i32 %n, 1
+  %cmp4 = icmp slt i32 %i1.0, %mul3
+  br i1 %cmp4, label %for.body5, label %for.end10
+
+for.body5:                                        ; preds = %for.cond2
+  br label %S1
+
+S1:                                               ; preds = %for.body5
+  %add6 = add nsw i32 %i1.0, 1
+  %arrayidx7 = getelementptr inbounds i32* %A, i32 %add6
+  store i32 1, i32* %arrayidx7, align 4
+  br label %for.inc8
+
+for.inc8:                                         ; preds = %S1
+  %inc9 = add nsw i32 %i1.0, 1
+  br label %for.cond2
+
+for.end10:                                        ; preds = %for.cond2
+  ret void
+}
+
diff --git a/rc1/test/Isl/Ast/reduction_modulo_and_loop_reversal_schedule.ll b/rc1/test/Isl/Ast/reduction_modulo_and_loop_reversal_schedule.ll
new file mode 100644
index 0000000..0285dbb
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_and_loop_reversal_schedule.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK-NOT: #pragma simd{{\s*$}}
+; CHECK: #pragma simd reduction
+; CHECK: Stmt_S0(2 * n - c1)
+; CHECK: #pragma simd{{\s*$}}
+; CHECK: Stmt_S1
+; CHECK: #pragma simd reduction
+; CHECK: Stmt_S0(2 * n - c1)
+; CHECK-NOT: #pragma simd{{\s*$}}
+;
+;    void rmalrs(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+; S0:    A[0] += i;
+;      for (long i = 0; i < 2 * n; i++)
+; S1:    A[i + 1] = 1;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmalrs(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  br label %S0
+
+S0:                                               ; preds = %for.body
+  %tmp = load i32* %A, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %A, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S0
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  br label %for.cond2
+
+for.cond2:                                        ; preds = %for.inc8, %for.end
+  %i1.0 = phi i32 [ 0, %for.end ], [ %inc9, %for.inc8 ]
+  %mul3 = shl nsw i32 %n, 1
+  %cmp4 = icmp slt i32 %i1.0, %mul3
+  br i1 %cmp4, label %for.body5, label %for.end10
+
+for.body5:                                        ; preds = %for.cond2
+  br label %S1
+
+S1:                                               ; preds = %for.body5
+  %add6 = add nsw i32 %i1.0, 1
+  %arrayidx7 = getelementptr inbounds i32* %A, i32 %add6
+  store i32 1, i32* %arrayidx7, align 4
+  br label %for.inc8
+
+for.inc8:                                         ; preds = %S1
+  %inc9 = add nsw i32 %i1.0, 1
+  br label %for.cond2
+
+for.end10:                                        ; preds = %for.cond2
+  ret void
+}
+
diff --git a/rc1/test/Isl/Ast/reduction_modulo_and_loop_reversal_schedule_2.ll b/rc1/test/Isl/Ast/reduction_modulo_and_loop_reversal_schedule_2.ll
new file mode 100644
index 0000000..3ac8a29
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_and_loop_reversal_schedule_2.ll
@@ -0,0 +1,76 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK:    #pragma omp parallel for reduction
+; CHECK:    for (int c0 = 0; c0 <= 2; c0 += 1) {
+; CHECK:      if (c0 == 2) {
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c1 = 1; c1 < 2 * n; c1 += 2)
+; CHECK:          Stmt_S0(c1);
+; CHECK:      } else if (c0 == 1) {
+; CHECK:        #pragma simd
+; CHECK:        for (int c1 = 0; c1 < 2 * n; c1 += 1)
+; CHECK:          Stmt_S1(c1);
+; CHECK:      } else
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c1 = -2 * n + 2; c1 <= 0; c1 += 2)
+; CHECK:          Stmt_S0(-c1);
+; CHECK:    }
+;
+;    void rmalrs2(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+; S0:    A[0] += i;
+;      for (long i = 0; i < 2 * n; i++)
+; S1:    A[i + 1] = 1;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmalrs2(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  br label %S0
+
+S0:                                               ; preds = %for.body
+  %tmp = load i32* %A, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %A, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S0
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  br label %for.cond2
+
+for.cond2:                                        ; preds = %for.inc8, %for.end
+  %i1.0 = phi i32 [ 0, %for.end ], [ %inc9, %for.inc8 ]
+  %mul3 = shl nsw i32 %n, 1
+  %cmp4 = icmp slt i32 %i1.0, %mul3
+  br i1 %cmp4, label %for.body5, label %for.end10
+
+for.body5:                                        ; preds = %for.cond2
+  br label %S1
+
+S1:                                               ; preds = %for.body5
+  %add6 = add nsw i32 %i1.0, 1
+  %arrayidx7 = getelementptr inbounds i32* %A, i32 %add6
+  store i32 1, i32* %arrayidx7, align 4
+  br label %for.inc8
+
+for.inc8:                                         ; preds = %S1
+  %inc9 = add nsw i32 %i1.0, 1
+  br label %for.cond2
+
+for.end10:                                        ; preds = %for.cond2
+  ret void
+}
+
diff --git a/rc1/test/Isl/Ast/reduction_modulo_schedule.ll b/rc1/test/Isl/Ast/reduction_modulo_schedule.ll
new file mode 100644
index 0000000..f4dfef6
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_schedule.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK-NOT: #pragma simd{{\s*$}}
+; CHECK: #pragma simd reduction
+; CHECK: Stmt_S0
+; CHECK: #pragma simd{{\s*$}}
+; CHECK: Stmt_S1
+; CHECK: #pragma simd reduction
+; CHECK: Stmt_S0
+; CHECK-NOT: #pragma simd{{\s*$}}
+;
+;    void rms(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+; S0:    A[0] += i;
+;      for (long i = 0; i < 2 * n; i++)
+; S1:    A[i + 1] = 1;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rms(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  br label %S0
+
+S0:                                               ; preds = %for.body
+  %tmp = load i32* %A, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %A, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %S0
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  br label %for.cond2
+
+for.cond2:                                        ; preds = %for.inc8, %for.end
+  %i1.0 = phi i32 [ 0, %for.end ], [ %inc9, %for.inc8 ]
+  %mul3 = shl nsw i32 %n, 1
+  %cmp4 = icmp slt i32 %i1.0, %mul3
+  br i1 %cmp4, label %for.body5, label %for.end10
+
+for.body5:                                        ; preds = %for.cond2
+  br label %S1
+
+S1:                                               ; preds = %for.body5
+  %add6 = add nsw i32 %i1.0, 1
+  %arrayidx7 = getelementptr inbounds i32* %A, i32 %add6
+  store i32 1, i32* %arrayidx7, align 4
+  br label %for.inc8
+
+for.inc8:                                         ; preds = %S1
+  %inc9 = add nsw i32 %i1.0, 1
+  br label %for.cond2
+
+for.end10:                                        ; preds = %for.cond2
+  ret void
+}
+
diff --git a/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions.ll b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions.ll
new file mode 100644
index 0000000..af7f799
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions.ll
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c0 = 0; c0 <= 1; c0 += 1) {
+; CHECK:      if (c0 == 1) {
+; CHECK:        for (int c1 = 1; c1 < 2 * n; c1 += 2)
+; CHECK:          #pragma simd reduction
+; CHECK:          for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:            Stmt_for_body3(c1, c3);
+; CHECK:      } else
+; CHECK:        for (int c1 = 0; c1 < 2 * n - 1; c1 += 2)
+; CHECK:          #pragma simd reduction
+; CHECK:          for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:            Stmt_for_body3(c1, c3);
+; CHECK:    }
+;
+;    void rmsmd(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+;        for (long j = 0; j < 1024; j++)
+;          A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmsmd(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_2.ll b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_2.ll
new file mode 100644
index 0000000..34677d2
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_2.ll
@@ -0,0 +1,64 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; Verify that the outer dimension doesnt't carry reduction dependences
+;
+; CHECK-NOT:#pragma omp parallel for reduction
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 < 2 * n; c1 += 1) {
+; CHECK:      if (c1 % 2 == 0) {
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:          Stmt_for_body3(c1, c3);
+; CHECK:      } else
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:          Stmt_for_body3(c1, c3);
+; CHECK:    }
+;
+;    void rmsmd2(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+;        for (long j = 0; j < 1024; j++)
+;          A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmsmd2(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_3.ll b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_3.ll
new file mode 100644
index 0000000..0a544d2
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_3.ll
@@ -0,0 +1,62 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; Verify that the outer dimension doesnt't carry reduction dependences
+;
+; CHECK-NOT:#pragma omp parallel for reduction
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 < 2 * n; c1 += 1)
+; CHECK:      #pragma simd reduction
+; CHECK:      for (int c3 = 0; c3 <= 1023; c3 += 1) {
+; CHECK:        if (c3 % 2 == 0) {
+; CHECK:          Stmt_for_body3(c1, c3);
+; CHECK:        } else
+; CHECK:          Stmt_for_body3(c1, c3);
+; CHECK:      }
+;
+;    void rmsmd3(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+;        for (long j = 0; j < 1024; j++)
+;          A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmsmd3(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_4.ll b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_4.ll
new file mode 100644
index 0000000..8516207
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_4.ll
@@ -0,0 +1,62 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; Verify that the outer dimension doesnt't carry reduction dependences
+;
+; CHECK-NOT:#pragma omp parallel for reduction
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 < 2 * n; c1 += 1)
+; CHECK:      #pragma simd reduction
+; CHECK:      for (int c3 = -1022; c3 <= 1023; c3 += 1) {
+; CHECK:        if ((c3 + 1022) % 2 == 0 && c3 <= 0) {
+; CHECK:          Stmt_for_body3(c1, -c3);
+; CHECK:        } else if ((c3 + 1023) % 2 == 0 && c3 >= 1)
+; CHECK:          Stmt_for_body3(c1, c3);
+; CHECK:      }
+;
+;    void rmsmd4(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+;        for (long j = 0; j < 1024; j++)
+;          A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmsmd4(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_5.ll b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_5.ll
new file mode 100644
index 0000000..a1e00b8
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_modulo_schedule_multiple_dimensions_5.ll
@@ -0,0 +1,65 @@
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; Verify that only the outer dimension needs privatization
+;
+; CHECK:    #pragma omp parallel for reduction
+; CHECK:    for (int c1 = 0; c1 <= 1023; c1 += 1) {
+; CHECK:      if (c1 % 2 == 0) {
+; CHECK-NOT:    #pragma simd reduction
+; CHECK:        #pragma simd
+; CHECK:        for (int c3 = 0; c3 < 2 * n; c3 += 1)
+; CHECK:          Stmt_for_body3(c3, c1);
+; CHECK:      } else
+; CHECK-NOT:    #pragma simd reduction
+; CHECK:        #pragma simd
+; CHECK:        for (int c3 = -2 * n + 1; c3 <= 0; c3 += 1)
+; CHECK:          Stmt_for_body3(-c3, c1);
+; CHECK:    }
+;
+;    void rmsmd5(int *A, long n) {
+;      for (long i = 0; i < 2 * n; i++)
+;        for (long j = 0; j < 1024; j++)
+;          A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmsmd5(i32* %A, i32 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc4, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+  %mul = shl nsw i32 %n, 1
+  %cmp = icmp slt i32 %i.0, %mul
+  br i1 %cmp, label %for.body, label %for.end6
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc4
+
+for.inc4:                                         ; preds = %for.end
+  %inc5 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end6:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_multiple_dimensions.ll b/rc1/test/Isl/Ast/reduction_multiple_dimensions.ll
new file mode 100644
index 0000000..98520dc
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_multiple_dimensions.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK-NOT:#pragma omp parallel for reduction
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 <= 2047; c1 += 1)
+; CHECK:      for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c5 = 0; c5 <= 511; c5 += 1)
+; CHECK:          Stmt_for_body6(c1, c3, c5);
+;
+;    void rmd(int *A) {
+;      for (long i = 0; i < 2048; i++)
+;        for (long j = 0; j < 1024; j++)
+;          for (long k = 0; k < 512; k++)
+;            A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmd(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond2 = icmp ne i32 %i.0, 2048
+  br i1 %exitcond2, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc7, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc8, %for.inc7 ]
+  %exitcond1 = icmp ne i32 %j.0, 1024
+  br i1 %exitcond1, label %for.body3, label %for.end9
+
+for.body3:                                        ; preds = %for.cond1
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %k.0, 512
+  br i1 %exitcond, label %for.body6, label %for.end
+
+for.body6:                                        ; preds = %for.cond4
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body6
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond4
+
+for.end:                                          ; preds = %for.cond4
+  br label %for.inc7
+
+for.inc7:                                         ; preds = %for.end
+  %inc8 = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end9:                                         ; preds = %for.cond1
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end9
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_multiple_dimensions_2.ll b/rc1/test/Isl/Ast/reduction_multiple_dimensions_2.ll
new file mode 100644
index 0000000..af63bc7
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_multiple_dimensions_2.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK-NOT:#pragma omp parallel for reduction
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 <= 2047; c1 += 1)
+; CHECK:      for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c5 = 0; c5 <= 511; c5 += 1)
+; CHECK:          Stmt_for_body6(c1, c3, c5);
+;
+;    void rmd2(int *A) {
+;      for (long i = 0; i < 2048; i++)
+;        for (long j = 0; j < 1024; j++)
+;          for (long k = 0; k < 512; k++)
+;            A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmd2(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond2 = icmp ne i32 %i.0, 2048
+  br i1 %exitcond2, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc7, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc8, %for.inc7 ]
+  %exitcond1 = icmp ne i32 %j.0, 1024
+  br i1 %exitcond1, label %for.body3, label %for.end9
+
+for.body3:                                        ; preds = %for.cond1
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %k.0, 512
+  br i1 %exitcond, label %for.body6, label %for.end
+
+for.body6:                                        ; preds = %for.cond4
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body6
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond4
+
+for.end:                                          ; preds = %for.cond4
+  br label %for.inc7
+
+for.inc7:                                         ; preds = %for.end
+  %inc8 = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end9:                                         ; preds = %for.cond1
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end9
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_multiple_dimensions_3.ll b/rc1/test/Isl/Ast/reduction_multiple_dimensions_3.ll
new file mode 100644
index 0000000..13ae1a1
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_multiple_dimensions_3.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK-NOT:#pragma omp parallel for reduction
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 <= 2047; c1 += 1)
+; CHECK:      for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c5 = 0; c5 <= 511; c5 += 1)
+; CHECK:          Stmt_for_body6(c1, c3, c5);
+;
+;    void rmd3(int *A) {
+;      for (long i = 0; i < 2048; i++)
+;        for (long j = 0; j < 1024; j++)
+;          for (long k = 0; k < 512; k++)
+;            A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmd3(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond2 = icmp ne i32 %i.0, 2048
+  br i1 %exitcond2, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc7, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc8, %for.inc7 ]
+  %exitcond1 = icmp ne i32 %j.0, 1024
+  br i1 %exitcond1, label %for.body3, label %for.end9
+
+for.body3:                                        ; preds = %for.cond1
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %k.0, 512
+  br i1 %exitcond, label %for.body6, label %for.end
+
+for.body6:                                        ; preds = %for.cond4
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body6
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond4
+
+for.end:                                          ; preds = %for.cond4
+  br label %for.inc7
+
+for.inc7:                                         ; preds = %for.end
+  %inc8 = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end9:                                         ; preds = %for.cond1
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end9
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/reduction_multiple_dimensions_4.ll b/rc1/test/Isl/Ast/reduction_multiple_dimensions_4.ll
new file mode 100644
index 0000000..1a8f703
--- /dev/null
+++ b/rc1/test/Isl/Ast/reduction_multiple_dimensions_4.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK-NOT:#pragma omp parallel for reduction
+; CHECK:    #pragma omp parallel for
+; CHECK:    for (int c1 = 0; c1 <= 2047; c1 += 1)
+; CHECK:      for (int c3 = 0; c3 <= 1023; c3 += 1)
+; CHECK:        #pragma simd reduction
+; CHECK:        for (int c5 = 0; c5 <= 511; c5 += 1)
+; CHECK:          Stmt_for_body6(c1, c3, c5);
+;
+;    void rmd4(int *A) {
+;      for (long i = 0; i < 2048; i++)
+;        for (long j = 0; j < 1024; j++)
+;          for (long k = 0; k < 512; k++)
+;            A[i] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @rmd4(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond2 = icmp ne i32 %i.0, 2048
+  br i1 %exitcond2, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc7, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc8, %for.inc7 ]
+  %exitcond1 = icmp ne i32 %j.0, 1024
+  br i1 %exitcond1, label %for.body3, label %for.end9
+
+for.body3:                                        ; preds = %for.cond1
+  br label %for.cond4
+
+for.cond4:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %k.0, 512
+  br i1 %exitcond, label %for.body6, label %for.end
+
+for.body6:                                        ; preds = %for.cond4
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %arrayidx, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body6
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond4
+
+for.end:                                          ; preds = %for.cond4
+  br label %for.inc7
+
+for.inc7:                                         ; preds = %for.end
+  %inc8 = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end9:                                         ; preds = %for.cond1
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end9
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/rlr___%for.cond---%for.end10.jscop b/rc1/test/Isl/Ast/rlr___%for.cond---%for.end10.jscop
new file mode 100644
index 0000000..fc50d5c
--- /dev/null
+++ b/rc1/test/Isl/Ast/rlr___%for.cond---%for.end10.jscop
@@ -0,0 +1,32 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end10",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S0[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S0",
+         "schedule" : "[n] -> { Stmt_S0[i0] -> scattering[0, n - i0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S1[i0] -> MemRef_A[1 + i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S1[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S1",
+         "schedule" : "[n] -> { Stmt_S1[i0] -> scattering[1, n - i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmalrs2___%for.cond---%for.end10.jscop b/rc1/test/Isl/Ast/rmalrs2___%for.cond---%for.end10.jscop
new file mode 100644
index 0000000..c84f0a0
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmalrs2___%for.cond---%for.end10.jscop
@@ -0,0 +1,32 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end10",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S0[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S0",
+         "schedule" : "[n] -> { Stmt_S0[i0] -> scattering[0, -i0, 0]: i0 % 2 = 0; Stmt_S0[i0] -> scattering[2, i0, 0]: i0 % 2 = 1 }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S1[i0] -> MemRef_A[1 + i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S1[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S1",
+         "schedule" : "[n] -> { Stmt_S1[i0] -> scattering[1, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmalrs___%for.cond---%for.end10.jscop b/rc1/test/Isl/Ast/rmalrs___%for.cond---%for.end10.jscop
new file mode 100644
index 0000000..9740b57
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmalrs___%for.cond---%for.end10.jscop
@@ -0,0 +1,32 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end10",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S0[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S0",
+         "schedule" : "[n] -> { Stmt_S0[i0] -> scattering[0, 2 * n - i0, 0]: i0 % 2 = 0; Stmt_S0[i0] -> scattering[2, 2  * n - i0, 0]: i0 % 2 = 1 }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S1[i0] -> MemRef_A[1 + i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S1[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S1",
+         "schedule" : "[n] -> { Stmt_S1[i0] -> scattering[1, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmd2___%for.cond---%for.end12.jscop b/rc1/test/Isl/Ast/rmd2___%for.cond---%for.end12.jscop
new file mode 100644
index 0000000..bca9793
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmd2___%for.cond---%for.end12.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end12",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body6[i0, i1, i2] : i0 >= 0 and i0 <= 2047 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 511 }",
+         "name" : "Stmt_for_body6",
+         "schedule" : "{ Stmt_for_body6[i0, i1, i2] -> scattering[0, i1, 0, i0, 0, i2, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmd3___%for.cond---%for.end12.jscop b/rc1/test/Isl/Ast/rmd3___%for.cond---%for.end12.jscop
new file mode 100644
index 0000000..7cd7570
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmd3___%for.cond---%for.end12.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end12",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body6[i0, i1, i2] : i0 >= 0 and i0 <= 2047 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 511 }",
+         "name" : "Stmt_for_body6",
+         "schedule" : "{ Stmt_for_body6[i0, i1, i2] -> scattering[0, i2, 0, i1, 0, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmd4___%for.cond---%for.end12.jscop b/rc1/test/Isl/Ast/rmd4___%for.cond---%for.end12.jscop
new file mode 100644
index 0000000..b29c322
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmd4___%for.cond---%for.end12.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end12",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body6[i0, i1, i2] : i0 >= 0 and i0 <= 2047 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 511 }",
+         "name" : "Stmt_for_body6",
+         "schedule" : "{ Stmt_for_body6[i0, i1, i2] -> scattering[0, i2, 0, i0, 0, i1, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmd___%for.cond---%for.end12.jscop b/rc1/test/Isl/Ast/rmd___%for.cond---%for.end12.jscop
new file mode 100644
index 0000000..be7cdc2
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmd___%for.cond---%for.end12.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end12",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body6[i0, i1, i2] : i0 >= 0 and i0 <= 2047 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 511 }",
+         "name" : "Stmt_for_body6",
+         "schedule" : "{ Stmt_for_body6[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rms___%for.cond---%for.end10.jscop b/rc1/test/Isl/Ast/rms___%for.cond---%for.end10.jscop
new file mode 100644
index 0000000..15a6930
--- /dev/null
+++ b/rc1/test/Isl/Ast/rms___%for.cond---%for.end10.jscop
@@ -0,0 +1,32 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end10",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S0[i0] -> MemRef_A[0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S0[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S0",
+         "schedule" : "[n] -> { Stmt_S0[i0] -> scattering[0, i0, 0]: i0 % 2 = 0; Stmt_S0[i0] -> scattering[2, i0, 0]: i0 % 2 = 1 }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_S1[i0] -> MemRef_A[1 + i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_S1[i0] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 }",
+         "name" : "Stmt_S1",
+         "schedule" : "[n] -> { Stmt_S1[i0] -> scattering[1, i0, 0] }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmsmd2___%for.cond---%for.end6.jscop b/rc1/test/Isl/Ast/rmsmd2___%for.cond---%for.end6.jscop
new file mode 100644
index 0000000..38cb44b
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmsmd2___%for.cond---%for.end6.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "[n] -> { Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0]: i0 % 2 = 0; Stmt_for_body3[i0, i1] -> scattering[0, i0, 1, i1, 0]: i0 % 2 = 1 }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmsmd3___%for.cond---%for.end6.jscop b/rc1/test/Isl/Ast/rmsmd3___%for.cond---%for.end6.jscop
new file mode 100644
index 0000000..44d71a3
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmsmd3___%for.cond---%for.end6.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "[n] -> { Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0]: i1 % 2 = 0; Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 1]: i1 % 2 = 1 }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmsmd4___%for.cond---%for.end6.jscop b/rc1/test/Isl/Ast/rmsmd4___%for.cond---%for.end6.jscop
new file mode 100644
index 0000000..9bfd4aa
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmsmd4___%for.cond---%for.end6.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "[n] -> { Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, -i1, 0]: i1 % 2 = 0; Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 1]: i1 % 2 = 1 }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmsmd5___%for.cond---%for.end6.jscop b/rc1/test/Isl/Ast/rmsmd5___%for.cond---%for.end6.jscop
new file mode 100644
index 0000000..ee1c3dd
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmsmd5___%for.cond---%for.end6.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "[n] -> { Stmt_for_body3[i0, i1] -> scattering[0, i1, 0, i0, 0]: i1 % 2 = 0; Stmt_for_body3[i0, i1] -> scattering[0, i1, 1, -i0, 0]: i1 % 2 = 1 }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/rmsmd___%for.cond---%for.end6.jscop b/rc1/test/Isl/Ast/rmsmd___%for.cond---%for.end6.jscop
new file mode 100644
index 0000000..8a8678a
--- /dev/null
+++ b/rc1/test/Isl/Ast/rmsmd___%for.cond---%for.end6.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "[n] -> {  : n >= -2147483648 and n <= 2147483647 }",
+   "name" : "for.cond => for.end6",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_for_body3[i0, i1] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= -1 + 2n and n >= 1 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "[n] -> { Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0]: i0 % 2 = 0; Stmt_for_body3[i0, i1] -> scattering[1, i0, 0, i1, 0]: i0 % 2 = 1 }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/Ast/run-time-condition.ll b/rc1/test/Isl/Ast/run-time-condition.ll
new file mode 100644
index 0000000..8820932
--- /dev/null
+++ b/rc1/test/Isl/Ast/run-time-condition.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -basicaa -polly-ast -analyze < %s | FileCheck %s
+
+; for (i = 0; i < 1024; i++)
+;   A[i] = B[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-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @run-time-condition(i16* noalias %A, i16* noalias %B) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %indvar = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i64 %indvar, 1024
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i16* %B, i64 0
+  %load = load i16* %arrayidx
+  %add10 = add nsw i16 %load, 1
+  %arrayidx13 = getelementptr inbounds i16* %A, i64 %indvar
+  store i16 %add10, i16* %arrayidx13, align 2
+  %inc = add nsw i64 %indvar, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
+; CHECK: if (1)
+; CHECK:     for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:       Stmt_for_body(c1);
+; CHECK: else
+; CHECK:     {  /* original code */ }
+
diff --git a/rc1/test/Isl/Ast/simple-run-time-condition.ll b/rc1/test/Isl/Ast/simple-run-time-condition.ll
new file mode 100644
index 0000000..592a72b
--- /dev/null
+++ b/rc1/test/Isl/Ast/simple-run-time-condition.ll
@@ -0,0 +1,94 @@
+; RUN: opt %loadPolly -polly-ast -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, int o, double A[n][m], long p, long q) {
+;
+; if (o >= 0)
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;         A[i+p][j+q] = 1.0;
+; else
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;         A[i+p][j+q-100] = 1.0;
+;
+
+; This test case is meant to verify that the run-time condition generated
+; for the delinearization is simplified such that conditions that would not
+; cause any code to be executed are not generated.
+
+; CHECK: if ((q == 100 && o <= 0 && p >= 0) || (q == 0 && o >= 1 && p >= 0) ? 1 : 0)
+
+; CHECK:     if (o >= 1) {
+; CHECK:       for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:         for (int c3 = 0; c3 < m; c3 += 1)
+; CHECK:           Stmt_for_j(c1, c3);
+; CHECK:     } else
+; CHECK:       for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:         for (int c3 = 0; c3 < m; c3 += 1)
+; CHECK:           Stmt_for_j_1(c1, c3);
+
+; CHECK: else
+; CHECK:     {  /* original code */ }
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A, i64 %p, i64 %q) {
+entry:
+  br label %cond
+
+cond:
+  %cmp = icmp sgt i64 %o, 0
+  br i1 %cmp, label %for.i, label %for.i.1
+
+for.i:
+  %i = phi i64 [ 0, %cond ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j.inc ]
+  %offset0 = add nsw i64 %i, %p
+  %subscript0 = mul i64 %offset0, %m
+  %offset1 = add nsw i64 %j, %q
+  %subscript1 = add i64 %offset1, %subscript0
+  %idx = getelementptr inbounds double* %A, i64 %subscript1
+  store double 1.0, double* %idx
+  br label %for.j.inc
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+for.i.1:
+  %i.1 = phi i64 [ 0, %cond ], [ %i.inc.1, %for.i.inc.1 ]
+  br label %for.j.1
+
+for.j.1:
+  %j.1 = phi i64 [ 0, %for.i.1 ], [ %j.inc.1, %for.j.inc.1 ]
+  %offset0.1 = add nsw i64 %i.1, %p
+  %subscript0.1 = mul i64 %offset0.1, %m
+  %offset1.1 = add nsw i64 %j.1, %q
+  %subscript1.1 = add i64 %offset1.1, %subscript0.1
+  %subscript1.2 = sub i64 %subscript1.1, 100
+  %idx.1 = getelementptr inbounds double* %A, i64 %subscript1.2
+  store double 1.0, double* %idx.1
+  br label %for.j.inc.1
+
+for.j.inc.1:
+  %j.inc.1 = add nsw i64 %j.1, 1
+  %j.exitcond.1 = icmp eq i64 %j.inc.1, %m
+  br i1 %j.exitcond.1, label %for.i.inc.1, label %for.j.1
+
+for.i.inc.1:
+  %i.inc.1 = add nsw i64 %i.1, 1
+  %i.exitcond.1 = icmp eq i64 %i.inc.1, %n
+  br i1 %i.exitcond.1, label %end, label %for.i.1
+
+end:
+  ret void
+}
diff --git a/rc1/test/Isl/Ast/single_loop_strip_mine.ll b/rc1/test/Isl/Ast/single_loop_strip_mine.ll
new file mode 100644
index 0000000..2f83ca0
--- /dev/null
+++ b/rc1/test/Isl/Ast/single_loop_strip_mine.ll
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly -basicaa -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -basicaa -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s -check-prefix=CHECK-VECTOR
+
+; for (i = 0; i < 1024; i++)
+;   A[i] = B[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-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @single_loop_strip_mine(i16* noalias %A, i16* noalias %B) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %indvar = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i64 %indvar, 1024
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i16* %B, i64 0
+  %load = load i16* %arrayidx
+  %add10 = add nsw i16 %load, 1
+  %arrayidx13 = getelementptr inbounds i16* %A, i64 %indvar
+  store i16 %add10, i16* %arrayidx13, align 2
+  %inc = add nsw i64 %indvar, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:     Stmt_for_body(c1);
+
+; CHECK-VECTOR: #pragma omp parallel for
+; CHECK-VECTOR: for (int c0 = 0; c0 <= 1023; c0 += 4)
+; CHECK-VECTOR:     #pragma simd
+; CHECK-VECTOR:     for (int c1 = c0; c1 <= c0 + 3; c1 += 1)
+; CHECK-VECTOR:           Stmt_for_body(c1);
+
+
diff --git a/rc1/test/Isl/Ast/single_loop_strip_mine___%for.cond---%for.end.jscop b/rc1/test/Isl/Ast/single_loop_strip_mine___%for.cond---%for.end.jscop
new file mode 100644
index 0000000..7dcf837
--- /dev/null
+++ b/rc1/test/Isl/Ast/single_loop_strip_mine___%for.cond---%for.end.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_B[0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 1023 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> [o0, i0] : exists (e0 = [(o0)/4]: 4e0 = o0 and o0 <= i0 and o0 >= -3 + i0 and i0 >= 0 and i0 <= 1023) }"
+      }
+   ]
+}
diff --git a/rc1/test/Isl/CodeGen/20100617.ll b/rc1/test/Isl/CodeGen/20100617.ll
new file mode 100644
index 0000000..398e620
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100617.ll
@@ -0,0 +1,19 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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 @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
+}
diff --git a/rc1/test/Isl/CodeGen/20100622.ll b/rc1/test/Isl/CodeGen/20100622.ll
new file mode 100644
index 0000000..02c6775
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100622.ll
@@ -0,0 +1,43 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %s
+; RUN: opt %loadPolly %defaultOpts -polly-detect -analyze  < %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"
+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:
diff --git a/rc1/test/Isl/CodeGen/20100707.ll b/rc1/test/Isl/CodeGen/20100707.ll
new file mode 100644
index 0000000..a19d636
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100707.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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 @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
+}
diff --git a/rc1/test/Isl/CodeGen/20100707_2.ll b/rc1/test/Isl/CodeGen/20100707_2.ll
new file mode 100644
index 0000000..ae46eb2
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100707_2.ll
@@ -0,0 +1,115 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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"
+
+@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
+}
diff --git a/rc1/test/Isl/CodeGen/20100708.ll b/rc1/test/Isl/CodeGen/20100708.ll
new file mode 100644
index 0000000..5edfe52
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100708.ll
@@ -0,0 +1,18 @@
+; RUN: opt %loadPolly %defaultOpts -polly-detect %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 fastcc void @execute() nounwind {
+entry:
+  br i1 undef, label %check_stack.exit456.thread, label %bb.i451.preheader
+
+bb.i451.preheader:                                ; preds = %bb116
+  br label %bb.i451
+
+bb.i451:                                          ; preds = %bb.i451, %bb.i451.preheader
+  br label %bb.i451
+
+check_stack.exit456.thread:                       ; preds = %bb116
+  unreachable
+
+}
diff --git a/rc1/test/Isl/CodeGen/20100708_2.ll b/rc1/test/Isl/CodeGen/20100708_2.ll
new file mode 100644
index 0000000..01a2ad7
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100708_2.ll
@@ -0,0 +1,28 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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 @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
+}
diff --git a/rc1/test/Isl/CodeGen/20100713.ll b/rc1/test/Isl/CodeGen/20100713.ll
new file mode 100644
index 0000000..cb3cdd4
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100713.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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 @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
+}
diff --git a/rc1/test/Isl/CodeGen/20100713_2.ll b/rc1/test/Isl/CodeGen/20100713_2.ll
new file mode 100644
index 0000000..ba81cee
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100713_2.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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 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
+}
diff --git a/rc1/test/Isl/CodeGen/20100717.ll b/rc1/test/Isl/CodeGen/20100717.ll
new file mode 100644
index 0000000..acadbbc
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100717.ll
@@ -0,0 +1,39 @@
+; RUN: opt %loadPolly %defaultOpts  -polly-codegen-isl -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 @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
+}
diff --git a/rc1/test/Isl/CodeGen/20100718-DomInfo-2.ll b/rc1/test/Isl/CodeGen/20100718-DomInfo-2.ll
new file mode 100644
index 0000000..b5b1afa
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100718-DomInfo-2.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl -verify-dom-info -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 @getNonAffNeighbour() nounwind {
+entry:
+  br i1 undef, label %bb, label %bb6
+
+bb:                                               ; preds = %entry
+  br i1 false, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  br label %bb16
+
+bb2:                                              ; preds = %bb
+  br i1 false, label %bb3, label %bb4
+
+bb3:                                              ; preds = %bb2
+  br label %bb16
+
+bb4:                                              ; preds = %bb2
+  br label %bb16
+
+bb6:                                              ; preds = %entry
+  br i1 false, label %bb7, label %bb9
+
+bb7:                                              ; preds = %bb6
+  br label %bb16
+
+bb9:                                              ; preds = %bb6
+  br label %bb16
+
+bb16:                                             ; preds = %bb9, %bb7, %bb4, %bb3, %bb1
+  ret void
+}
diff --git a/rc1/test/Isl/CodeGen/20100718-DomInfo.ll b/rc1/test/Isl/CodeGen/20100718-DomInfo.ll
new file mode 100644
index 0000000..d0daa2c
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100718-DomInfo.ll
@@ -0,0 +1,28 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl -verify-dom-info -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 @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
+}
diff --git a/rc1/test/Isl/CodeGen/20100720-MultipleConditions.ll b/rc1/test/Isl/CodeGen/20100720-MultipleConditions.ll
new file mode 100644
index 0000000..6424719
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100720-MultipleConditions.ll
@@ -0,0 +1,96 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze %s
+
+;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];
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; 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
diff --git a/rc1/test/Isl/CodeGen/20100809-IndependentBlock.ll b/rc1/test/Isl/CodeGen/20100809-IndependentBlock.ll
new file mode 100644
index 0000000..df64aa0
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100809-IndependentBlock.ll
@@ -0,0 +1,31 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl -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
+}
diff --git a/rc1/test/Isl/CodeGen/20100811-ScalarDependencyBetweenBrAndCnd.ll b/rc1/test/Isl/CodeGen/20100811-ScalarDependencyBetweenBrAndCnd.ll
new file mode 100644
index 0000000..e6250fd
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20100811-ScalarDependencyBetweenBrAndCnd.ll
@@ -0,0 +1,30 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl -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
+}
diff --git a/rc1/test/Isl/CodeGen/20101030-Overflow.ll b/rc1/test/Isl/CodeGen/20101030-Overflow.ll
new file mode 100644
index 0000000..540c2c1
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20101030-Overflow.ll
@@ -0,0 +1,22 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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
+
+}
diff --git a/rc1/test/Isl/CodeGen/20101103-Overflow3.ll b/rc1/test/Isl/CodeGen/20101103-Overflow3.ll
new file mode 100644
index 0000000..cc6bb66
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20101103-Overflow3.ll
@@ -0,0 +1,24 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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
+}
diff --git a/rc1/test/Isl/CodeGen/20101103-signmissmatch.ll b/rc1/test/Isl/CodeGen/20101103-signmissmatch.ll
new file mode 100644
index 0000000..50636cf
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20101103-signmissmatch.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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
+}
diff --git a/rc1/test/Isl/CodeGen/20110226-Ignore-Dead-Code.ll b/rc1/test/Isl/CodeGen/20110226-Ignore-Dead-Code.ll
new file mode 100644
index 0000000..67b2e6f
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20110226-Ignore-Dead-Code.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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
+}
diff --git a/rc1/test/Isl/CodeGen/20110226-PHI-Node-removed.ll b/rc1/test/Isl/CodeGen/20110226-PHI-Node-removed.ll
new file mode 100644
index 0000000..75676be
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20110226-PHI-Node-removed.ll
@@ -0,0 +1,30 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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
+}
diff --git a/rc1/test/Isl/CodeGen/20110312-Fail-without-basicaa.ll b/rc1/test/Isl/CodeGen/20110312-Fail-without-basicaa.ll
new file mode 100644
index 0000000..28e275b
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20110312-Fail-without-basicaa.ll
@@ -0,0 +1,27 @@
+; 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
+}
diff --git a/rc1/test/Isl/CodeGen/20120316-InvalidCast.ll b/rc1/test/Isl/CodeGen/20120316-InvalidCast.ll
new file mode 100644
index 0000000..c95545f
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20120316-InvalidCast.ll
@@ -0,0 +1,20 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %s
+
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32"
+target triple = "hexagon-unknown-linux-gnu"
+
+define void @fixup_gotos(i32* %A, i32* %data) nounwind {
+entry:
+  br label %if
+
+if:
+  %cond = icmp eq i32* %A, null
+  br i1 %cond, label %last, label %then
+
+then:
+  store i32 1, i32* %data, align 4
+  br label %last
+
+last:
+  ret void
+}
diff --git a/rc1/test/Isl/CodeGen/20120403-RHS-type-mismatch.ll b/rc1/test/Isl/CodeGen/20120403-RHS-type-mismatch.ll
new file mode 100755
index 0000000..65f6240
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20120403-RHS-type-mismatch.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly -polly-codegen-isl %s
+
+; We just check that this compilation does not crash.
+
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32"
+target triple = "hexagon-unknown-linux-gnu"
+
+define void @init() nounwind {
+entry:
+  %hi.129.reg2mem = alloca i64
+  br label %for.body
+
+for.cond5.preheader:                              ; preds = %for.body
+  br label %for.body7
+
+for.body:                                         ; preds = %for.body, %entry
+  br i1 undef, label %for.body, label %for.cond5.preheader
+
+for.body7:                                        ; preds = %for.body7, %for.cond5.preheader
+  %i.128 = phi i64 [ 0, %for.cond5.preheader ], [ %inc17, %for.body7 ]
+  %inc17 = add nsw i64 %i.128, 1
+  store i64 undef, i64* %hi.129.reg2mem
+  br i1 false, label %for.body7, label %for.end18
+
+for.end18:                                        ; preds = %for.body7
+  unreachable
+}
diff --git a/rc1/test/Isl/CodeGen/20130211-getNumberOfIterations.ll b/rc1/test/Isl/CodeGen/20130211-getNumberOfIterations.ll
new file mode 100644
index 0000000..ce2a984
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20130211-getNumberOfIterations.ll
@@ -0,0 +1,29 @@
+; RUN: opt %loadPolly -polly-codegen-isl -polly-vectorizer=polly < %s
+; RUN: opt %loadPolly -polly-codegen-isl -polly-vectorizer=bb < %s
+
+; This test case checks that the polly vectorizer does not crash when
+; calculating the number of iterations.
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@b = external global [2048 x i64], align 16
+
+define void @foo(i64 %n) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %indvar = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i64 %indvar, %n
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds [2048 x i64]* @b, i64 0, i64 %indvar
+  store i64 1, i64* %arrayidx
+  %inc = add nsw i64 %indvar, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
diff --git a/rc1/test/Isl/CodeGen/20130221.ll b/rc1/test/Isl/CodeGen/20130221.ll
new file mode 100644
index 0000000..7b6ee2f
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/20130221.ll
@@ -0,0 +1,21 @@
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-codegen-scev < %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @list_sequence(i32* %A) {
+entry:
+  br label %for.body
+
+for.body:
+  %i = phi i32 [ 0, %entry ], [ %i.inc, %for.body ]
+  %i.inc = add nsw i32 %i, 1
+  %cmp5 = icmp slt i32 %i.inc, 2
+  br i1 %cmp5, label %for.body, label %for.next
+
+for.next:
+  store i32 %i.inc, i32* %A
+  br label %for.end
+
+for.end:
+  ret void
+}
diff --git a/rc1/test/Isl/CodeGen/LoopParallelMD/single_loop_param_parallel.ll b/rc1/test/Isl/CodeGen/LoopParallelMD/single_loop_param_parallel.ll
new file mode 100644
index 0000000..4ad9158
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/LoopParallelMD/single_loop_param_parallel.ll
@@ -0,0 +1,102 @@
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=SEQUENTIAL
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-codegen-scev < %s | FileCheck %s -check-prefix=SEQUENTIAL-SCEV
+; RUN: opt %loadPolly -polly-codegen-isl -polly-ast-detect-parallel -S < %s | FileCheck %s -check-prefix=PARALLEL
+; RUN: opt %loadPolly -polly-codegen-isl -polly-ast-detect-parallel -S -polly-codegen-scev < %s | FileCheck %s -check-prefix=PARALLEL-SCEV
+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"
+
+; This is a trivially parallel loop. We just use it to ensure that we actually
+; emit the right information.
+;
+; for (i = 0; i < n; i++)
+;   A[i] = 1;
+;
+@A = common global [1024 x i32] zeroinitializer
+define void @test-one(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.backedge ]
+  %exitcond = icmp ne i64 %i, %n
+  br i1 %exitcond, label %loop.body, label %ret
+
+loop.body:
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %i
+  store i32 1, i32* %scevgep
+  br label %loop.backedge
+
+loop.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.header
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; SEQUENTIAL: @test-one
+; SEQUENTIAL-NOT: !llvm.mem.parallel_loop_access
+; SEQUENTIAL-NOT: !llvm.loop !0
+; SEQUENTIAL-SCEV: @test-one
+; SEQUENTIAL-SCEV-NOT: !llvm.mem.parallel_loop_access
+; SEQUENTIAL-SCEV-NOT: !llvm.loop
+
+; PARALLEL: @test-one
+; PARALLEL: store i32 1, i32* %p_scevgep, !llvm.mem.parallel_loop_access !0
+; PARALLEL:  br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit, !llvm.loop !0
+; PARALLEL-SCEV: @test-one
+; PARALLEL-SCEV: store i32 1, i32* %scevgep1, !llvm.mem.parallel_loop_access !0
+; PARALLEL-SCEV:  br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit, !llvm.loop !0
+
+; This loop has memory dependences that require at least a simple dependence
+; analysis to detect the parallelism.
+;
+; for (i = 0; i < n; i++)
+;   A[2 * i] = A[2 * i + 1];
+;
+define void @test-two(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.backedge ]
+  %exitcond = icmp ne i64 %i, %n
+  br i1 %exitcond, label %loop.body, label %ret
+
+loop.body:
+  %loadoffset1 = mul nsw i64 %i, 2
+  %loadoffset2 = add nsw i64 %loadoffset1, 1
+  %scevgepload = getelementptr [1024 x i32]* @A, i64 0, i64 %loadoffset2
+  %val = load i32* %scevgepload
+  %storeoffset = mul i64 %i, 2
+  %scevgepstore = getelementptr [1024 x i32]* @A, i64 0, i64 %storeoffset
+  store i32 %val, i32* %scevgepstore
+  br label %loop.backedge
+
+loop.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.header
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; SEQUENTIAL: @test-two
+; SEQUENTIAL-NOT: !llvm.mem.parallel_loop_access
+; SEQUENTIAL-NOT: !llvm.loop !0
+; SEQUENTIAL-SCEV: @test-two
+; SEQUENTIAL-SCEV-NOT: !llvm.mem.parallel_loop_access
+; SEQUENTIAL-SCEV-NOT: !llvm.loop
+
+; PARALLEL: @test-two
+; PARALLEL: %val_p_scalar_ = load i32* %p_scevgepload, !llvm.mem.parallel_loop_access !1
+; PARALLEL: store i32 %val_p_scalar_, i32* %p_scevgepstore, !llvm.mem.parallel_loop_access !1
+; PARALLEL: br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit, !llvm.loop !1
+; PARALLEL-SCEV: @test-two
+; PARALLEL-SCEV: %val_p_scalar_ = load i32* %scevgep, !llvm.mem.parallel_loop_access !1
+; PARALLEL-SCEV: store i32 %val_p_scalar_, i32* %scevgep1, !llvm.mem.parallel_loop_access !1
+; PARALLEL-SCEV:  br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit, !llvm.loop !1
diff --git a/rc1/test/Isl/CodeGen/PHIInExit.ll b/rc1/test/Isl/CodeGen/PHIInExit.ll
new file mode 100644
index 0000000..8afccb9
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/PHIInExit.ll
@@ -0,0 +1,104 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %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..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
+}
+
+define i32 @pthread_once(i32*, void ()*) {
+  ret i32 0
+}
+
+define i8* @pthread_getspecific(i32) {
+  ret i8* null
+}
+
+define i32 @pthread_setspecific(i32, i8*) {
+  ret i32 0
+}
+
+define i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) {
+  ret i32 0
+}
+
+define i32 @pthread_cancel(i64) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_lock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_trylock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_unlock(%union.pthread_mutex_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_key_create(i32*, void (i8*)*) {
+  ret i32 0
+}
+
+define i32 @pthread_key_delete(i32) {
+  ret i32 0
+}
+
+define i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*) {
+  ret i32 0
+}
+
+define i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32) {
+  ret i32 0
+}
+
+define i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*) {
+  ret i32 0
+}
diff --git a/rc1/test/Isl/CodeGen/constant_condition.ll b/rc1/test/Isl/CodeGen/constant_condition.ll
new file mode 100644
index 0000000..181ec3e
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/constant_condition.ll
@@ -0,0 +1,56 @@
+;RUN: opt %loadPolly %defaultOpts -polly-detect-scops-in-regions-without-loops -polly-detect-scops-in-functions-without-loops -polly-ast -analyze < %s | FileCheck %s
+
+;#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];
+;}
+
+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
+}
+
+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();
diff --git a/rc1/test/Isl/CodeGen/create-conditional-scop.ll b/rc1/test/Isl/CodeGen/create-conditional-scop.ll
new file mode 100644
index 0000000..3e3c52a
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/create-conditional-scop.ll
@@ -0,0 +1,29 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl -verify-loop-info < %s -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32"
+target triple = "hexagon-unknown-linux-gnu"
+
+; This test case used to fail, because we did not add the newly generated basic
+; block %polly.start as a basic block to the surrounding loop.
+define void @foo() nounwind {
+entry:
+  br i1 undef, label %while.cond14.preheader, label %for.body7.single_entry.single_entry
+
+while.cond14.preheader:                           ; preds = %for.inc12, %for.body7.single_entry.single_entry, %entry
+  ret void
+
+for.body7.single_entry.single_entry:              ; preds = %for.inc12, %entry
+  br i1 undef, label %while.cond14.preheader, label %while.body
+
+while.body:                                       ; preds = %while.body, %for.body7.single_entry.single_entry
+  %indvar35 = phi i32 [ %0, %while.body ], [ 0, %for.body7.single_entry.single_entry ]
+  %0 = add i32 %indvar35, 1
+  %exitcond2 = icmp eq i32 %0, 0
+  br i1 %exitcond2, label %for.inc12, label %while.body
+
+for.inc12:                                        ; preds = %while.body
+  br i1 undef, label %while.cond14.preheader, label %for.body7.single_entry.single_entry
+}
+
+; CHECK: polly.split_new_and_old
+; CHECK: br i1 true, label %polly.start, label %while.body
diff --git a/rc1/test/Isl/CodeGen/debug-intrinsics.ll b/rc1/test/Isl/CodeGen/debug-intrinsics.ll
new file mode 100644
index 0000000..026a9ac
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/debug-intrinsics.ll
@@ -0,0 +1,80 @@
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define void @foo(float* %A, i64 %N) #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  tail call void @llvm.dbg.value(metadata !{float* %A}, i64 0, metadata !14), !dbg !15
+  tail call void @llvm.dbg.value(metadata !{i64 %N}, i64 0, metadata !16), !dbg !15
+  tail call void @llvm.dbg.value(metadata !17, i64 0, metadata !18), !dbg !20
+  %cmp1 = icmp sgt i64 %N, 0, !dbg !20
+  br i1 %cmp1, label %for.body.lr.ph, label %for.end, !dbg !20
+
+for.body.lr.ph:                                   ; preds = %entry.split
+  br label %for.body, !dbg !20
+
+for.body:                                         ; preds = %for.body.lr.ph, %for.body
+  %0 = phi i64 [ 0, %for.body.lr.ph ], [ %1, %for.body ], !dbg !21
+  %arrayidx = getelementptr float* %A, i64 %0, !dbg !21
+  %conv = sitofp i64 %0 to float, !dbg !21
+  store float %conv, float* %arrayidx, align 4, !dbg !21
+  %1 = add nsw i64 %0, 1, !dbg !20
+  tail call void @llvm.dbg.value(metadata !{i64 %1}, i64 0, metadata !18), !dbg !20
+  %exitcond = icmp ne i64 %1, %N, !dbg !20
+  br i1 %exitcond, label %for.body, label %for.cond.for.end_crit_edge, !dbg !20
+
+for.cond.for.end_crit_edge:                       ; preds = %for.body
+  br label %for.end, !dbg !20
+
+for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry.split
+  ret void, !dbg !22
+}
+
+; CHECK: polly.split_new_and_old:
+
+; CHECK: tail call void @llvm.dbg.value
+; CHECK: tail call void @llvm.dbg.value
+; CHECK: tail call void @llvm.dbg.value
+; CHECK: tail call void @llvm.dbg.value
+; CHECK-NOT: tail call void @llvm.dbg.value
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata) #1
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata) #1
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!11, !12}
+!llvm.ident = !{!13}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/grosser/Projects/polly/git/tools/polly/loop.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"loop.c", metadata !"/home/grosser/Projects/polly/git/tools/polly"}
+!2 = metadata !{}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo", metadata !"foo", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (float*, i64)* @foo, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [/home/grosser/Projects/polly/git/tools/polly/loop.c]
+!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{null, metadata !8, metadata !10}
+!8 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from float]
+!9 = metadata !{i32 786468, null, null, metadata !"float", i32 0, i64 32, i64 32, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] [float] [line 0, size 32, align 32, offset 0, enc DW_ATE_float]
+!10 = metadata !{i32 786468, null, null, metadata !"long int", i32 0, i64 64, i64 64, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [long int] [line 0, size 64, align 64, offset 0, enc DW_ATE_signed]
+!11 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!12 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
+!13 = metadata !{metadata !"clang version 3.5 "}
+!14 = metadata !{i32 786689, metadata !4, metadata !"A", metadata !5, i32 16777217, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [A] [line 1]
+!15 = metadata !{i32 1, i32 0, metadata !4, null}
+!16 = metadata !{i32 786689, metadata !4, metadata !"N", metadata !5, i32 33554433, metadata !10, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [N] [line 1]
+!17 = metadata !{i64 0}
+!18 = metadata !{i32 786688, metadata !19, metadata !"i", metadata !5, i32 2, metadata !10, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [i] [line 2]
+!19 = metadata !{i32 786443, metadata !1, metadata !4, i32 2, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [/home/grosser/Projects/polly/git/tools/polly/loop.c]
+!20 = metadata !{i32 2, i32 0, metadata !19, null}
+!21 = metadata !{i32 3, i32 0, metadata !19, null}
+!22 = metadata !{i32 4, i32 0, metadata !4, null}
diff --git a/rc1/test/Isl/CodeGen/loop_with_condition.ll b/rc1/test/Isl/CodeGen/loop_with_condition.ll
new file mode 100644
index 0000000..29eb284
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/loop_with_condition.ll
@@ -0,0 +1,175 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+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 (int c1 = 0; c1 <= 1023; c1 += 1) {
+; CHECK:   if (c1 >= 513) {
+; CHECK:     Stmt_5(c1);
+; CHECK:   } else
+; CHECK:     Stmt_4(c1);
+; CHECK:   Stmt_6(c1);
+; CHECK: }
diff --git a/rc1/test/Isl/CodeGen/loop_with_condition_2.ll b/rc1/test/Isl/CodeGen/loop_with_condition_2.ll
new file mode 100644
index 0000000..ce297db
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/loop_with_condition_2.ll
@@ -0,0 +1,137 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -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 [1024 x i32] zeroinitializer, align 16
+@B = common global [1024 x i32] zeroinitializer, align 16
+
+define void @loop_with_condition(i32 %m) nounwind {
+entry:
+  fence seq_cst
+  %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
+  fence seq_cst
+  ret void
+}
+
+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 (int c1 = 0; c1 <= 1023; c1 += 1) {
+; CHECK:   if (c1 >= m + 1025) {
+; CHECK:     Stmt_if_else(c1);
+; CHECK:   } else
+; CHECK:     Stmt_if_then(c1);
+; CHECK:   Stmt_if_end(c1);
+; CHECK: }
diff --git a/rc1/test/Isl/CodeGen/loop_with_condition_ineq.ll b/rc1/test/Isl/CodeGen/loop_with_condition_ineq.ll
new file mode 100644
index 0000000..3066b8e
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/loop_with_condition_ineq.ll
@@ -0,0 +1,177 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+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 (int c1 = 0; c1 <= 1023; c1 += 1) {
+; CHECK:   if (c1 >= 513) {
+; CHECK:     Stmt_4(c1);
+; CHECK:   } else if (c1 <= 511) {
+; CHECK:     Stmt_4(c1);
+; CHECK:   } else
+; CHECK:     Stmt_5(512);
+; CHECK:   Stmt_6(c1);
+; CHECK: }
diff --git a/rc1/test/Isl/CodeGen/loop_with_condition_nested.ll b/rc1/test/Isl/CodeGen/loop_with_condition_nested.ll
new file mode 100644
index 0000000..d6b7103
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/loop_with_condition_nested.ll
@@ -0,0 +1,218 @@
+; RUN: opt %loadPolly -basicaa -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl -loops -analyze < %s | FileCheck %s -check-prefix=LOOPS
+
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  ret void
+}
+
+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 (int c1 = 0; c1 <= 1023; c1 += 1) {
+; CHECK:   if (c1 <= 20) {
+; CHECK:     Stmt_7(c1);
+; CHECK:   } else if (c1 <= 512)
+; CHECK:     Stmt_6(c1);
+; CHECK:   Stmt_9(c1);
+; CHECK: }
+
+; LOOPS: Printing analysis 'Natural Loop Information' for function 'loop_with_condition':
+; LOOPS: Loop at depth 1 containing: %1<header><exiting>,%2,%4,%7,%6,%8,%9,%10<latch>
+; LOOPS: Loop at depth 1 containing:
+; LOOPS: %polly.loop_header<header>,%polly.cond,%polly.merge,%polly.then,%polly.else,%polly.stmt.,%polly.cond3,%polly.merge4,%polly.then5,%polly.else6,%polly.stmt.7,%polly.stmt.8<latch><exiting>
diff --git a/rc1/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll b/rc1/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll
new file mode 100644
index 0000000..3bc8051
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/multidim_2d_parametric_array_static_loop_bounds.ll
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Derived from the following code:
+;
+; void foo(long n, long m, double A[n][m]) {
+;   for (long i = 0; i < 100; i++)
+;     for (long j = 0; j < 150; j++)
+;       A[i][j] = 1.0;
+; }
+
+; CHECK: polly.split_new_and_old:
+; CHECK: %0 = icmp sge i64 %m, 150
+; CHECK: %1 = select i1 %0, i64 1, i64 0
+; CHECK: %2 = icmp ne i64 0, %1
+; CHECK: br i1 %2, label %polly.start, label %for.i
+
+define void @foo(i64 %n, i64 %m, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  %tmp = mul nsw i64 %i, %m
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j ]
+  %vlaarrayidx.sum = add i64 %j, %tmp
+  %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
+  store double 1.0, double* %arrayidx
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, 150
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, 100
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/Isl/CodeGen/reduction.ll b/rc1/test/Isl/CodeGen/reduction.ll
new file mode 100644
index 0000000..aa51afa
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/reduction.ll
@@ -0,0 +1,89 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl -S < %s 2>&1 | not FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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]
+  fence seq_cst
+  %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
+
+; CHECK:  Could not generate independent blocks
diff --git a/rc1/test/Isl/CodeGen/reduction_2.ll b/rc1/test/Isl/CodeGen/reduction_2.ll
new file mode 100644
index 0000000..c1daa33
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/reduction_2.ll
@@ -0,0 +1,93 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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 (int c1 = 0; c1 <= 1018; c1 += 1)
+; CHECK:   Stmt_for_body(c1);
diff --git a/rc1/test/Isl/CodeGen/reduction_simple_binary.ll b/rc1/test/Isl/CodeGen/reduction_simple_binary.ll
new file mode 100644
index 0000000..e9bc1f1
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/reduction_simple_binary.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s
+;
+; CHECK: pragma simd reduction
+; CHECK: pragma omp parallel for reduction
+;
+; int prod;
+; void f() {
+;   for (int i = 0; i < 100; i++)
+;     prod *= i;
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+@prod = common global i32 0, align 4
+
+define void @f() {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i1.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i1.0, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %add2 = add nsw i32 %i1.0, 3
+  %tmp1 = load i32* @prod, align 4
+  %mul3 = mul nsw i32 %tmp1, %add2
+  store i32 %mul3, i32* @prod, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %i1.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll b/rc1/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll
new file mode 100644
index 0000000..017f047
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/run-time-condition-with-scev-parameters.ll
@@ -0,0 +1,28 @@
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-delinearize < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-delinearize -polly-codegen-scev < %s | FileCheck %s
+
+; CHECK: %1 = zext i32 %n to i64
+; CHECK: %2 = icmp sge i64 %1, 1
+; CHECK: %3 = select i1 %2, i64 1, i64 0
+; CHECK: %4 = icmp ne i64 0, %3
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @init_array(i32 %n, double* %data) {
+entry:
+  %0 = zext i32 %n to i64
+  br label %for.body4
+
+for.body4:                                        ; preds = %for.body4, %entry
+  %indvar1 = phi i64 [ %indvar.next2, %for.body4 ], [ 0, %entry ]
+  %.moved.to.for.body4 = mul i64 %0, %indvar1
+  %1 = add i64 %.moved.to.for.body4, 0
+  %arrayidx7 = getelementptr double* %data, i64 %1
+  store double undef, double* %arrayidx7, align 8
+  %indvar.next2 = add i64 %indvar1, 1
+  br i1 false, label %for.body4, label %for.end10
+
+for.end10:                                        ; preds = %for.body4
+  ret void
+}
diff --git a/rc1/test/Isl/CodeGen/run-time-condition.ll b/rc1/test/Isl/CodeGen/run-time-condition.ll
new file mode 100644
index 0000000..9d57630
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/run-time-condition.ll
@@ -0,0 +1,31 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl -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-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @run-time-condition(i16* noalias %A, i16* noalias %B) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %indvar = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i64 %indvar, 1024
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i16* %B, i64 0
+  %load = load i16* %arrayidx
+  %add10 = add nsw i16 %load, 1
+  %arrayidx13 = getelementptr inbounds i16* %A, i64 %indvar
+  store i16 %add10, i16* %arrayidx13, align 2
+  %inc = add nsw i64 %indvar, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
+; The trivial case, no run-time checks required.
+;
+; CHECK: polly.split_new_and_old:
+; CHECK:  br i1 true, label %polly.start, label %for.cond
diff --git a/rc1/test/Isl/CodeGen/scev.ll b/rc1/test/Isl/CodeGen/scev.ll
new file mode 100644
index 0000000..5511dfc
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/scev.ll
@@ -0,0 +1,22 @@
+; RUN: opt %loadPolly %defaultOpts -polly-detect < %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 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
+}
diff --git a/rc1/test/Isl/CodeGen/sequential_loops.ll b/rc1/test/Isl/CodeGen/sequential_loops.ll
new file mode 100644
index 0000000..538e454
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/sequential_loops.ll
@@ -0,0 +1,138 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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: {
+; CHECK:   for (int c1 = 0; c1 <= 511; c1 += 1)
+; CHECK:     Stmt_bb2(c1);
+; CHECK:   for (int c1 = 0; c1 <= 511; c1 += 1)
+; CHECK:     Stmt_bb6(c1);
+; CHECK: }
diff --git a/rc1/test/Isl/CodeGen/simple_loop_non_single_exit.ll b/rc1/test/Isl/CodeGen/simple_loop_non_single_exit.ll
new file mode 100644
index 0000000..ab4c2b9
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_loop_non_single_exit.ll
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -polly-codegen-isl -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CHECK-CODE
+
+; void f(long A[], long N) {
+;   long i;
+;   if (true)
+;     for (i = 0; i < N; ++i)
+;       A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br label %next
+
+next:
+  br i1 true, label %for.i, label %return
+
+for.i:
+  %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Create LLVM-IR from SCoPs' for region: 'next => polly.merge_new_and_old'
+; CHECK-CODE: polly.split_new_and_old
+; CHECK-CODE: polly.merge_new_and_old
diff --git a/rc1/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll b/rc1/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll
new file mode 100644
index 0000000..4f09802
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_loop_non_single_exit_2.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-codegen-isl -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CHECK-CODE
+
+; void f(long A[], long N) {
+;   long i;
+;   if (true)
+;     if (true)
+;       for (i = 0; i < N; ++i)
+;         A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br i1 true, label %next, label %return
+
+next:
+  br i1 true, label %for.i, label %return
+
+for.i:
+  %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Create LLVM-IR from SCoPs' for region: 'for.i => return'
+; CHECK-CODE: polly.split_new_and_old
+; CHECK-CODE: polly.merge_new_and_old
diff --git a/rc1/test/Isl/CodeGen/simple_non_single_entry.ll b/rc1/test/Isl/CodeGen/simple_non_single_entry.ll
new file mode 100644
index 0000000..c0c90ec
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_non_single_entry.ll
@@ -0,0 +1,71 @@
+; RUN: opt %loadPolly -polly-detect-scops-in-regions-without-loops -polly-codegen-isl -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect-scops-in-regions-without-loops -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CHECK-CODE
+
+; void f(long A[], long N) {
+;   long i;
+;
+;  if (true){
+;    i = 0;
+;    goto next;
+;  }else{
+;    i = 1;
+;    goto next;
+; }
+;
+; next:
+;  if (true)
+;    goto for.i;
+;  else
+;    goto for.i;
+;
+; for.i:
+;   for (i = 0; i < N; ++i)
+;     A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br i1 true, label %then1, label %else1
+
+then1:
+  br label %next
+
+else1:
+  br label %next
+
+next:
+  br i1 true, label %then, label %else
+
+then:
+  br label %for.i.head
+
+else:
+  br label %for.i.head
+
+for.i.head:
+  br label %for.i.head1
+
+for.i.head1:
+  br label %for.i
+
+for.i:
+  %indvar = phi i64 [ 0, %for.i.head1], [ %indvar.next, %for.i ]
+  fence seq_cst
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Create LLVM-IR from SCoPs' for region: 'next.split => polly.merge_new_and_old'
+; CHECK-CODE: polly.split_new_and_old
+; CHECK-CODE: polly.merge_new_and_old
diff --git a/rc1/test/Isl/CodeGen/simple_nonaffine_loop.ll b/rc1/test/Isl/CodeGen/simple_nonaffine_loop.ll
new file mode 100644
index 0000000..5f88cce
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_nonaffine_loop.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -polly-ast -polly-allow-nonaffine -analyze < %s | FileCheck %s
+
+;#include <stdio.h>
+;#include <stdlib.h>
+;#include <math.h>
+;
+;int main()
+;{
+;	int A[1024*1024];
+;	int i;
+;	for (i = 0; i < 1024; i++)
+;		A[i*i] = 2*i;
+;
+;	printf("Random Value: %d", A[rand() % 1024*1024]);
+;
+;	return 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-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
+@.str = private unnamed_addr constant [17 x i8] c"Random Value: %d\00", align 1
+
+define i32 @main() nounwind uwtable ssp {
+entry:
+  %A = alloca [1048576 x i32], align 16
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %0 = phi i32 [ 0, %entry.split ], [ %1, %for.body ]
+  %mul = mul i32 %0, 2
+  %mul1 = mul nsw i32 %0, %0
+  %idxprom1 = zext i32 %mul1 to i64
+  %arrayidx = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom1
+  store i32 %mul, i32* %arrayidx, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  %call = call i32 @rand() nounwind
+  %rem = srem i32 %call, 1024
+  %mul2 = shl nsw i32 %rem, 10
+  %idxprom3 = sext i32 %mul2 to i64
+  %arrayidx4 = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom3
+  %2 = load i32* %arrayidx4, align 16
+  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i64 0, i64 0), i32 %2) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @rand()
+
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:   Stmt_for_body(c1);
diff --git a/rc1/test/Isl/CodeGen/simple_vec_assign_scalar.ll b/rc1/test/Isl/CodeGen/simple_vec_assign_scalar.ll
new file mode 100644
index 0000000..5e388bf
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_assign_scalar.ll
@@ -0,0 +1,65 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %vector-opt -dce -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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: %p_scevgep1.moved.to.bb3 = getelementptr [1024 x float]* @A, i64 0, i64 0
+; CHECK: %p_scevgep.moved.to.bb3 = getelementptr [1024 x float]* @B, i64 0, i64 0
+; CHECK: %vector_ptr = bitcast float* %p_scevgep1.moved.to.bb3 to <4 x float>*
+; CHECK: %tmp_p_vec_full = load <4 x float>* %vector_ptr, align 8
+; 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>
+; CHECK: %vector_ptr7 = bitcast float* %p_scevgep.moved.to.bb3 to <4 x float>*
+; CHECK: store <4 x float> %tmp4p_vec, <4 x float>* %vector_ptr7, align 8
+
diff --git a/rc1/test/Isl/CodeGen/simple_vec_assign_scalar_2.ll b/rc1/test/Isl/CodeGen/simple_vec_assign_scalar_2.ll
new file mode 100644
index 0000000..396cc95
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_assign_scalar_2.ll
@@ -0,0 +1,66 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %vector-opt -dce -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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 %{{[^,]+}}, i32 0
+; CHECK: insertelement <4 x float> %0, float %{{[^,]+}}, i32 1
+; CHECK: insertelement <4 x float> %1, float %{{[^,]+}}, i32 2
+; CHECK: insertelement <4 x float> %2, float %{{[^,]+}}, i32 3
+; CHECK: fadd <4 x float> %tmp_p_vec_full, %3
+
diff --git a/rc1/test/Isl/CodeGen/simple_vec_call.ll b/rc1/test/Isl/CodeGen/simple_vec_call.ll
new file mode 100644
index 0000000..6a77824
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_call.ll
@@ -0,0 +1,43 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl %vector-opt -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
+
+declare float @foo(float) readnone
+
+define void @simple_vec_call() nounwind {
+entry:
+  br label %body
+
+body:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar_next, %body ]
+  %scevgep = getelementptr [1024 x float]* @B, i64 0, i64 %indvar
+  %value = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+  %result = tail call float @foo(float %value) nounwind
+  store float %result, float* %scevgep, align 4
+  %indvar_next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar_next, 4
+  br i1 %exitcond, label %return, label %body
+
+return:
+  ret void
+}
+
+; CHECK: %value_p_splat_one = load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*), align 8
+; CHECK: %value_p_splat = shufflevector <1 x float> %value_p_splat_one, <1 x float> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK: %0 = extractelement <4 x float> %value_p_splat, i32 0
+; CHECK: %1 = extractelement <4 x float> %value_p_splat, i32 1
+; CHECK: %2 = extractelement <4 x float> %value_p_splat, i32 2
+; CHECK: %3 = extractelement <4 x float> %value_p_splat, i32 3
+; CHECK: [[RES1:%[a-zA-Z0-9_]+]] = tail call float @foo(float %0) [[NUW:#[0-9]+]]
+; CHECK: [[RES2:%[a-zA-Z0-9_]+]] = tail call float @foo(float %1) [[NUW]]
+; CHECK: [[RES3:%[a-zA-Z0-9_]+]] = tail call float @foo(float %2) [[NUW]]
+; CHECK: [[RES4:%[a-zA-Z0-9_]+]] = tail call float @foo(float %3) [[NUW]]
+; CHECK: %4 = insertelement <4 x float> undef, float [[RES1]], i32 0
+; CHECK: %5 = insertelement <4 x float> %4, float [[RES2]], i32 1
+; CHECK: %6 = insertelement <4 x float> %5, float [[RES3]], i32 2
+; CHECK: %7 = insertelement <4 x float> %6, float [[RES4]], i32 3
+; CHECK:  store <4 x float> %7
+; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/rc1/test/Isl/CodeGen/simple_vec_call_2.ll b/rc1/test/Isl/CodeGen/simple_vec_call_2.ll
new file mode 100644
index 0000000..850f939
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_call_2.ll
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl %vector-opt -polly-codegen-scev=false -dce -S < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl %vector-opt -polly-codegen-scev=true -dce -S < %s | FileCheck %s -check-prefix=CHECK-SCEV
+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
+
+declare float** @foo(float) readnone
+
+define void @simple_vec_call() nounwind {
+entry:
+  br label %body
+
+body:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar_next, %body ]
+  %scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 %indvar
+  %value = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+  %result = tail call float** @foo(float %value) nounwind
+  store float** %result, float*** %scevgep, align 4
+  %indvar_next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar_next, 4
+  br i1 %exitcond, label %return, label %body
+
+return:
+  ret void
+}
+
+; CHECK: %p_scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 0
+; CHECK: %value_p_splat_one = load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*), align 8
+; CHECK: %value_p_splat = shufflevector <1 x float> %value_p_splat_one, <1 x float> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK: %0 = extractelement <4 x float> %value_p_splat, i32 0
+; CHECK: %1 = extractelement <4 x float> %value_p_splat, i32 1
+; CHECK: %2 = extractelement <4 x float> %value_p_splat, i32 2
+; CHECK: %3 = extractelement <4 x float> %value_p_splat, i32 3
+; CHECK: [[RES1:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %0) [[NUW:#[0-9]+]]
+; CHECK: [[RES2:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %1) [[NUW]]
+; CHECK: [[RES3:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %2) [[NUW]]
+; CHECK: [[RES4:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %3) [[NUW]]
+; CHECK: %4 = insertelement <4 x float**> undef, float** %p_result, i32 0
+; CHECK: %5 = insertelement <4 x float**> %4, float** %p_result4, i32 1
+; CHECK: %6 = insertelement <4 x float**> %5, float** %p_result5, i32 2
+; CHECK: %7 = insertelement <4 x float**> %6, float** %p_result6, i32 3
+; CHECK: %vector_ptr = bitcast float*** %p_scevgep to <4 x float**>*
+; CHECK: store <4 x float**> %7, <4 x float**>* %vector_ptr, align 8
+; CHECK: attributes [[NUW]] = { nounwind }
+
+; CHECK-SCEV: %value_p_splat_one = load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*), align 8
+; CHECK-SCEV: %value_p_splat = shufflevector <1 x float> %value_p_splat_one, <1 x float> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK-SCEV: %0 = extractelement <4 x float> %value_p_splat, i32 0
+; CHECK-SCEV: %1 = extractelement <4 x float> %value_p_splat, i32 1
+; CHECK-SCEV: %2 = extractelement <4 x float> %value_p_splat, i32 2
+; CHECK-SCEV: %3 = extractelement <4 x float> %value_p_splat, i32 3
+; CHECK-SCEV: [[RES1:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %0) [[NUW:#[0-9]+]]
+; CHECK-SCEV: [[RES2:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %1) [[NUW]]
+; CHECK-SCEV: [[RES3:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %2) [[NUW]]
+; CHECK-SCEV: [[RES4:%[a-zA-Z0-9_]+]] = tail call float** @foo(float %3) [[NUW]]
+; CHECK-SCEV: %4 = insertelement <4 x float**> undef, float** %p_result, i32 0
+; CHECK-SCEV: %5 = insertelement <4 x float**> %4, float** %p_result1, i32 1
+; CHECK-SCEV: %6 = insertelement <4 x float**> %5, float** %p_result2, i32 2
+; CHECK-SCEV: %7 = insertelement <4 x float**> %6, float** %p_result3, i32 3
+; CHECK-SCEV: store <4 x float**> %7, <4 x float**>* bitcast ([1024 x float**]* @B to <4 x float**>*), align
+; CHECK-SCEV: attributes [[NUW]] = { nounwind }
diff --git a/rc1/test/Isl/CodeGen/simple_vec_cast.ll b/rc1/test/Isl/CodeGen/simple_vec_cast.ll
new file mode 100644
index 0000000..6d0ac9c
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_cast.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl %vector-opt -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 double] zeroinitializer, align 16
+
+define void @simple_vec_const() nounwind {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb3, %bb
+  %indvar = phi i64 [ %indvar.next, %bb3 ], [ 0, %bb ]
+  %scevgep = getelementptr [1024 x double]* @B, i64 0, i64 %indvar
+  %exitcond = icmp ne i64 %indvar, 4
+  br i1 %exitcond, label %bb2, label %bb4
+
+bb2:                                              ; preds = %bb1
+  %tmp = load float* getelementptr inbounds ([1024 x float]* @A, i64 0, i64 0), align 16
+  %tmp2 = fpext float %tmp to double
+  store double %tmp2, double* %scevgep, align 4
+  br label %bb3
+
+bb3:                                              ; preds = %bb2
+  %indvar.next = add i64 %indvar, 1
+  br label %bb1
+
+bb4:                                              ; preds = %bb1
+  ret void
+}
+
+; CHECK: %p_scevgep.moved.to.bb2 = getelementptr [1024 x double]* @B, i64 0, i64 0
+; CHECK: %tmp_p_splat_one = load <1 x float>* bitcast ([1024 x float]* @A to <1 x float>*), align 8
+; CHECK: %tmp_p_splat = shufflevector <1 x float> %tmp_p_splat_one, <1 x float> %tmp_p_splat_one, <4 x i32> zeroinitializer
+; CHECK: %0 = fpext <4 x float> %tmp_p_splat to <4 x double>
+; CHECK: %vector_ptr = bitcast double* %p_scevgep.moved.to.bb2 to <4 x double>*
+; CHECK: store <4 x double> %0, <4 x double>* %vector_ptr, align 8
+
diff --git a/rc1/test/Isl/CodeGen/simple_vec_const.ll b/rc1/test/Isl/CodeGen/simple_vec_const.ll
new file mode 100644
index 0000000..1c58ba2
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_const.ll
@@ -0,0 +1,57 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %vector-opt -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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
diff --git a/rc1/test/Isl/CodeGen/simple_vec_large_width.ll b/rc1/test/Isl/CodeGen/simple_vec_large_width.ll
new file mode 100644
index 0000000..8e1cc20
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_large_width.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %vector-opt -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: [[VEC1:%[a-zA-Z0-9_]+_full]] = load <15 x float>*
+; CHECK: store <15 x float> [[VEC1]]
diff --git a/rc1/test/Isl/CodeGen/simple_vec_ptr_ptr_ty.ll b/rc1/test/Isl/CodeGen/simple_vec_ptr_ptr_ty.ll
new file mode 100644
index 0000000..5884e92
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_ptr_ptr_ty.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl %vector-opt -S -polly-codegen-scev=false < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl %vector-opt -S -polly-codegen-scev=true < %s | FileCheck %s -check-prefix=CHECK-SCEV
+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
+
+declare float @foo(float) readnone
+
+define void @simple_vec_call() nounwind {
+entry:
+  br label %body
+
+body:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar_next, %body ]
+  %scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 %indvar
+  %value = load float*** getelementptr inbounds ([1024 x float**]* @A, i64 0, i64 0), align 16
+  store float** %value, float*** %scevgep, align 4
+  %indvar_next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar_next, 4
+  br i1 %exitcond, label %return, label %body
+
+return:
+  ret void
+}
+
+; CHECK: %p_scevgep = getelementptr [1024 x float**]* @B, i64 0, i64 0
+; CHECK: %p_scevgep1 = getelementptr [1024 x float**]* @B, i64 0, i64 1
+; CHECK: %p_scevgep2 = getelementptr [1024 x float**]* @B, i64 0, i64 2
+; CHECK: %p_scevgep3 = getelementptr [1024 x float**]* @B, i64 0, i64 3
+; CHECK: %value_p_splat_one = load <1 x float**>* bitcast ([1024 x float**]* @A to <1 x float**>*), align 8
+; CHECK: %value_p_splat = shufflevector <1 x float**> %value_p_splat_one, <1 x float**> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK: %vector_ptr = bitcast float*** %p_scevgep to <4 x float**>*
+; CHECK: store <4 x float**> %value_p_splat, <4 x float**>* %vector_ptr
+
+
+; CHECK-SCEV: %value_p_splat_one = load <1 x float**>* bitcast ([1024 x float**]* @A to <1 x float**>*), align 8
+; CHECK-SCEV: %value_p_splat = shufflevector <1 x float**> %value_p_splat_one, <1 x float**> %value_p_splat_one, <4 x i32> zeroinitializer
+; CHECK-SCEV: store <4 x float**> %value_p_splat, <4 x float**>* bitcast ([1024 x float**]* @B to <4 x float**>*), align 8
diff --git a/rc1/test/Isl/CodeGen/simple_vec_stride_negative_one.ll b/rc1/test/Isl/CodeGen/simple_vec_stride_negative_one.ll
new file mode 100644
index 0000000..9741298
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_stride_negative_one.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-codegen-isl -polly-codegen-scev %vector-opt -S < %s | FileCheck %s
+
+; ModuleID = 'reverse.c'
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+;int A[100];
+;void foo() {
+;  for (int i=3; i >= 0; i--)
+;    A[i]+=1;
+;}
+
+
+@A = common global [100 x i32] zeroinitializer, align 16
+
+; Function Attrs: nounwind uwtable
+define void @foo() #0 {
+entry:
+  br label %for.body
+
+for.body:                                         ; preds = %entry, %for.body
+  %indvars.iv = phi i64 [ 3, %entry ], [ %indvars.iv.next, %for.body ]
+  %arrayidx = getelementptr inbounds [100 x i32]* @A, i64 0, i64 %indvars.iv
+  %0 = load i32* %arrayidx, align 4
+  %add = add nsw i32 %0, 1
+  store i32 %add, i32* %arrayidx, align 4
+  %indvars.iv.next = add nsw i64 %indvars.iv, -1
+  %1 = trunc i64 %indvars.iv to i32
+  %cmp = icmp sgt i32 %1, 0
+  br i1 %cmp, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  ret void
+}
+
+; CHECK: @foo
+; CHECK: [[LOAD:%[a-zA-Z0-9_]+]] = load <4 x i32>*
+; CHECK: [[REVERSE_LOAD:%[a-zA-Z0-9_]+reverse]] = shufflevector <4 x i32> [[LOAD]], <4 x i32> [[LOAD]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
diff --git a/rc1/test/Isl/CodeGen/simple_vec_stride_x.ll b/rc1/test/Isl/CodeGen/simple_vec_stride_x.ll
new file mode 100644
index 0000000..a793434
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_stride_x.ll
@@ -0,0 +1,73 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %vector-opt  -dce -S < %s | FileCheck %s
+
+;#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];
+;}
+
+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: [[LOAD1:%[a-zA-Z0-9_]+_scalar_]] = load float*
+; CHECK: [[VEC1:%[a-zA-Z0-9_]+]] = insertelement <4 x float> undef, float [[LOAD1]], i32 0
+; CHECK: [[LOAD2:%[a-zA-Z0-9_]+]] = load float*
+; CHECK: [[VEC2:%[a-zA-Z0-9_]+]] = insertelement <4 x float> [[VEC1]], float [[LOAD2]], i32 1
+; CHECK: [[LOAD3:%[a-zA-Z0-9_]+]] = load float*
+; CHECK: [[VEC3:%[a-zA-Z0-9_]+]] = insertelement <4 x float> [[VEC2]], float [[LOAD3]], i32 2
+; CHECK: [[LOAD4:%[a-zA-Z0-9_]+]] = load float*
+; CHECK: [[VEC4:%[a-zA-Z0-9_]+]] = insertelement <4 x float> [[VEC3]], float [[LOAD4]], i32 3
+; CHECK: [[EL1:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 0
+; CHECK: store float [[EL1]]
+; CHECK: [[EL2:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 1
+; CHECK: store float [[EL2]]
+; CHECK: [[EL3:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 2
+; CHECK: store float [[EL3]]
+; CHECK: [[EL4:%[a-zA-Z0-9_]+]] = extractelement <4 x float> [[VEC4]], i32 3
+; CHECK: store float [[EL4]]
diff --git a/rc1/test/Isl/CodeGen/simple_vec_two_stmts.ll b/rc1/test/Isl/CodeGen/simple_vec_two_stmts.ll
new file mode 100644
index 0000000..5606637
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/simple_vec_two_stmts.ll
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly %defaultOpts -polly-codegen-isl %vector-opt -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: [[LOAD1:%[a-zA-Z0-9_]+_full]] = load <4 x float>*
+; CHECK: store <4 x float> [[LOAD1]]
+; CHECK: [[LOAD2:%[a-zA-Z0-9_]+_full]] = load <4 x float>*
+; CHECK: store <4 x float> [[LOAD2]]
+
diff --git a/rc1/test/Isl/CodeGen/single_do_loop_int_max_iterations.ll b/rc1/test/Isl/CodeGen/single_do_loop_int_max_iterations.ll
new file mode 100644
index 0000000..1751d78
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_do_loop_int_max_iterations.ll
@@ -0,0 +1,93 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze  -S < %s | FileCheck %s
+
+;#define N 20
+;#include "limits.h"
+;#include <stdio.h>
+;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;
+;}
+
+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:
+  fence seq_cst
+  br label %do.body
+
+do.body:                                          ; preds = %do.cond, %entry
+  %0 = phi i32 [ 0, %entry ], [ %inc, %do.cond ]  ; <i32> [#uses=2]
+  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
+  fence seq_cst
+  ret void
+}
+
+define i32 @main() nounwind {
+entry:
+  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 = 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 = 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 (int c1 = 0; c1 <= 2147483646; c1 += 1)
+; CHECK:   Stmt_do_body(c1);
diff --git a/rc1/test/Isl/CodeGen/single_do_loop_int_max_iterations___%do.body---%do.end.jscop b/rc1/test/Isl/CodeGen/single_do_loop_int_max_iterations___%do.body---%do.end.jscop
new file mode 100644
index 0000000..fcd78fc
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_do_loop_int_max_iterations___%do.body---%do.end.jscop
@@ -0,0 +1,13 @@
+{
+	"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
diff --git a/rc1/test/Isl/CodeGen/single_do_loop_int_param_iterations.ll b/rc1/test/Isl/CodeGen/single_do_loop_int_param_iterations.ll
new file mode 100644
index 0000000..7c9163b
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_do_loop_int_param_iterations.ll
@@ -0,0 +1,77 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze  < %s | FileCheck %s
+; XFAIL: *
+
+;define N 20
+;#include "limits.h"
+;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;
+;}
+
+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:
+  fence seq_cst
+  %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]
+  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
+  fence seq_cst
+  ret void
+}
+
+define i32 @main() nounwind {
+entry:
+  store i32 0, i32* getelementptr inbounds ([20 x i32]* @A, i32 0, i32 0)
+  call void @bar(i32 10)
+  %tmp = 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
+
diff --git a/rc1/test/Isl/CodeGen/single_do_loop_ll_max_iterations.ll b/rc1/test/Isl/CodeGen/single_do_loop_ll_max_iterations.ll
new file mode 100644
index 0000000..8400f54
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_do_loop_ll_max_iterations.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly -polly-ast -analyze  -S < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl < %s
+
+;#define N 20
+;#include "limits.h"
+;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;
+;}
+
+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:
+  store i64 0, i64* getelementptr inbounds ([20 x i64]* @A, i32 0, i32 0)
+  fence seq_cst
+  br label %do.body
+
+do.body:                                          ; preds = %do.cond, %entry
+  %0 = phi i64 [ 0, %entry ], [ %inc, %do.cond ]  ; <i64> [#uses=2]
+  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
+  fence seq_cst
+  %tmp3 = 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
+}
+
+; CHECK: for (int c1 = 0; c1 <= 9223372036854775806; c1 += 1)
+; CHECK:   Stmt_do_body(c1);
diff --git a/rc1/test/Isl/CodeGen/single_do_loop_one_iteration.ll b/rc1/test/Isl/CodeGen/single_do_loop_one_iteration.ll
new file mode 100644
index 0000000..14a08d4
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_do_loop_one_iteration.ll
@@ -0,0 +1,70 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze  < %s | FileCheck %s
+; XFAIL: *
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK: S0(0)
diff --git a/rc1/test/Isl/CodeGen/single_do_loop_scev_replace.ll b/rc1/test/Isl/CodeGen/single_do_loop_scev_replace.ll
new file mode 100644
index 0000000..5696415
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_do_loop_scev_replace.ll
@@ -0,0 +1,95 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze < %s | FileCheck %s
+
+;#define N 20
+;#include "limits.h"
+;#include <stdio.h>
+;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;
+;}
+
+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:
+  fence seq_cst
+  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
+  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
+  fence seq_cst
+  ret void
+}
+
+define i32 @main() nounwind {
+entry:
+  call void @single_do_loop_scev_replace()
+  %tmp = load %struct._IO_FILE** @stdout          ; <%struct._IO_FILE*> [#uses=1]
+  %tmp1 = 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 = 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 (int c1 = 0; c1 <= 19; c1 += 1)
+; CHECK:   Stmt_do_cond(c1);
+
+
diff --git a/rc1/test/Isl/CodeGen/single_loop.ll b/rc1/test/Isl/CodeGen/single_loop.ll
new file mode 100644
index 0000000..4add7d3
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_loop.ll
@@ -0,0 +1,85 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze < %s | FileCheck %s
+
+;#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;
+;}
+;
+
+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 (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:   Stmt_for_body(c1);
diff --git a/rc1/test/Isl/CodeGen/single_loop_int_max_iterations.ll b/rc1/test/Isl/CodeGen/single_loop_int_max_iterations.ll
new file mode 100644
index 0000000..52ce1c3
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_loop_int_max_iterations.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze  -S < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK: for (int c1 = 0; c1 <= 2147483646; c1 += 1)
+; CHECK:   Stmt_for_body(c1);
diff --git a/rc1/test/Isl/CodeGen/single_loop_ll_max_iterations.ll b/rc1/test/Isl/CodeGen/single_loop_ll_max_iterations.ll
new file mode 100644
index 0000000..4aad4c8
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_loop_ll_max_iterations.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze  -S < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK: for (int c1 = 0; c1 <= 9223372036854775806; c1 += 1)
+; CHECK:   Stmt_for_body(c1);
diff --git a/rc1/test/Isl/CodeGen/single_loop_one_iteration.ll b/rc1/test/Isl/CodeGen/single_loop_one_iteration.ll
new file mode 100644
index 0000000..32b1289
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_loop_one_iteration.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK: Stmt_for_body(0);
diff --git a/rc1/test/Isl/CodeGen/single_loop_param.ll b/rc1/test/Isl/CodeGen/single_loop_param.ll
new file mode 100644
index 0000000..570fe03
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_loop_param.ll
@@ -0,0 +1,71 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -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-pc-linux-gnu"
+
+@A = common global [1024 x i32] zeroinitializer, align 16 ; <[1024 x i32]*> [#uses=3]
+
+define void @bar(i64 %n) nounwind {
+bb:
+  fence seq_cst
+  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
+  fence seq_cst
+  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 @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
+
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   Stmt_bb2(c1);
+
diff --git a/rc1/test/Isl/CodeGen/single_loop_zero_iterations.ll b/rc1/test/Isl/CodeGen/single_loop_zero_iterations.ll
new file mode 100644
index 0000000..48403f5
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/single_loop_zero_iterations.ll
@@ -0,0 +1,70 @@
+; RUN: opt %loadPolly %defaultOpts -polly-ast -analyze  -S < %s | FileCheck %s
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK: for region: 'for.cond => for.end.region' in function 'main':
+; CHECK-NEXT: main():
+; CHECK-NOT:   Stmt_for_body(0);
diff --git a/rc1/test/Isl/CodeGen/split_edges.ll b/rc1/test/Isl/CodeGen/split_edges.ll
new file mode 100644
index 0000000..a166b76
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/split_edges.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-codegen-isl -verify-region-info -verify-dom-info -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-pc-linux-gnu"
+
+define void @loop_with_condition() nounwind {
+bb0:
+  fence seq_cst
+  br label %bb1
+
+bb1:
+  br i1 true, label %bb2, label %bb3
+
+bb2:
+  %ind1 = phi i32 [0, %bb1], [ %inc1, %bb2]
+  %inc1 = add i32 %ind1, 1
+  %cond1 = icmp eq i32 %ind1, 32
+  br i1 %cond1, label %bb4, label %bb2
+
+bb3:
+  %ind2 = phi i32 [0, %bb1], [ %inc2, %bb3]
+  %inc2 = add i32 %ind2, 1
+  br i1 true, label %bb4, label %bb3
+
+bb4:
+  br label %bb5
+
+bb5:
+  fence seq_cst
+  ret void
+
+}
+
+; CHECK: polly.split_new_and_old
+; CHECK: polly.merge_new_and_old
diff --git a/rc1/test/Isl/CodeGen/split_edges_2.ll b/rc1/test/Isl/CodeGen/split_edges_2.ll
new file mode 100644
index 0000000..dc56e88
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/split_edges_2.ll
@@ -0,0 +1,33 @@
+; RUN: opt %loadPolly -polly-codegen-isl -verify-region-info -verify-dom-info -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-pc-linux-gnu"
+
+define void @loop_with_condition() nounwind {
+bb0:
+  fence seq_cst
+  br label %bb1
+
+bb1:
+  br label %bb2
+
+bb2:
+  %ind1 = phi i32 [0, %bb1], [ %inc1, %bb2]
+  %inc1 = add i32 %ind1, 1
+  %cond1 = icmp eq i32 %ind1, 32
+  br i1 %cond1, label %bb4, label %bb2
+
+bb4:
+  br label %bb5
+
+bb5:
+  fence seq_cst
+  ret void
+
+}
+
+; CHECK: polly.split_new_and_old
+; CHECK: polly.merge_new_and_old
+
+
+
diff --git a/rc1/test/Isl/CodeGen/test.ll b/rc1/test/Isl/CodeGen/test.ll
new file mode 100644
index 0000000..f7aa0f8
--- /dev/null
+++ b/rc1/test/Isl/CodeGen/test.ll
@@ -0,0 +1,68 @@
+; RUN: opt %loadPolly -polly-cloog -analyze  -S < %s | FileCheck %s
+; XFAIL: *
+
+;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];
+;}
+
+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: }
+
diff --git a/rc1/test/Isl/single_loop_param_less_equal.ll b/rc1/test/Isl/single_loop_param_less_equal.ll
new file mode 100644
index 0000000..fbc798e
--- /dev/null
+++ b/rc1/test/Isl/single_loop_param_less_equal.ll
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CODEGEN
+; RUN: opt %loadPolly -polly-codegen-isl -loops -analyze < %s | FileCheck %s -check-prefix=LOOPS
+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
+
+define void @bar(i64 %n) {
+start:
+  %n_plus_one = add i64 %n, 1
+  fence seq_cst
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.backedge ]
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %i
+  %exitcond = icmp ne i64 %i, %n_plus_one
+  br i1 %exitcond, label %loop.body, label %ret
+
+loop.body:
+  store i32 1, i32* %scevgep
+  br label %loop.backedge
+
+loop.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.header
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 <= n; c1 += 1)
+; CHECK:   Stmt_loop_body(c1)
+
+; CODEGEN: polly.start:
+; CODEGEN:   br label %polly.loop_if
+
+; CODEGEN: polly.loop_exit:
+; CODEGEN:   br label %polly.merge_new_and_old
+
+; CODEGEN: polly.loop_if:
+; CODEGEN:   %polly.loop_guard = icmp sle i64 0, %n
+; CODEGEN:   br i1 %polly.loop_guard, label %polly.loop_preheader, label %polly.loop_exit
+
+; CODEGEN: polly.loop_header:
+; CODEGEN:   %polly.indvar = phi i64 [ 0, %polly.loop_preheader ], [ %polly.indvar_next, %polly.stmt.loop.body ]
+; CODEGEN:   br label %polly.stmt.loop.body
+
+; CODEGEN: polly.stmt.loop.body:
+; CODEGEN:   %p_scevgep.moved.to.loop.body = getelementptr [1024 x i32]* @A, i64 0, i64 %polly.indvar
+; CODEGEN:   store i32 1, i32* %p_scevgep.moved.to.loop.body
+; CODEGEN:   %polly.indvar_next = add nsw i64 %polly.indvar, 1
+; CODEGEN:   %polly.adjust_ub = sub i64 %n, 1
+; CODEGEN:   %polly.loop_cond = icmp sle i64 %polly.indvar, %polly.adjust_ub
+; CODEGEN:   br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit
+
+; CODEGEN: polly.loop_preheader:
+; CODEGEN:   br label %polly.loop_header
+
+; LOOPS: Loop at depth 1 containing: %loop.header<header><exiting>,%loop.body,%loop.backedge<latch>
+; LOOPS: Loop at depth 1 containing: %polly.loop_header<header>,%polly.stmt.loop.body<latch><exiting>
diff --git a/rc1/test/Isl/single_loop_param_less_than.ll b/rc1/test/Isl/single_loop_param_less_than.ll
new file mode 100644
index 0000000..1497081
--- /dev/null
+++ b/rc1/test/Isl/single_loop_param_less_than.ll
@@ -0,0 +1,58 @@
+; RUN: opt %loadPolly -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CODEGEN
+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
+
+define void @bar(i64 %n) {
+start:
+  fence seq_cst
+  br label %loop.header
+
+loop.header:
+  %i = phi i64 [ 0, %start ], [ %i.next, %loop.backedge ]
+  %scevgep = getelementptr [1024 x i32]* @A, i64 0, i64 %i
+  %exitcond = icmp ne i64 %i, %n
+  br i1 %exitcond, label %loop.body, label %ret
+
+loop.body:
+  store i32 1, i32* %scevgep
+  br label %loop.backedge
+
+loop.backedge:
+  %i.next = add nsw i64 %i, 1
+  br label %loop.header
+
+ret:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 < n; c1 += 1)
+; CHECK:   Stmt_loop_body(c1)
+
+; CODEGEN: polly.start:
+; CODEGEN:   br label %polly.loop_if
+
+; CODEGEN: polly.loop_exit:
+; CODEGEN:   br label %polly.merge_new_and_old
+
+; CODEGEN: polly.loop_if:
+; CODEGEN:   %polly.loop_guard = icmp slt i64 0, %n
+; CODEGEN:   br i1 %polly.loop_guard, label %polly.loop_preheader, label %polly.loop_exit
+
+; CODEGEN: polly.loop_header:
+; CODEGEN:   %polly.indvar = phi i64 [ 0, %polly.loop_preheader ], [ %polly.indvar_next, %polly.stmt.loop.body ]
+; CODEGEN:   br label %polly.stmt.loop.body
+
+; CODEGEN: polly.stmt.loop.body:
+; CODEGEN:   %p_scevgep.moved.to.loop.body = getelementptr [1024 x i32]* @A, i64 0, i64 %polly.indvar
+; CODEGEN:   store i32 1, i32* %p_scevgep.moved.to.loop.body
+; CODEGEN:   %polly.indvar_next = add nsw i64 %polly.indvar, 1
+; CODEGEN:   %polly.adjust_ub = sub i64 %n, 1
+; CODEGEN:   %polly.loop_cond = icmp slt i64 %polly.indvar, %polly.adjust_ub
+; CODEGEN:   br i1 %polly.loop_cond, label %polly.loop_header, label %polly.loop_exit
+
+; CODEGEN: polly.loop_preheader:
+; CODEGENL   br label %polly.loop_header
diff --git a/rc1/test/Isl/single_loop_uint_max_iterations.ll b/rc1/test/Isl/single_loop_uint_max_iterations.ll
new file mode 100644
index 0000000..cff4745
--- /dev/null
+++ b/rc1/test/Isl/single_loop_uint_max_iterations.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze  < %s | FileCheck %s
+; XFAIL: *
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK:for (c2=0;
diff --git a/rc1/test/Isl/single_loop_ull_max_iterations.ll b/rc1/test/Isl/single_loop_ull_max_iterations.ll
new file mode 100644
index 0000000..acab526
--- /dev/null
+++ b/rc1/test/Isl/single_loop_ull_max_iterations.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly %defaultOpts -polly-cloog-scop -S -analyze  < %s | FileCheck %s
+; XFAIL: *
+
+;#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;
+;}
+
+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
+  fence seq_cst
+  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
+  fence seq_cst
+  %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
+}
+
+; CHECK:for (c2=0;
diff --git a/rc1/test/Makefile b/rc1/test/Makefile
new file mode 100755
index 0000000..d20ac71
--- /dev/null
+++ b/rc1/test/Makefile
@@ -0,0 +1,64 @@
+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
+
+
+check-polly:: lit.site.cfg polly-lib
+	@ echo '--- Running polly tests for $(TARGET_TRIPLE) ---'
+	@ $(PYTHON) $(LLVM_SRC_ROOT)/utils/lit/lit.py \
+	  $(LIT_ARGS) $(TESTARGS) $(TESTDIRS)
+
+FORCE:
+
+polly-lib: FORCE
+	$(MAKE) -C ../lib || exit 1;
+
+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" \
+	     -e "s#@LLVM_SHLIBEXT@#$(SHLIBEXT)#g" \
+             -e "s#@POLLY_LIB_DIR@#$(LibDir)#g" \
+             -e "s#@LINK_POLLY_INTO_TOOLS@#OFF#g" \
+             -e "s#@CLOOG_FOUND@#$(CLOOG_FOUND)#g" \
+             -e "s#@CUDALIB_FOUND@#$(CUDALIB_FOUND)#g" \
+	     $(PROJ_SRC_DIR)/lit.site.cfg.in > $@
+
+clean::
+	@ find . -name Output | xargs rm -fr
+
+.PHONY: check-polly clean
diff --git a/rc1/test/README b/rc1/test/README
new file mode 100644
index 0000000..e8470c6
--- /dev/null
+++ b/rc1/test/README
@@ -0,0 +1 @@
+place tests here
\ No newline at end of file
diff --git a/rc1/test/ScheduleOptimizer/2012-03-16-Empty-Domain.ll b/rc1/test/ScheduleOptimizer/2012-03-16-Empty-Domain.ll
new file mode 100644
index 0000000..374e3bf
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/2012-03-16-Empty-Domain.ll
@@ -0,0 +1,17 @@
+; RUN: opt %loadPolly -polly-opt-isl -S %s
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32"
+target triple = "hexagon-unknown-linux-gnu"
+
+define void @sdbout_label() nounwind {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.cond, %entry
+  %0 = phi i32 [ 0, %entry ], [ %1, %for.cond ]
+  %1 = add nsw i32 %0, 1
+  %exitcond72 = icmp eq i32 %1, 7
+  br i1 %exitcond72, label %sw.epilog66, label %for.cond
+
+sw.epilog66:                                      ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScheduleOptimizer/2012-04-16-Trivially-vectorizable-loops.ll b/rc1/test/ScheduleOptimizer/2012-04-16-Trivially-vectorizable-loops.ll
new file mode 100644
index 0000000..c25dcf2
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/2012-04-16-Trivially-vectorizable-loops.ll
@@ -0,0 +1,205 @@
+; RUN: opt %loadPolly -basicaa -polly-opt-isl %vector-opt %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%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 [1536 x [1536 x float]] zeroinitializer, align 16
+@B = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@stdout = external global %struct._IO_FILE*
+@.str = private unnamed_addr constant [5 x i8] c"%lf \00", align 1
+@C = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@.str1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
+
+define void @init_array() nounwind uwtable {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc17, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc18, %for.inc17 ]
+  %cmp = icmp slt i32 %i.0, 1536
+  br i1 %cmp, label %for.body, label %for.end19
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %cmp2 = icmp slt i32 %j.0, 1536
+  br i1 %cmp2, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %mul = mul nsw i32 %i.0, %j.0
+  %rem = srem i32 %mul, 1024
+  %add = add nsw i32 1, %rem
+  %conv = sitofp i32 %add to double
+  %div = fdiv double %conv, 2.000000e+00
+  %conv4 = fptrunc double %div to float
+  %idxprom = sext i32 %j.0 to i64
+  %idxprom5 = sext i32 %i.0 to i64
+  %arrayidx = getelementptr inbounds [1536 x [1536 x float]]* @A, i32 0, i64 %idxprom5
+  %arrayidx6 = getelementptr inbounds [1536 x float]* %arrayidx, i32 0, i64 %idxprom
+  store float %conv4, float* %arrayidx6, align 4
+  %mul7 = mul nsw i32 %i.0, %j.0
+  %rem8 = srem i32 %mul7, 1024
+  %add9 = add nsw i32 1, %rem8
+  %conv10 = sitofp i32 %add9 to double
+  %div11 = fdiv double %conv10, 2.000000e+00
+  %conv12 = fptrunc double %div11 to float
+  %idxprom13 = sext i32 %j.0 to i64
+  %idxprom14 = sext i32 %i.0 to i64
+  %arrayidx15 = getelementptr inbounds [1536 x [1536 x float]]* @B, i32 0, i64 %idxprom14
+  %arrayidx16 = getelementptr inbounds [1536 x float]* %arrayidx15, i32 0, i64 %idxprom13
+  store float %conv12, float* %arrayidx16, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc17
+
+for.inc17:                                        ; preds = %for.end
+  %inc18 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end19:                                        ; preds = %for.cond
+  ret void
+}
+
+define void @print_array() nounwind uwtable {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %cmp = icmp slt i32 %i.0, 1536
+  br i1 %cmp, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %cmp2 = icmp slt i32 %j.0, 1536
+  br i1 %cmp2, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %0 = load %struct._IO_FILE** @stdout, align 8
+  %idxprom = sext i32 %j.0 to i64
+  %idxprom4 = sext i32 %i.0 to i64
+  %arrayidx = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom4
+  %arrayidx5 = getelementptr inbounds [1536 x float]* %arrayidx, i32 0, i64 %idxprom
+  %1 = load float* %arrayidx5, align 4
+  %conv = fpext float %1 to double
+  %call = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %0, i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), double %conv)
+  %rem = srem i32 %j.0, 80
+  %cmp6 = icmp eq i32 %rem, 79
+  br i1 %cmp6, label %if.then, label %if.end
+
+if.then:                                          ; preds = %for.body3
+  %2 = load %struct._IO_FILE** @stdout, align 8
+  %call8 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %2, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %for.body3
+  br label %for.inc
+
+for.inc:                                          ; preds = %if.end
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  %3 = load %struct._IO_FILE** @stdout, align 8
+  %call9 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %3, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
+
+declare i32 @fprintf(%struct._IO_FILE*, i8*, ...)
+
+define i32 @main() nounwind uwtable {
+entry:
+  call void @init_array()
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc28, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc29, %for.inc28 ]
+  %cmp = icmp slt i32 %i.0, 1536
+  br i1 %cmp, label %for.body, label %for.end30
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc25, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc26, %for.inc25 ]
+  %cmp2 = icmp slt i32 %j.0, 1536
+  br i1 %cmp2, label %for.body3, label %for.end27
+
+for.body3:                                        ; preds = %for.cond1
+  %idxprom = sext i32 %j.0 to i64
+  %idxprom4 = sext i32 %i.0 to i64
+  %arrayidx = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom4
+  %arrayidx5 = getelementptr inbounds [1536 x float]* %arrayidx, i32 0, i64 %idxprom
+  store float 0.000000e+00, float* %arrayidx5, align 4
+  br label %for.cond6
+
+for.cond6:                                        ; preds = %for.inc, %for.body3
+  %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+  %cmp7 = icmp slt i32 %k.0, 1536
+  br i1 %cmp7, label %for.body8, label %for.end
+
+for.body8:                                        ; preds = %for.cond6
+  %idxprom9 = sext i32 %j.0 to i64
+  %idxprom10 = sext i32 %i.0 to i64
+  %arrayidx11 = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom10
+  %arrayidx12 = getelementptr inbounds [1536 x float]* %arrayidx11, i32 0, i64 %idxprom9
+  %0 = load float* %arrayidx12, align 4
+  %idxprom13 = sext i32 %k.0 to i64
+  %idxprom14 = sext i32 %i.0 to i64
+  %arrayidx15 = getelementptr inbounds [1536 x [1536 x float]]* @A, i32 0, i64 %idxprom14
+  %arrayidx16 = getelementptr inbounds [1536 x float]* %arrayidx15, i32 0, i64 %idxprom13
+  %1 = load float* %arrayidx16, align 4
+  %idxprom17 = sext i32 %j.0 to i64
+  %idxprom18 = sext i32 %k.0 to i64
+  %arrayidx19 = getelementptr inbounds [1536 x [1536 x float]]* @B, i32 0, i64 %idxprom18
+  %arrayidx20 = getelementptr inbounds [1536 x float]* %arrayidx19, i32 0, i64 %idxprom17
+  %2 = load float* %arrayidx20, align 4
+  %mul = fmul float %1, %2
+  %add = fadd float %0, %mul
+  %idxprom21 = sext i32 %j.0 to i64
+  %idxprom22 = sext i32 %i.0 to i64
+  %arrayidx23 = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom22
+  %arrayidx24 = getelementptr inbounds [1536 x float]* %arrayidx23, i32 0, i64 %idxprom21
+  store float %add, float* %arrayidx24, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body8
+  %inc = add nsw i32 %k.0, 1
+  br label %for.cond6
+
+for.end:                                          ; preds = %for.cond6
+  br label %for.inc25
+
+for.inc25:                                        ; preds = %for.end
+  %inc26 = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end27:                                        ; preds = %for.cond1
+  br label %for.inc28
+
+for.inc28:                                        ; preds = %for.end27
+  %inc29 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end30:                                        ; preds = %for.cond
+  ret i32 0
+}
diff --git a/rc1/test/ScheduleOptimizer/2012-10-14-Zero-Bands.ll b/rc1/test/ScheduleOptimizer/2012-10-14-Zero-Bands.ll
new file mode 100644
index 0000000..894d57d
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/2012-10-14-Zero-Bands.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly -polly-detect-scops-in-regions-without-loops -polly-detect-scops-in-functions-without-loops -polly-opt-isl -analyze < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@A = common global [1536 x float] zeroinitializer
+
+define void @read_nres() {
+entry:
+  br label %if.cond
+
+if.cond:
+  br i1 false, label %if.then, label %if.end
+
+if.then:
+  %ptr = getelementptr [1536 x float]* @A, i64 0, i32 23
+  store float undef, float* %ptr
+  br label %if.end
+
+if.end:
+  br label %return
+
+return:
+  ret void
+}
+
+; CHECK: Calculated schedule:
+; CHECK-NOT: Stmt_if_then
diff --git a/rc1/test/ScheduleOptimizer/2013-04-11-Empty-Domain-two.ll b/rc1/test/ScheduleOptimizer/2013-04-11-Empty-Domain-two.ll
new file mode 100644
index 0000000..15d7dc6
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/2013-04-11-Empty-Domain-two.ll
@@ -0,0 +1,24 @@
+; RUN: opt %loadPolly -polly-opt-isl -S %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Check that we handle statements with an empty iteration domain correctly.
+
+define void @f() {
+entry:
+  %A = alloca double
+  br label %for
+
+for:
+  %indvar = phi i32 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i32 %indvar, -1
+  br i1 %exitcond, label %for.inc, label %return
+
+for.inc:
+  %indvar.next = add i32 %indvar, 1
+  store double 1.0, double* %A
+  br label %for
+
+return:
+  ret void
+}
diff --git a/rc1/test/ScheduleOptimizer/computeout.ll b/rc1/test/ScheduleOptimizer/computeout.ll
new file mode 100644
index 0000000..578478c
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/computeout.ll
@@ -0,0 +1,70 @@
+; RUN: opt -S %loadPolly -basicaa -polly-opt-isl -polly-opt-fusion=max -polly-ast -analyze < %s | FileCheck %s 
+; RUN: opt -S %loadPolly -basicaa -polly-opt-isl -polly-opt-fusion=max -polly-ast -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
+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"
+
+;     for(i = 0; i < 100; i++ )
+; S1:   A[i] = 2;
+;
+;     for (i = 0; i < 10; i++ )
+; S2:   A[i]  = 5;
+;
+;     for (i = 0; i < 200; i++ )
+; S3:   A[i] = 5;
+
+define void @sequential_writes() {
+entry:
+  %A = alloca [200 x i32]
+  br label %S1
+
+S1:
+  %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+  %arrayidx.1 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.1
+  store i32 2, i32* %arrayidx.1
+  %indvar.next.1 = add i64 %indvar.1, 1
+  %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+  br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+  br label %S2
+
+S2:
+  %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+  %arrayidx.2 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.2
+  store i32 5, i32* %arrayidx.2
+  %indvar.next.2 = add i64 %indvar.2, 1
+  %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+  br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+  br label %S3
+
+S3:
+  %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+  %arrayidx.3 = getelementptr [200 x i32]* %A, i64 0, i64 %indvar.3
+  store i32 7, i32* %arrayidx.3
+  %indvar.next.3 = add i64 %indvar.3, 1
+  %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+  br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+  ret void
+}
+
+
+; CHECK: for (int c0 = 0; c0 <= 199; c0 += 1) {
+; CHECK:   if (c0 <= 99) {
+; CHECK:     Stmt_S1(c0);
+; CHECK:     if (c0 <= 9)
+; CHECK:       Stmt_S2(c0);
+; CHECK:   }
+; CHECK:   Stmt_S3(c0);
+; CHECK: }
+
+; TIMEOUT: for (int c1 = 0; c1 <= 99; c1 += 1)
+; TIMEOUT: Stmt_S1(c1);
+; TIMEOUT: for (int c1 = 0; c1 <= 9; c1 += 1)
+; TIMEOUT: Stmt_S2(c1);
+; TIMEOUT: for (int c1 = 0; c1 <= 199; c1 += 1)
+; TIMEOUT: Stmt_S3(c1);
+
diff --git a/rc1/test/ScheduleOptimizer/line-tiling-2.ll b/rc1/test/ScheduleOptimizer/line-tiling-2.ll
new file mode 100644
index 0000000..b0f5199
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/line-tiling-2.ll
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -polly-opt-isl -analyze -polly-no-tiling=0 -polly-ast -polly-tile-sizes=1,64 %s
+; CHECK: c0 += 1
+; CHECK: c1 += 64
+; CHECK: c1 <= c1 + 63
+; ModuleID = 'line-tiling-2.ll'
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+; Function Attrs: nounwind
+define void @line([512 x i32]* %A) {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body3.lr.ph
+
+for.body3.lr.ph:                                  ; preds = %for.inc5, %entry.split
+  %i.0 = phi i32 [ 0, %entry.split ], [ %inc6, %for.inc5 ]
+  br label %for.body3
+
+for.body3:                                        ; preds = %for.body3.lr.ph, %for.body3
+  %j.0 = phi i32 [ 0, %for.body3.lr.ph ], [ %inc, %for.body3 ]
+  %mul = mul nsw i32 %j.0, %i.0
+  %rem = srem i32 %mul, 42
+  %arrayidx4 = getelementptr inbounds [512 x i32]* %A, i32 %i.0, i32 %j.0
+  store i32 %rem, i32* %arrayidx4, align 4
+  %inc = add nsw i32 %j.0, 1
+  %cmp2 = icmp slt i32 %inc, 512
+  br i1 %cmp2, label %for.body3, label %for.inc5
+
+for.inc5:                                         ; preds = %for.body3
+  %inc6 = add nsw i32 %i.0, 1
+  %cmp = icmp slt i32 %inc6, 1024
+  br i1 %cmp, label %for.body3.lr.ph, label %for.end7
+
+for.end7:                                         ; preds = %for.inc5
+  ret void
+}
diff --git a/rc1/test/ScheduleOptimizer/line-tiling.ll b/rc1/test/ScheduleOptimizer/line-tiling.ll
new file mode 100644
index 0000000..f646196
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/line-tiling.ll
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -polly-opt-isl -analyze -polly-no-tiling=0 -polly-ast -polly-tile-sizes=64,1 %s
+; CHECK: c0 += 64
+; CHECK: c1 += 1
+; CHECK: c0 <= c0 + 63
+; ModuleID = 'line-tiling.ll'
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+; Function Attrs: nounwind
+define void @line([512 x i32]* %A) {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body3.lr.ph
+
+for.body3.lr.ph:                                  ; preds = %for.inc5, %entry.split
+  %i.0 = phi i32 [ 0, %entry.split ], [ %inc6, %for.inc5 ]
+  br label %for.body3
+
+for.body3:                                        ; preds = %for.body3.lr.ph, %for.body3
+  %j.0 = phi i32 [ 0, %for.body3.lr.ph ], [ %inc, %for.body3 ]
+  %mul = mul nsw i32 %j.0, %i.0
+  %rem = srem i32 %mul, 42
+  %arrayidx4 = getelementptr inbounds [512 x i32]* %A, i32 %i.0, i32 %j.0
+  store i32 %rem, i32* %arrayidx4, align 4
+  %inc = add nsw i32 %j.0, 1
+  %cmp2 = icmp slt i32 %inc, 512
+  br i1 %cmp2, label %for.body3, label %for.inc5
+
+for.inc5:                                         ; preds = %for.body3
+  %inc6 = add nsw i32 %i.0, 1
+  %cmp = icmp slt i32 %inc6, 1024
+  br i1 %cmp, label %for.body3.lr.ph, label %for.end7
+
+for.end7:                                         ; preds = %for.inc5
+  ret void
+}
diff --git a/rc1/test/ScheduleOptimizer/prevectorization.ll b/rc1/test/ScheduleOptimizer/prevectorization.ll
new file mode 100644
index 0000000..5f80b73
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/prevectorization.ll
@@ -0,0 +1,78 @@
+; RUN: opt -S %loadPolly -basicaa -polly-opt-isl -polly-vectorizer=polly -polly-ast -analyze < %s | FileCheck %s 
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@C = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@A = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@B = common global [1536 x [1536 x float]] zeroinitializer, align 16
+
+; Function Attrs: nounwind uwtable
+define void @foo() #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.cond1.preheader
+
+for.cond1.preheader:                              ; preds = %entry.split, %for.inc28
+  %indvar4 = phi i64 [ 0, %entry.split ], [ %indvar.next5, %for.inc28 ]
+  br label %for.body3
+
+for.body3:                                        ; preds = %for.cond1.preheader, %for.inc25
+  %indvar6 = phi i64 [ 0, %for.cond1.preheader ], [ %indvar.next7, %for.inc25 ]
+  %arrayidx24 = getelementptr [1536 x [1536 x float]]* @C, i64 0, i64 %indvar4, i64 %indvar6
+  store float 0.000000e+00, float* %arrayidx24, align 4
+  br label %for.body8
+
+for.body8:                                        ; preds = %for.body3, %for.body8
+  %indvar = phi i64 [ 0, %for.body3 ], [ %indvar.next, %for.body8 ]
+  %arrayidx16 = getelementptr [1536 x [1536 x float]]* @A, i64 0, i64 %indvar4, i64 %indvar
+  %arrayidx20 = getelementptr [1536 x [1536 x float]]* @B, i64 0, i64 %indvar, i64 %indvar6
+  %0 = load float* %arrayidx24, align 4
+  %1 = load float* %arrayidx16, align 4
+  %2 = load float* %arrayidx20, align 4
+  %mul = fmul float %1, %2
+  %add = fadd float %0, %mul
+  store float %add, float* %arrayidx24, align 4
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp ne i64 %indvar.next, 1536
+  br i1 %exitcond, label %for.body8, label %for.inc25
+
+for.inc25:                                        ; preds = %for.body8
+  %indvar.next7 = add i64 %indvar6, 1
+  %exitcond8 = icmp ne i64 %indvar.next7, 1536
+  br i1 %exitcond8, label %for.body3, label %for.inc28
+
+for.inc28:                                        ; preds = %for.inc25
+  %indvar.next5 = add i64 %indvar4, 1
+  %exitcond9 = icmp ne i64 %indvar.next5, 1536
+  br i1 %exitcond9, label %for.cond1.preheader, label %for.end30
+
+for.end30:                                        ; preds = %for.inc28
+  ret void
+}
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+; CHECK: #pragma omp parallel for
+; CHECK: for (int c1 = 0; c1 <= 1535; c1 += 32)
+; CHECK:   for (int c2 = 0; c2 <= 1535; c2 += 32)
+; CHECK:     for (int c3 = c1; c3 <= c1 + 31; c3 += 1)
+; CHECK:       for (int c4 = c2; c4 <= c2 + 31; c4 += 4)
+; CHECK:         #pragma simd
+; CHECK:         for (int c5 = c4; c5 <= c4 + 3; c5 += 1)
+; CHECK:           Stmt_for_body3(c3, c5);
+; CHECK: #pragma omp parallel for
+; CHECK: for (int c1 = 0; c1 <= 1535; c1 += 32)
+; CHECK:   for (int c2 = 0; c2 <= 1535; c2 += 32)
+; CHECK:     for (int c3 = 0; c3 <= 1535; c3 += 32)
+; CHECK:       for (int c4 = c1; c4 <= c1 + 31; c4 += 1)
+; CHECK:         for (int c5 = c2; c5 <= c2 + 31; c5 += 4)
+; CHECK:           for (int c6 = c3; c6 <= c3 + 31; c6 += 1)
+; CHECK:             #pragma simd
+; CHECK:             for (int c7 = c5; c7 <= c5 + 3; c7 += 1)
+; CHECK:               Stmt_for_body8(c4, c7, c6);
+
+!llvm.ident = !{!0}
+
+!0 = metadata !{metadata !"clang version 3.5.0 "}
diff --git a/rc1/test/ScheduleOptimizer/rectangular-tiling.ll b/rc1/test/ScheduleOptimizer/rectangular-tiling.ll
new file mode 100644
index 0000000..b74bf44
--- /dev/null
+++ b/rc1/test/ScheduleOptimizer/rectangular-tiling.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-opt-isl -analyze -polly-no-tiling=0 -polly-ast -polly-tile-sizes=256,16 %s
+; CHECK: c0 += 256
+; CHECK: c1 += 16
+; CHECK: c0 <= c0 + 255
+; CHECK: c1 <= c1 + 15
+; ModuleID = 'rectangular-tiling.ll'
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+; Function Attrs: nounwind
+define void @rect([512 x i32]* %A) {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body3.lr.ph
+
+for.body3.lr.ph:                                  ; preds = %for.inc5, %entry.split
+  %i.0 = phi i32 [ 0, %entry.split ], [ %inc6, %for.inc5 ]
+  br label %for.body3
+
+for.body3:                                        ; preds = %for.body3.lr.ph, %for.body3
+  %j.0 = phi i32 [ 0, %for.body3.lr.ph ], [ %inc, %for.body3 ]
+  %mul = mul nsw i32 %j.0, %i.0
+  %rem = srem i32 %mul, 42
+  %arrayidx4 = getelementptr inbounds [512 x i32]* %A, i32 %i.0, i32 %j.0
+  store i32 %rem, i32* %arrayidx4, align 4
+  %inc = add nsw i32 %j.0, 1
+  %cmp2 = icmp slt i32 %inc, 512
+  br i1 %cmp2, label %for.body3, label %for.inc5
+
+for.inc5:                                         ; preds = %for.body3
+  %inc6 = add nsw i32 %i.0, 1
+  %cmp = icmp slt i32 %inc6, 1024
+  br i1 %cmp, label %for.body3.lr.ph, label %for.end7
+
+for.end7:                                         ; preds = %for.inc5
+  ret void
+}
diff --git a/rc1/test/ScopDetect/base_pointer.ll b/rc1/test/ScopDetect/base_pointer.ll
new file mode 100644
index 0000000..ee05d13
--- /dev/null
+++ b/rc1/test/ScopDetect/base_pointer.ll
@@ -0,0 +1,297 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -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 void @base_pointer_in_condition(i64** noalias %A_ptr, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br label %pre
+
+pre:
+  %A = load i64** %A_ptr
+  br i1 true, label %for.i, label %then
+
+for.i:
+  %indvar = phi i64 [ 0, %pre ], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %then, label %for.i
+
+then:
+  br label %return
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_in_condition
+; CHECK: Valid Region for Scop: for.i => then
+
+define void @base_pointer_is_argument(float* %A, i64 %n) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* %A, i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_is_argument
+; CHECK: Valid Region for Scop: for.i => exit
+
+define void @base_pointer_is_const_expr(i64 %n) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* inttoptr (i64 100 to float*), i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_is_const_expr
+; CHECK-LABEL: Valid Region for Scop: for.i => exit
+
+@A = external global float
+
+define void @base_pointer_is_global(i64 %n) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* @A, i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_is_global
+; CHECK: Valid Region for Scop: for.i => exit
+
+declare float *@foo()
+
+define void @base_pointer_is_inst_outside(i64 %n) {
+entry:
+  %A = call float *@foo()
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* %A, i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_is_inst_outside
+; CHECK: Valid Region for Scop: for.i => exit
+
+declare float* @getNextBasePtr(float*) readnone nounwind
+
+define void @base_pointer_is_phi_node(i64 %n, float* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  %ptr = phi float* [ %ptr.next, %for.i.inc ], [ %A, %entry ]
+; To get a PHI node inside a SCoP that can not be analyzed but
+; for which the surrounding SCoP is normally still valid we use a function
+; without any side effects.
+  %ptr.next = call float* @getNextBasePtr(float* %ptr)
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* %ptr, i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_is_phi_node
+; CHECK-NOT: Valid Region for Scop
+
+define void @base_pointer_is_inst_inside_invariant_1(i64 %n, float* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+; To get an instruction inside a region, we use a function without side
+; effects on which SCEV blocks, but for which it is still clear that the
+; return value remains invariant throughout the whole loop.
+  %ptr = call float* @getNextBasePtr(float* %A)
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* %ptr, i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_is_inst_inside_invariant_1
+; CHECK: Valid Region for Scop: for.i => exit
+
+declare float* @getNextBasePtr2(float*) readnone nounwind
+
+define void @base_pointer_is_inst_inside_invariant_2(i64 %n, float* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  %ptr = call float* @getNextBasePtr2(float* %A)
+  %ptr2 = call float* @getNextBasePtr(float* %ptr)
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* %ptr2, i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK-LABEL: base_pointer_is_inst_inside_invariant_2
+; CHECK: Valid Region for Scop: for.i => exit
+
+declare float* @getNextBasePtr3(float*, i64) readnone nounwind
+
+define void @base_pointer_is_inst_inside_variant(i64 %n, float* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  %ptr = call float* @getNextBasePtr3(float* %A, i64 %indvar.i)
+  %ptr2 = call float* @getNextBasePtr(float* %ptr)
+  br label %S1
+
+S1:
+  %conv = sitofp i64 %indvar.i to float
+  %arrayidx5 = getelementptr float* %ptr2, i64 %indvar.i
+  store float %conv, float* %arrayidx5, align 4
+  br label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK: base_pointer_is_inst_inside_variant
+; CHECK-NOT: Valid Region for Scop
+
+define void @base_pointer_is_ptr2ptr(float** noalias %A, i64 %n) {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ]
+  %arrayidx = getelementptr float** %A, i64 %indvar.i
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ 0, %for.i ], [ %indvar.j.next, %for.j ]
+  %conv = sitofp i64 %indvar.i to float
+  %basepointer = load float** %arrayidx, align 8
+  %arrayidx5 = getelementptr float* %basepointer, i64 %indvar.j
+  store float %conv, float* %arrayidx5, align 4
+  %indvar.j.next = add i64 %indvar.j, 1
+  %exitcond.j = icmp ne i64 %indvar.j.next, %n
+  br i1 %exitcond.j, label %for.j, label %for.i.inc
+
+for.i.inc:
+  %indvar.i.next = add i64 %indvar.i, 1
+  %exitcond.i = icmp ne i64 %indvar.i.next, %n
+  br i1 %exitcond.i, label %for.i, label %exit
+
+exit:
+  ret void
+}
+
+; CHECK: base_pointer_is_ptr2ptr
+; CHECK-NOT: Valid Region for Scop
diff --git a/rc1/test/ScopDetect/cross_loop_non_single_exit.ll b/rc1/test/ScopDetect/cross_loop_non_single_exit.ll
new file mode 100644
index 0000000..82ec1e7
--- /dev/null
+++ b/rc1/test/ScopDetect/cross_loop_non_single_exit.ll
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;   if (true)
+;     for (i = 0; i < N; ++i)
+;       A[i] = i;
+;   else
+;     for (j = 0; j < N; ++j)
+;        A[j] = 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) nounwind {
+entry:
+  fence seq_cst
+  br i1 true, label %next, label %next2
+
+next2:
+  br i1 true, label %for.j, label %return
+
+for.j:
+  %indvar2 = phi i64 [ 0, %next2], [ %indvar2.next2, %for.j]
+  %scevgep2 = getelementptr i64* %A, i64 %indvar2
+  store i64 %indvar2, i64* %scevgep2
+  %indvar2.next2 = add nsw i64 %indvar2, 1
+  %exitcond2 = icmp eq i64 %indvar2.next2, %N
+  br i1 %exitcond2, label %return, label %for.j
+
+next:
+  br i1 true, label %for.i, label %return
+
+for.i:
+  %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Valid Region for Scop: next => return
+; CHECK: Valid Region for Scop: next2 => return
diff --git a/rc1/test/ScopDetect/cross_loop_non_single_exit_2.ll b/rc1/test/ScopDetect/cross_loop_non_single_exit_2.ll
new file mode 100644
index 0000000..7302054
--- /dev/null
+++ b/rc1/test/ScopDetect/cross_loop_non_single_exit_2.ll
@@ -0,0 +1,62 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;   if (true)
+;     for (i = 0; i < N; ++i)
+;       A[i] = i;
+;   else
+;     for (j = 0; j < N; ++j)
+;        A[j] = 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"
+
+declare i64 @foo()
+
+define void @f(i64* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br i1 true, label %next, label %next2
+
+next2:
+  br i1 true, label %for.j, label %return
+
+for.j:
+  %indvar2 = phi i64 [ 0, %next2], [ %indvar2.next2, %for.j]
+  %scevgep2 = getelementptr i64* %A, i64 %indvar2
+  store i64 %indvar2, i64* %scevgep2
+  %indvar2.next2 = add nsw i64 %indvar2, 1
+  %exitcond2 = icmp eq i64 %indvar2.next2, %N
+  br i1 %exitcond2, label %return, label %for.j
+
+next:
+  br i1 true, label %for.i, label %return
+
+for.i:
+  %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %i = call i64 @foo()
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  br i1 true, label %return_a, label %return_b
+
+return_a:
+  br label %return_join
+
+return_b:
+  br label %return_join
+
+return_join:
+  fence seq_cst
+  ret void
+}
+
+; CHECK-NOT: Valid Region for Scop: next => return
+; CHECK: Valid Region for Scop: next2 => return
diff --git a/rc1/test/ScopDetect/dependency_to_phi_node_outside_of_region.ll b/rc1/test/ScopDetect/dependency_to_phi_node_outside_of_region.ll
new file mode 100644
index 0000000..2a67dd6
--- /dev/null
+++ b/rc1/test/ScopDetect/dependency_to_phi_node_outside_of_region.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-detect < %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 void @f(i64* %A, i64 %N, i64 %M) nounwind {
+entry:
+  fence seq_cst
+  br label %for.i
+
+for.i:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %next, label %for.i
+
+next:
+  fence seq_cst
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ %indvar, %next ], [ %indvar.j.next, %for.j ]
+  %scevgep.j = getelementptr i64* %A, i64 %indvar.j
+  store i64 %indvar.j, i64* %scevgep.j
+  fence seq_cst
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %M
+  br i1 %exitcond.j, label %return, label %for.j
+
+return:
+  fence seq_cst
+  ret void
+}
diff --git a/rc1/test/ScopDetect/indvars.ll b/rc1/test/ScopDetect/indvars.ll
new file mode 100644
index 0000000..56d1954
--- /dev/null
+++ b/rc1/test/ScopDetect/indvars.ll
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly -analyze -polly-detect -polly-codegen-isl -polly-codegen-scev < %s | FileCheck %s
+;
+; When a region header is part of a loop, then all entering edges of this region
+; should not come from the loop but outside the region.
+
+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(i64* %A) nounwind {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.next.i, %for.i.backedge ]
+  %indvar.next.i = add i64 %indvar.i, 1
+  %scevgep = getelementptr i64* %A, i64 %indvar.i
+  store i64 %indvar.i, i64* %scevgep, align 4
+  br i1 true, label %for.j.preheader, label %for.j2
+
+for.j.preheader:
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ %indvar.next.j, %for.j ], [ 0, %for.j.preheader ]
+  %indvar.next.j = add i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.next.j, 10
+  br i1 %exitcond.j, label %for.j2, label %for.j
+
+for.j2:
+  fence seq_cst
+  br label %for.i.backedge
+
+for.i.backedge:
+  %exitcond.i = icmp eq i64 %indvar.next.i, 2048
+  br i1 %exitcond.i, label %for.i, label %.end
+
+.end:
+  ret void
+}
+
+; CHECK: Valid Region for Scop: for.j => for.j2
diff --git a/rc1/test/ScopDetect/invalidate_scalar_evolution.ll b/rc1/test/ScopDetect/invalidate_scalar_evolution.ll
new file mode 100644
index 0000000..4e3ebcd
--- /dev/null
+++ b/rc1/test/ScopDetect/invalidate_scalar_evolution.ll
@@ -0,0 +1,45 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -analyze -polly-codegen-scev < %s | FileCheck %s -check-prefix=CHECK-SCEV 
+
+; void f(long A[], long N) {
+;   long i;
+;   for (i = 0; i < N; ++i)
+;     A[i] = 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* %A, i64 %N, i64 %p) nounwind {
+entry:
+  fence seq_cst
+  br label %pre
+
+pre:
+  %p_tmp = srem i64 %p, 5
+  br i1 true, label %for.i, label %then
+
+for.i:
+  %indvar = phi i64 [ 0, %pre ], [ %indvar.next, %for.i ]
+  %indvar.p1 = phi i64 [ 0, %pre ], [ %indvar.p1.next, %for.i ]
+  %indvar.p2 = phi i64 [ 0, %pre ], [ %indvar.p2.next, %for.i ]
+  %sum = add i64 %indvar, %indvar.p1
+  %sum2 = sub i64 %sum, %indvar.p2
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %indvar.p1.next = add nsw i64 %indvar.p1, %p_tmp
+  %indvar.p2.next = add nsw i64 %indvar.p2, %p_tmp
+  %exitcond = icmp eq i64 %sum2, %N
+  br i1 %exitcond, label %then, label %for.i
+
+then:
+  br label %return
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK-NOT: Valid Region for Scop
+; CHECK-SCEV: Valid Region for Scop: for.i => then
diff --git a/rc1/test/ScopDetect/keep_going_expansion.ll b/rc1/test/ScopDetect/keep_going_expansion.ll
new file mode 100644
index 0000000..9cdecfa
--- /dev/null
+++ b/rc1/test/ScopDetect/keep_going_expansion.ll
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -basicaa -polly-detect-track-failures -polly-detect-keep-going -polly-detect -analyze < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @a(i32 %n, i32* noalias %A, i32* noalias %B) #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.cond2.preheader:                              ; preds = %for.body
+  br label %for.body4
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %indvar = phi i64 [ 0, %entry.split ], [ %indvar.next, %for.body ]
+  %j.02 = trunc i64 %indvar to i32
+  %arrayidx = getelementptr i32* %B, i64 %indvar
+  store i32 %j.02, i32* %arrayidx, align 4
+  %indvar.next = add i64 %indvar, 1
+  %exitcond3 = icmp ne i64 %indvar.next, 32
+  br i1 %exitcond3, label %for.body, label %for.cond2.preheader
+
+for.body4:                                        ; preds = %for.cond2.preheader, %for.body4
+  %0 = phi i32 [ 0, %for.cond2.preheader ], [ %1, %for.body4 ]
+  %mul = mul i32 %n, %0
+  %idxprom5 = sext i32 %mul to i64
+  %arrayidx6 = getelementptr inbounds i32* %A, i64 %idxprom5
+  store i32 %0, i32* %arrayidx6, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 32
+  br i1 %exitcond, label %for.body4, label %for.end9
+
+for.end9:                                         ; preds = %for.body4
+  %idxprom10 = sext i32 %n to i64
+  %arrayidx11 = getelementptr inbounds i32* %A, i64 %idxprom10
+  %2 = load i32* %arrayidx11, align 4
+  %idxprom12 = sext i32 %n to i64
+  %arrayidx13 = getelementptr inbounds i32* %B, i64 %idxprom12
+  %3 = load i32* %arrayidx13, align 4
+  %add = add nsw i32 %3, %2
+  ret i32 %add
+}
+
+; CHECK: Valid Region for Scop: for.body => for.cond2.preheader
diff --git a/rc1/test/ScopDetect/multidim_two_accesses_different_delinearization.ll b/rc1/test/ScopDetect/multidim_two_accesses_different_delinearization.ll
new file mode 100644
index 0000000..ebddf3f
--- /dev/null
+++ b/rc1/test/ScopDetect/multidim_two_accesses_different_delinearization.ll
@@ -0,0 +1,45 @@
+; RUN: opt %loadPolly -polly-detect -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Derived from the following code:
+;
+; void foo(long n, long m, double *A) {
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;       *(A + i * n + j) = 1.0;
+;       *(A + j * m + i) = 2.0;
+; }
+
+; CHECK-NOT: Valid Region for Scop
+
+define void @foo(i64 %n, i64 %m, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j ]
+  %tmp = mul nsw i64 %i, %m
+  %vlaarrayidx.sum = add i64 %j, %tmp
+  %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
+  store double 1.0, double* %arrayidx
+  %tmp1 = mul nsw i64 %j, %n
+  %vlaarrayidx.sum1 = add i64 %i, %tmp1
+  %arrayidx1 = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum1
+  store double 1.0, double* %arrayidx1
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopDetect/nested_loop_single_exit.ll b/rc1/test/ScopDetect/nested_loop_single_exit.ll
new file mode 100644
index 0000000..5a616d7
--- /dev/null
+++ b/rc1/test/ScopDetect/nested_loop_single_exit.ll
@@ -0,0 +1,45 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-isl -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i, j;
+;   if (true)
+;     for (j = 0; j < N; ++j)
+;       for (i = 0; i < N; ++i)
+;         A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br label %next
+
+next:
+  br i1 true, label %for.j, label %return
+
+for.j:
+  %j.015 = phi i64 [ %inc5, %for.inc8 ], [ 0, %next ]
+  br label %for.i
+
+for.i:
+  %indvar = phi i64 [ 0, %for.j], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %for.inc8, label %for.i
+
+for.inc8:                                         ; preds = %for.body3
+  %inc5 = add nsw i64 %j.015, 1
+  %exitcond16 = icmp eq i64 %inc5, %N
+  br i1 %exitcond16, label %return, label %for.j
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Valid Region for Scop: next => return
diff --git a/rc1/test/ScopDetect/parametric-multiply-in-scev.ll b/rc1/test/ScopDetect/parametric-multiply-in-scev.ll
new file mode 100644
index 0000000..ff0802d
--- /dev/null
+++ b/rc1/test/ScopDetect/parametric-multiply-in-scev.ll
@@ -0,0 +1,29 @@
+; RUN: opt %loadPolly -polly-detect-scops-in-regions-without-loops -polly-detect-scops-in-functions-without-loops -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect-scops-in-regions-without-loops -polly-detect-scops-in-functions-without-loops -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+
+;  foo(float *A, long n, long k) {
+;    if (true)
+;      A[n * k] = 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-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo(float* %A, i64 %n, i64 %k) {
+entry:
+  br label %for.j
+
+for.j:
+  br i1 true, label %if.then, label %return
+
+if.then:
+  %mul = mul nsw i64 %n, %k
+  %arrayidx = getelementptr float* %A, i64 %mul
+  store float 0.000000e+00, float* %arrayidx
+  br label %return
+
+return:
+  ret void
+}
+
+; CHECK: Valid Region for Scop: for.j => return
diff --git a/rc1/test/ScopDetect/remove_all_children.ll b/rc1/test/ScopDetect/remove_all_children.ll
new file mode 100644
index 0000000..61fb57d
--- /dev/null
+++ b/rc1/test/ScopDetect/remove_all_children.ll
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @remove_all_children(i32* %eclass) {
+entry:
+  br label %while.body
+
+while.cond.loopexit:                              ; preds = %while.body50, %while.end44
+  fence seq_cst
+  br label %while.cond.backedge
+
+while.body:                                       ; preds = %while.cond.backedge, %entry
+  br label %if.end33
+
+while.cond.backedge:                              ; preds = %while.end30, %while.cond.loopexit
+  br i1 false, label %while.body, label %while.end60
+
+if.end33:                                         ; preds = %while.end30
+  br i1 false, label %while.body36, label %while.end44
+
+while.body36:                                     ; preds = %while.body36, %while.body36.lr.ph
+  %indvar77 = phi i64 [ 0, %if.end33 ], [ %indvar.next78, %while.body36 ]
+  %arrayidx40 = getelementptr i32* %eclass, i64 0
+  %indvar.next78 = add i64 %indvar77, 1
+  br i1 false, label %while.body36, label %while.end44
+
+while.end44:                                      ; preds = %while.body36, %if.end33
+  br i1 false, label %while.body50, label %while.cond.loopexit
+
+while.body50:                                     ; preds = %while.body50, %while.body50.lr.ph
+  %indvar79 = phi i64 [ 0, %while.end44 ], [ %indvar.next80, %while.body50 ]
+  %arrayidx55 = getelementptr i32* %eclass, i64 0
+  store i32 0, i32* %arrayidx55, align 4
+  %indvar.next80 = add i64 %indvar79, 1
+  br i1 false, label %while.body50, label %while.cond.loopexit
+
+while.end60:                                      ; preds = %while.cond.backedge
+  ret void
+}
+; remove_all_children
+; CHECK-NOT: Valid Region
+; CHECK: Valid Region for Scop: if.end33 => while.cond.loopexit
+; CHECK-NOT: Valid Region
diff --git a/rc1/test/ScopDetect/report-scop-location.ll b/rc1/test/ScopDetect/report-scop-location.ll
new file mode 100644
index 0000000..a4dc045
--- /dev/null
+++ b/rc1/test/ScopDetect/report-scop-location.ll
@@ -0,0 +1,82 @@
+; RUN: opt %loadPolly -polly-detect -polly-report -disable-output < %s  2>&1 | FileCheck %s
+target datalayout = "e-i64:64-f80:128-s:64-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define void @foo(float* %A) #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body, !dbg !11
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %indvar = phi i64 [ 0, %entry.split ], [ %indvar.next, %for.body ]
+  %i.01 = trunc i64 %indvar to i32, !dbg !13
+  %arrayidx = getelementptr float* %A, i64 %indvar, !dbg !13
+  %conv = sitofp i32 %i.01 to float, !dbg !13
+  store float %conv, float* %arrayidx, align 4, !dbg !13
+  %indvar.next = add i64 %indvar, 1, !dbg !11
+  %exitcond = icmp ne i64 %indvar.next, 100, !dbg !11
+  br i1 %exitcond, label %for.body, label %for.end, !dbg !11
+
+for.end:                                          ; preds = %for.body
+  ret void, !dbg !14
+}
+
+; CHECK: note: Polly detected an optimizable loop region (scop) in function 'foo'
+; CHECK: test.c:2: Start of scop
+; CHECK: test.c:3: End of scop
+
+; Function Attrs: nounwind uwtable
+define void @bar(float* %A) #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body, !dbg !15
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %indvar = phi i64 [ 0, %entry.split ], [ %indvar.next, %for.body ]
+  %i.01 = trunc i64 %indvar to i32, !dbg !17
+  %arrayidx = getelementptr float* %A, i64 %indvar, !dbg !17
+  %conv = sitofp i32 %i.01 to float, !dbg !17
+  store float %conv, float* %arrayidx, align 4, !dbg !17
+  %indvar.next = add i64 %indvar, 1, !dbg !15
+  %exitcond = icmp ne i64 %indvar.next, 100, !dbg !15
+  br i1 %exitcond, label %for.body, label %for.end, !dbg !15
+
+for.end:                                          ; preds = %for.body
+  ret void, !dbg !18
+}
+
+; CHECK: note: Polly detected an optimizable loop region (scop) in function 'bar'
+; CHECK: test.c:9: Start of scop
+; CHECK: test.c:13: End of scop
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!8, !9}
+!llvm.ident = !{!10}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/home/grosser/Projects/polly/git/tools/polly/test.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"test.c", metadata !"/home/grosser/Projects/polly/git/tools/polly"}
+!2 = metadata !{i32 0}
+!3 = metadata !{metadata !4, metadata !7}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"foo", metadata !"foo", metadata !"", i32 1, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (float*)* @foo, null, null, metadata !2, i32 1} ; [ DW_TAG_subprogram ] [line 1] [def] [foo]
+!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [/home/grosser/Projects/polly/git/tools/polly/test.c]
+!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !2, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"bar", metadata !"bar", metadata !"", i32 6, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (float*)* @bar, null, null, metadata !2, i32 6} ; [ DW_TAG_subprogram ] [line 6] [def] [bar]
+!8 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!9 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
+!10 = metadata !{metadata !"clang version 3.5 "}
+!11 = metadata !{i32 2, i32 0, metadata !12, null}
+!12 = metadata !{i32 786443, metadata !1, metadata !4, i32 2, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [/home/grosser/Projects/polly/git/tools/polly/test.c]
+!13 = metadata !{i32 3, i32 0, metadata !12, null}
+!14 = metadata !{i32 4, i32 0, metadata !4, null}
+!15 = metadata !{i32 9, i32 0, metadata !16, null}
+!16 = metadata !{i32 786443, metadata !1, metadata !7, i32 9, i32 0, i32 1} ; [ DW_TAG_lexical_block ] [/home/grosser/Projects/polly/git/tools/polly/test.c]
+!17 = metadata !{i32 13, i32 0, metadata !16, null}
+!18 = metadata !{i32 14, i32 0, metadata !7, null}
+
diff --git a/rc1/test/ScopDetect/sequential_loops.ll b/rc1/test/ScopDetect/sequential_loops.ll
new file mode 100644
index 0000000..0111f23
--- /dev/null
+++ b/rc1/test/ScopDetect/sequential_loops.ll
@@ -0,0 +1,94 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -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"
+
+; Two sequential loops right after each other.
+;
+; void f(long A[], long N) {
+;   long i;
+;   for (i = 0; i < N; ++i)
+;     A[i] = i;
+;   for (i = 0; i < N; ++i)
+;     A[i] = i;
+; }
+
+define void @f1(i64* %A, i64 %N) nounwind {
+; CHECK-LABEL: 'Polly - Detect static control parts (SCoPs)' for function 'f1'
+entry:
+  fence seq_cst
+  br label %for.i.1
+
+for.i.1:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.i.1 ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %for.i.2, label %for.i.1
+
+for.i.2:
+  %indvar.2 = phi i64 [ 0, %for.i.1 ], [ %indvar.next.2, %for.i.2 ]
+  %scevgep.2 = getelementptr i64* %A, i64 %indvar.2
+  store i64 %indvar.2, i64* %scevgep.2
+  %indvar.next.2 = add nsw i64 %indvar.2, 1
+  %exitcond.2 = icmp eq i64 %indvar.next.2, %N
+  br i1 %exitcond.2, label %return, label %for.i.2
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; C-H-E-C-K: Valid Region for Scop: for.i.1 => return
+; This one is currently not completely detected due to the PHI node in
+; for.i.2 causing a 'PHI node in exit BB' error for the first loop. This should
+; be fixed at some point. Such test cases do not really show up for us, as
+; the -loop-simplify pass always inserts a preheader as in the test case below.
+
+; Two sequential loops with a basic block in between.
+;
+;     void f(long A[], long N) {
+;       long i;
+;
+;       for (i = 0; i < N; ++i)
+;         A[i] = i;
+; preheader:
+;       ;
+;
+;       for (i = 0; i < N; ++i)
+;         A[i] = i;
+;     }
+
+define void @f2(i64* %A, i64 %N) nounwind {
+; CHECK-LABEL: 'Polly - Detect static control parts (SCoPs)' for function 'f2'
+entry:
+  fence seq_cst
+  br label %for.i.1
+
+for.i.1:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.i.1 ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %preheader, label %for.i.1
+
+preheader:
+  br label %for.i.2
+
+for.i.2:
+  %indvar.2 = phi i64 [ 0, %preheader ], [ %indvar.next.2, %for.i.2 ]
+  %scevgep.2 = getelementptr i64* %A, i64 %indvar.2
+  store i64 %indvar.2, i64* %scevgep.2
+  %indvar.next.2 = add nsw i64 %indvar.2, 1
+  %exitcond.2 = icmp eq i64 %indvar.next.2, %N
+  br i1 %exitcond.2, label %return, label %for.i.2
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Valid Region for Scop: for.i.1 => return
diff --git a/rc1/test/ScopDetect/simple_loop.ll b/rc1/test/ScopDetect/simple_loop.ll
new file mode 100644
index 0000000..7485b5f
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_loop.ll
@@ -0,0 +1,31 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;   for (i = 0; i < N; ++i)
+;     A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br label %for.i
+
+for.i:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Valid Region for Scop: for.i => return
diff --git a/rc1/test/ScopDetect/simple_loop_non_single_entry.ll b/rc1/test/ScopDetect/simple_loop_non_single_entry.ll
new file mode 100644
index 0000000..3746d2e
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_loop_non_single_entry.ll
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;
+;  if (true)
+;    goto loop;
+;  else
+;    goto loop;
+;
+; loop:
+;   for (i = 0; i < N; ++i)
+;     A[i] = i;
+; }
+
+; We will not detect this scop, as the loop is not in -loop-simplify form.
+
+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) nounwind {
+entry:
+  fence seq_cst
+  br i1 true, label %then, label %else
+
+then:
+  br label %for.i
+
+else:
+  br label %for.i
+
+for.i:
+  %indvar = phi i64 [ 0, %then ], [ 0, %else], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK-NOT: Valid Region for Scop
diff --git a/rc1/test/ScopDetect/simple_loop_non_single_exit.ll b/rc1/test/ScopDetect/simple_loop_non_single_exit.ll
new file mode 100644
index 0000000..77288db
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_loop_non_single_exit.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;   if (true)
+;     for (i = 0; i < N; ++i)
+;       A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br label %next
+
+next:
+  br i1 true, label %for.i, label %return
+
+for.i:
+  %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Valid Region for Scop: next => return
diff --git a/rc1/test/ScopDetect/simple_loop_non_single_exit_2.ll b/rc1/test/ScopDetect/simple_loop_non_single_exit_2.ll
new file mode 100644
index 0000000..d444d59
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_loop_non_single_exit_2.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;   if (true)
+;     if (true)
+;       for (i = 0; i < N; ++i)
+;         A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br i1 true, label %next, label %return
+
+next:
+  br i1 true, label %for.i, label %return
+
+for.i:
+  %indvar = phi i64 [ 0, %next], [ %indvar.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Valid Region for Scop: next => return
diff --git a/rc1/test/ScopDetect/simple_loop_two_phi_nodes.ll b/rc1/test/ScopDetect/simple_loop_two_phi_nodes.ll
new file mode 100644
index 0000000..e7396b2
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_loop_two_phi_nodes.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SCEV
+
+; void f(long A[], long N) {
+;   long i;
+;   long i_non_canonical = 1;
+;   for (i = 0; i < N; ++i) {
+;     A[i] = i_non_canonical;
+;     i_non_canonical += 1;
+;   }
+; }
+
+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) nounwind {
+entry:
+  %cmp = icmp sgt i64 %N, 0
+  br i1 %cmp, label %for.i, label %return
+
+for.i:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.i ]
+  %indvar_non_canonical = phi i64 [ 1, %entry ], [ %indvar_non_canonical.next, %for.i ]
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar_non_canonical, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %indvar_non_canonical.next = add nsw i64 %indvar_non_canonical, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  ret void
+}
+
+; CHECK-NOT: Valid Region for Scop
+; CHECK-SCEV: Valid Region for Scop: for.i => return
diff --git a/rc1/test/ScopDetect/simple_loop_with_param.ll b/rc1/test/ScopDetect/simple_loop_with_param.ll
new file mode 100644
index 0000000..d117213
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_loop_with_param.ll
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -basicaa -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-detect -analyze -polly-codegen-scev < %s | FileCheck -check-prefix=CHECK-SCEV %s
+
+; void f(long A[], long N, long *init_ptr) {
+;   long i, j;
+;   long i_non_canonical;
+;
+;   for (i = 0; i < N; ++i) {
+;     init = *init_ptr;
+;     i_non_canonical = init;
+;     for (i = 0; i < N; ++i) {
+;       A[i] = i_non_canonical;
+;       i_non_canonical += 1;
+;     }
+;   }
+; }
+
+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* noalias %A, i64 %N, i64* noalias %init_ptr) nounwind {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:
+  %init = load i64* %init_ptr
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %indvar.j.non_canonical = phi i64 [ %init, %entry.next ], [ %indvar.j.non_canonical.next, %for.j ]
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %indvar.j.non_canonical, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %indvar.j.non_canonical.next = add nsw i64 %indvar.j.non_canonical, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:
+  ret void
+}
+
+; CHECK-NOT: Valid Region for Scop
+; CHECK-SCEV: Valid Region for Scop: for.j => for.i.end
diff --git a/rc1/test/ScopDetect/simple_loop_with_param_2.ll b/rc1/test/ScopDetect/simple_loop_with_param_2.ll
new file mode 100644
index 0000000..5c2890d
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_loop_with_param_2.ll
@@ -0,0 +1,48 @@
+; RUN: opt %loadPolly -basicaa -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     init = *init_ptr;
+;     for (i = 0; i < N; ++i) {
+;       A[i] = init + 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* noalias %A, i64 %N, i64* noalias %init_ptr) nounwind {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:
+  %init = load i64* %init_ptr
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %init_plus_two = add i64 %init, 2
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_plus_two, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:
+  ret void
+}
+
+; CHECK: Valid Region for Scop: for.i => return
diff --git a/rc1/test/ScopDetect/simple_non_single_entry.ll b/rc1/test/ScopDetect/simple_non_single_entry.ll
new file mode 100644
index 0000000..cd355f5
--- /dev/null
+++ b/rc1/test/ScopDetect/simple_non_single_entry.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly -polly-detect-scops-in-regions-without-loops -polly-detect -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-detect-scops-in-regions-without-loops -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; void f(long A[], long N) {
+;   long i;
+;
+;  if (true){
+;    i = 0;
+;    goto next;
+;  }else{
+;    i = 1;
+;    goto next;
+; }
+;
+; next:
+;  if (true)
+;    goto for.i;
+;  else
+;    goto for.i;
+;
+; for.i:
+;   for (i = 0; i < N; ++i)
+;     A[i] = 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* %A, i64 %N) nounwind {
+entry:
+  fence seq_cst
+  br i1 true, label %then1, label %else1
+
+then1:
+  br label %next
+
+else1:
+  br label %next
+
+next:
+  br i1 true, label %then, label %else
+
+then:
+  br label %for.i.head
+
+else:
+  br label %for.i.head
+
+for.i.head:
+  br label %for.i.head1
+
+for.i.head1:
+  br label %for.i
+
+for.i:
+  %indvar = phi i64 [ 0, %for.i.head1], [ %indvar.next, %for.i ]
+  fence seq_cst
+  %scevgep = getelementptr i64* %A, i64 %indvar
+  store i64 %indvar, i64* %scevgep
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for.i
+
+return:
+  fence seq_cst
+  ret void
+}
+
+; CHECK: Valid Region for Scop: next => for.i.head1
diff --git a/rc1/test/ScopDetect/skip_function_attribute.ll b/rc1/test/ScopDetect/skip_function_attribute.ll
new file mode 100644
index 0000000..9d181fe
--- /dev/null
+++ b/rc1/test/ScopDetect/skip_function_attribute.ll
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
+;
+; Verify polly skips this function
+;
+; CHECK-NOT: Valid Region for Scop
+;
+;    void polly_skip_me(int *A, int N) {
+;      for (int i = 0; i < N; i++)
+;        A[i] = A[i] * A[i] + A[i];
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @polly_skip_me(i32* %A, i32 %N) #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  %cmp1 = icmp sgt i32 %N, 0
+  br i1 %cmp1, label %for.body.preheader, label %for.end
+
+for.body.preheader:                               ; preds = %entry.split
+  br label %for.body
+
+for.body:                                         ; preds = %for.body.preheader, %for.body
+  %i.02 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.02
+  %tmp = load i32* %arrayidx, align 4
+  %mul = mul nsw i32 %tmp, %tmp
+  %add = add nsw i32 %mul, %tmp
+  %arrayidx3 = getelementptr inbounds i32* %A, i32 %i.02
+  store i32 %add, i32* %arrayidx3, align 4
+  %inc = add nsw i32 %i.02, 1
+  %cmp = icmp slt i32 %inc, %N
+  br i1 %cmp, label %for.body, label %for.end.loopexit
+
+for.end.loopexit:                                 ; preds = %for.body
+  br label %for.end
+
+for.end:                                          ; preds = %for.end.loopexit, %entry.split
+  ret void
+}
+
+attributes #0 = { "polly.skip.fn" }
diff --git a/rc1/test/ScopDetectionDiagnostics/ReportFuncCall-01.ll b/rc1/test/ScopDetectionDiagnostics/ReportFuncCall-01.ll
new file mode 100644
index 0000000..81c0f62
--- /dev/null
+++ b/rc1/test/ScopDetectionDiagnostics/ReportFuncCall-01.ll
@@ -0,0 +1,67 @@
+; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -analyze < %s 2>&1 | FileCheck %s
+
+; #define N 1024
+; double invalidCall(double A[N]);
+;
+; void a(double A[N], int n) {
+;   for (int i=0; i<n; ++i) {
+;     A[i] = invalidCall(A);
+;   }
+; }
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @a(double* %A, i32 %n) #0 {
+entry:
+  %cmp1 = icmp sgt i32 %n, 0, !dbg !10
+  br i1 %cmp1, label %for.body.lr.ph, label %for.end, !dbg !10
+
+for.body.lr.ph:                                   ; preds = %entry
+  %0 = zext i32 %n to i64
+  br label %for.body, !dbg !10
+
+for.body:                                         ; preds = %for.body, %for.body.lr.ph
+  %indvar = phi i64 [ 0, %for.body.lr.ph ], [ %indvar.next, %for.body ]
+  %arrayidx = getelementptr double* %A, i64 %indvar, !dbg !12
+  %call = tail call double @invalidCall(double* %A) #2, !dbg !12
+  store double %call, double* %arrayidx, align 8, !dbg !12, !tbaa !14
+  %indvar.next = add i64 %indvar, 1, !dbg !10
+  %exitcond = icmp eq i64 %indvar.next, %0, !dbg !10
+  br i1 %exitcond, label %for.end.loopexit, label %for.body, !dbg !10
+
+for.end.loopexit:                                 ; preds = %for.body
+  br label %for.end
+
+for.end:                                          ; preds = %for.end.loopexit, %entry
+  ret void, !dbg !18
+}
+
+declare double @invalidCall(double*) #1
+
+; CHECK: remark: ReportFuncCall.c:4:8: The following errors keep this region from being a Scop.
+; CHECK: remark: ReportFuncCall.c:5:12: This function call cannot be handeled. Try to inline it.
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7, !8}
+!llvm.ident = !{!9}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5.0 ", i1 true, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !"", i32 2} ; [ DW_TAG_compile_unit ] [/home/simbuerg/Projekte/llvm/tools/polly/test/ScopDetectionDiagnostics/ReportFuncCall.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"ReportFuncCall.c", metadata !"/home/simbuerg/Projekte/llvm/tools/polly/test/ScopDetectionDiagnostics"}
+!2 = metadata !{}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"a", metadata !"a", metadata !"", i32 3, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, void (double*, i32)* @a, null, null, metadata !2, i32 3} ; [ DW_TAG_subprogram ] [line 3] [def] [a]
+!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [/home/simbuerg/Projekte/llvm/tools/polly/test/ScopDetectionDiagnostics/ReportFuncCall.c]
+!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !2, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!8 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
+!9 = metadata !{metadata !"clang version 3.5.0 "}
+!10 = metadata !{i32 4, i32 8, metadata !11, null}
+!11 = metadata !{i32 786443, metadata !1, metadata !4, i32 4, i32 3, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [/home/simbuerg/Projekte/llvm/tools/polly/test/ScopDetectionDiagnostics/ReportFuncCall.c]
+!12 = metadata !{i32 5, i32 12, metadata !13, null}
+!13 = metadata !{i32 786443, metadata !1, metadata !11, i32 4, i32 27, i32 0, i32 1} ; [ DW_TAG_lexical_block ] [/home/simbuerg/Projekte/llvm/tools/polly/test/ScopDetectionDiagnostics/ReportFuncCall.c]
+!14 = metadata !{metadata !15, metadata !15, i64 0}
+!15 = metadata !{metadata !"double", metadata !16, i64 0}
+!16 = metadata !{metadata !"omnipotent char", metadata !17, i64 0}
+!17 = metadata !{metadata !"Simple C/C++ TBAA"}
+!18 = metadata !{i32 7, i32 1, metadata !4, null}
diff --git a/rc1/test/ScopDetectionDiagnostics/ReportVariantBasePtr-01.ll b/rc1/test/ScopDetectionDiagnostics/ReportVariantBasePtr-01.ll
new file mode 100644
index 0000000..259a96f
--- /dev/null
+++ b/rc1/test/ScopDetectionDiagnostics/ReportVariantBasePtr-01.ll
@@ -0,0 +1,99 @@
+; RUN: opt %loadPolly -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s
+
+; struct b {
+;   double **b;
+; };
+;
+; void a(struct b *A) {
+;   for (int i=0; i<32; i++)
+;     A->b[i] = 0;
+; }
+
+; CHECK: remark: ReportVariantBasePtr01.c:6:8: The following errors keep this region from being a Scop.
+; CHECK: remark: ReportVariantBasePtr01.c:7:5: The base address of this array is not invariant inside the loop
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.b = type { double** }
+
+define void @a(%struct.b* nocapture readonly %A) #0 {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  tail call void @llvm.dbg.value(metadata !{%struct.b* %A}, i64 0, metadata !16), !dbg !23
+  tail call void @llvm.dbg.value(metadata !24, i64 0, metadata !17), !dbg !25
+  %b = getelementptr inbounds %struct.b* %A, i64 0, i32 0, !dbg !26
+  br label %for.body, !dbg !27
+
+for.body:                                         ; preds = %for.body, %entry.split
+  %indvar4 = phi i64 [ %indvar.next, %for.body ], [ 0, %entry.split ]
+  %0 = mul i64 %indvar4, 4, !dbg !26
+  %1 = add i64 %0, 3, !dbg !26
+  %2 = add i64 %0, 2, !dbg !26
+  %3 = add i64 %0, 1, !dbg !26
+  %4 = load double*** %b, align 8, !dbg !26, !tbaa !28
+  %arrayidx = getelementptr double** %4, i64 %0, !dbg !26
+  store double* null, double** %arrayidx, align 8, !dbg !26, !tbaa !33
+  %5 = load double*** %b, align 8, !dbg !26, !tbaa !28
+  %arrayidx.1 = getelementptr double** %5, i64 %3, !dbg !26
+  store double* null, double** %arrayidx.1, align 8, !dbg !26, !tbaa !33
+  %6 = load double*** %b, align 8, !dbg !26, !tbaa !28
+  %arrayidx.2 = getelementptr double** %6, i64 %2, !dbg !26
+  store double* null, double** %arrayidx.2, align 8, !dbg !26, !tbaa !33
+  %7 = load double*** %b, align 8, !dbg !26, !tbaa !28
+  %arrayidx.3 = getelementptr double** %7, i64 %1, !dbg !26
+  store double* null, double** %arrayidx.3, align 8, !dbg !26, !tbaa !33
+  %indvar.next = add i64 %indvar4, 1, !dbg !27
+  %exitcond = icmp eq i64 %indvar.next, 8, !dbg !27
+  br i1 %exitcond, label %for.end, label %for.body, !dbg !27
+
+for.end:                                          ; preds = %for.body
+  ret void, !dbg !34
+}
+
+declare void @llvm.dbg.value(metadata, i64, metadata) #1
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!20, !21}
+!llvm.ident = !{!22}
+
+!0 = metadata !{i32 786449, metadata !1, i32 12, metadata !"clang version 3.5.0 ", i1 true, metadata !"", i32 0, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2, metadata !"", i32 1} ; [ DW_TAG_compile_unit ] [test/ScopDetectionDiagnostics/ReportVariantBasePtr01.c] [DW_LANG_C99]
+!1 = metadata !{metadata !"ReportVariantBasePtr01.c", metadata !"test/ScopDetectionDiagnostics"}
+!2 = metadata !{}
+!3 = metadata !{metadata !4}
+!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"a", metadata !"a", metadata !"", i32 5, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 true, void (%struct.b*)* @a, null, null, metadata !15, i32 5} ; [ DW_TAG_subprogram ] [line 5] [def] [a]
+!5 = metadata !{i32 786473, metadata !1}          ; [ DW_TAG_file_type ] [test/ScopDetectionDiagnostics/ReportVariantBasePtr01.c]
+!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
+!7 = metadata !{null, metadata !8}
+!8 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from b]
+!9 = metadata !{i32 786451, metadata !1, null, metadata !"b", i32 1, i64 64, i64 64, i32 0, i32 0, null, metadata !10, i32 0, null, null, null} ; [ DW_TAG_structure_type ] [b] [line 1, size 64, align 64, offset 0] [def] [from ]
+!10 = metadata !{metadata !11}
+!11 = metadata !{i32 786445, metadata !1, metadata !9, metadata !"b", i32 2, i64 64, i64 64, i64 0, i32 0, metadata !12} ; [ DW_TAG_member ] [b] [line 2, size 64, align 64, offset 0] [from ]
+!12 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !13} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
+!13 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !14} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from double]
+!14 = metadata !{i32 786468, null, null, metadata !"double", i32 0, i64 64, i64 64, i64 0, i32 0, i32 4} ; [ DW_TAG_base_type ] [double] [line 0, size 64, align 64, offset 0, enc DW_ATE_float]
+!15 = metadata !{metadata !16, metadata !17}
+!16 = metadata !{i32 786689, metadata !4, metadata !"A", metadata !5, i32 16777221, metadata !8, i32 0, i32 0} ; [ DW_TAG_arg_variable ] [A] [line 5]
+!17 = metadata !{i32 786688, metadata !18, metadata !"i", metadata !5, i32 6, metadata !19, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [i] [line 6]
+!18 = metadata !{i32 786443, metadata !1, metadata !4, i32 6, i32 3, i32 0, i32 0} ; [ DW_TAG_lexical_block ] [test/ScopDetectionDiagnostics/ReportVariantBasePtr01.c]
+!19 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
+!20 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
+!21 = metadata !{i32 2, metadata !"Debug Info Version", i32 1}
+!22 = metadata !{metadata !"clang version 3.5.0 "}
+!23 = metadata !{i32 5, i32 18, metadata !4, null}
+!24 = metadata !{i32 0}
+!25 = metadata !{i32 6, i32 12, metadata !18, null}
+!26 = metadata !{i32 7, i32 5, metadata !18, null}
+!27 = metadata !{i32 6, i32 8, metadata !18, null}
+!28 = metadata !{metadata !29, metadata !30, i64 0}
+!29 = metadata !{metadata !"b", metadata !30, i64 0}
+!30 = metadata !{metadata !"any pointer", metadata !31, i64 0}
+!31 = metadata !{metadata !"omnipotent char", metadata !32, i64 0}
+!32 = metadata !{metadata !"Simple C/C++ TBAA"}
+!33 = metadata !{metadata !30, metadata !30, i64 0}
+!34 = metadata !{i32 8, i32 1, metadata !4, null} ; [ DW_TAG_imported_declaration ]
diff --git a/rc1/test/ScopInfo/20111108-Parameter-not-detected.ll b/rc1/test/ScopInfo/20111108-Parameter-not-detected.ll
new file mode 100644
index 0000000..c4f62ea
--- /dev/null
+++ b/rc1/test/ScopInfo/20111108-Parameter-not-detected.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -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-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @foo()
+
+define i32 @main(i8* %A) nounwind uwtable {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc5, %entry
+  %indvar_out = phi i64 [ %indvar_out.next, %for.inc5 ], [ 0, %entry ]
+  call void @foo()
+  %tmp = add i64 %indvar_out, 2
+  %exitcond5 = icmp ne i64 %indvar_out, 1023
+  br i1 %exitcond5, label %for.body, label %for.end7
+
+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 ]
+  %exitcond = icmp ne i64 %indvar, 1023
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %tmp1 = add i64 %tmp, %indvar
+  %cmp4 = icmp sgt i64 %tmp1, 1000
+  br i1 %cmp4, label %if.then, label %if.end
+
+if.then:                                          ; preds = %for.body3
+  %arrayidx = getelementptr i8* %A, i64 %indvar
+  store i8 5, i8* %arrayidx
+  br label %if.end
+
+if.end:                                           ; preds = %if.end.single_exit
+  br label %for.inc
+
+for.inc:                                          ; preds = %if.end
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc5
+
+for.inc5:                                         ; preds = %for.end
+  %indvar_out.next = add i64 %indvar_out, 1
+  br label %for.cond
+
+for.end7:                                         ; preds = %for.cond
+  ret i32 0
+}
+
+; CHECK: Context:
+; CHECK: p0: {0,+,1}<%for.cond>
+
+; CHECK: Domain :=
+; CHECK: [p_0] -> { Stmt_if_then[i0] : i0 >= 0 and i0 <= 1022 and i0 >= 999 - p_0 };
+
diff --git a/rc1/test/ScopInfo/2012-03-16-Crash-because-of-unsigned-in-scev.ll b/rc1/test/ScopInfo/2012-03-16-Crash-because-of-unsigned-in-scev.ll
new file mode 100644
index 0000000..64cff17
--- /dev/null
+++ b/rc1/test/ScopInfo/2012-03-16-Crash-because-of-unsigned-in-scev.ll
@@ -0,0 +1,32 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32"
+target triple = "hexagon-unknown-linux-gnu"
+
+@array = external global [64 x i8], align 8
+
+define void @foo(i32* %A) nounwind {
+entry:
+  br label %if.then132
+
+if.then132:
+  %loaded = load i32* %A
+  %0 = icmp ugt i32 %loaded, 10
+  %umax = select i1 %0, i32 %loaded, i32 10
+  br label %do.body
+
+do.body:
+  %indvar = phi i32 [ %3, %do.body ], [ 0, %if.then132 ]
+  %1 = add i32 0, %umax
+  %2 = sub i32 %1, %indvar
+  %arrayidx = getelementptr [64 x i8]* @array, i32 0, i32 %2
+  store i8 1, i8* %arrayidx, align 1
+  %3 = add i32 %indvar, 1
+  %exitcond = icmp eq i32 %3, 20
+  br i1 %exitcond, label %for.end, label %do.body
+
+for.end:
+  ret void
+}
+
+;CHECK: p0: (10 umax %loaded)
diff --git a/rc1/test/ScopInfo/Alias-0.ll b/rc1/test/ScopInfo/Alias-0.ll
new file mode 100755
index 0000000..8474131
--- /dev/null
+++ b/rc1/test/ScopInfo/Alias-0.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+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
diff --git a/rc1/test/ScopInfo/Alias-1.ll b/rc1/test/ScopInfo/Alias-1.ll
new file mode 100755
index 0000000..c8f0093
--- /dev/null
+++ b/rc1/test/ScopInfo/Alias-1.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+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
diff --git a/rc1/test/ScopInfo/Alias-2.ll b/rc1/test/ScopInfo/Alias-2.ll
new file mode 100755
index 0000000..3a70bf4
--- /dev/null
+++ b/rc1/test/ScopInfo/Alias-2.ll
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+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
diff --git a/rc1/test/ScopInfo/Alias-3.ll b/rc1/test/ScopInfo/Alias-3.ll
new file mode 100755
index 0000000..7ad9ad6
--- /dev/null
+++ b/rc1/test/ScopInfo/Alias-3.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+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
diff --git a/rc1/test/ScopInfo/Alias-4.ll b/rc1/test/ScopInfo/Alias-4.ll
new file mode 100755
index 0000000..a47f799
--- /dev/null
+++ b/rc1/test/ScopInfo/Alias-4.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -analyze < %s -stats 2>&1 | not FileCheck %s
+; REQUIRES: asserts
+
+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
diff --git a/rc1/test/ScopInfo/bug_2010_10_22.ll b/rc1/test/ScopInfo/bug_2010_10_22.ll
new file mode 100755
index 0000000..a9ba276
--- /dev/null
+++ b/rc1/test/ScopInfo/bug_2010_10_22.ll
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -polly-analyze-ir %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 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
+}
diff --git a/rc1/test/ScopInfo/bug_2011_1_5.ll b/rc1/test/ScopInfo/bug_2011_1_5.ll
new file mode 100755
index 0000000..4d17c98
--- /dev/null
+++ b/rc1/test/ScopInfo/bug_2011_1_5.ll
@@ -0,0 +1,60 @@
+; RUN: opt %loadPolly -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.
+
+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
+}
diff --git a/rc1/test/ScopInfo/bug_scev_not_fully_eval.ll b/rc1/test/ScopInfo/bug_scev_not_fully_eval.ll
new file mode 100644
index 0000000..fa8098c
--- /dev/null
+++ b/rc1/test/ScopInfo/bug_scev_not_fully_eval.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-detect -analyze  < %s | not 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"
+
+@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:
diff --git a/rc1/test/ScopInfo/cond_constant_in_loop.ll b/rc1/test/ScopInfo/cond_constant_in_loop.ll
new file mode 100644
index 0000000..a71ec46
--- /dev/null
+++ b/rc1/test/ScopInfo/cond_constant_in_loop.ll
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+;void f(long a[], long N, long M) {
+;  long i, j, k;
+;  for (j = 0; j < M; ++j)
+;    if (true)
+;      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 ], [ %2, %bb3 ]        ; <i64> [#uses=5]
+  %scevgep = getelementptr i64* %a, i64 %1        ; <i64*> [#uses=2]
+  br i1 true, 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
+  %2 = add nsw i64 %1, 1                          ; <i64> [#uses=2]
+  %exitcond = icmp eq i64 %2, %M                  ; <i1> [#uses=1]
+  br i1 %exitcond, label %return, label %bb
+
+return:                                           ; preds = %bb3, %entry
+  ret void
+}
+
+; CHECK: Stmt_bb1
+; CHECK:   Domain :=
+; CHECK:     [M, N] -> { Stmt_bb1[i0] : i0 >= 0 and i0 <= -1 + M };
+; CHECK: Stmt_bb2
+; CHECK:   Domain :=
+; CHECK:     [M, N] -> { Stmt_bb2[i0] : 1 = 0 };
+
diff --git a/rc1/test/ScopInfo/cond_in_loop.ll b/rc1/test/ScopInfo/cond_in_loop.ll
new file mode 100644
index 0000000..55ab6dc
--- /dev/null
+++ b/rc1/test/ScopInfo/cond_in_loop.ll
@@ -0,0 +1,48 @@
+; RUN: opt %loadPolly -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!
diff --git a/rc1/test/ScopInfo/constant_start_integer.ll b/rc1/test/ScopInfo/constant_start_integer.ll
new file mode 100644
index 0000000..f28b9d8
--- /dev/null
+++ b/rc1/test/ScopInfo/constant_start_integer.ll
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(float *input) {
+;   for (int j = 0; j < 8; j++) {
+;     //SCoP begin
+;     for (int i = 0; i < 63; i++) {
+;       float x = input[j * 64 + i + 1];
+;       input[j * 64 + i + 0] = x * x;
+;     }
+;   }
+; }
+
+; CHECK  p0: {0,+,256}<%for.cond1.preheader>
+; CHECK-NOT: p1
+
+; CHECK: ReadAccess
+; CHECK:   [p_0] -> { Stmt_for_body3[i0] -> MemRef_input[o0] : 4o0 = 4 + p_0 + 4i0 };
+; CHECK: MustWriteAccess
+; CHECK:   [p_0] -> { Stmt_for_body3[i0] -> MemRef_input[o0] : 4o0 = p_0 + 4i0 };
+
+define void @foo(float* nocapture %input) {
+entry:
+  br label %for.cond1.preheader
+
+for.cond1.preheader:                              ; preds = %for.inc10, %entry
+  %j.021 = phi i64 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %mul = shl nsw i64 %j.021, 6
+  br label %for.body3
+
+for.body3:                                        ; preds = %for.body3, %for.cond1.preheader
+  %i.020 = phi i64 [ 0, %for.cond1.preheader ], [ %inc, %for.body3 ]
+  %add = add nsw i64 %i.020, %mul
+  %add4 = add nsw i64 %add, 1
+  %arrayidx = getelementptr inbounds float* %input, i64 %add4
+  %0 = load float* %arrayidx, align 8
+  %mul5 = fmul float %0, %0
+  %arrayidx9 = getelementptr inbounds float* %input, i64 %add
+  store float %mul5, float* %arrayidx9, align 8
+  %inc = add nsw i64 %i.020, 1
+  %exitcond = icmp eq i64 %inc, 63
+  br i1 %exitcond, label %for.inc10, label %for.body3
+
+for.inc10:                                        ; preds = %for.body3
+  %inc11 = add nsw i64 %j.021, 1
+  %exitcond22 = icmp eq i64 %inc11, 8
+  fence seq_cst
+  br i1 %exitcond22, label %for.end12, label %for.cond1.preheader
+
+for.end12:                                        ; preds = %for.inc10
+  ret void
+}
diff --git a/rc1/test/ScopInfo/delinearize-together-all-data-refs.ll b/rc1/test/ScopInfo/delinearize-together-all-data-refs.ll
new file mode 100644
index 0000000..97a80f2
--- /dev/null
+++ b/rc1/test/ScopInfo/delinearize-together-all-data-refs.ll
@@ -0,0 +1,77 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize -polly-codegen-scev < %s | FileCheck %s
+
+; void foo(long n, long m, long o, double A[n][m][o]) {
+;   for (long i = 0; i < n-3; i++)
+;     for (long j = 4; j < m; j++)
+;       for (long k = 0; k < o-7; k++) {
+;         A[i+3][j-4][k+7] = 1.0;
+;         A[i][0][k] = 2.0;
+;       }
+; }
+
+; CHECK: [n, m, o] -> { Stmt_for_body6[i0, i1, i2] -> MemRef_A[3 + i0, i1, 7 + i2] };
+; CHECK: [n, m, o] -> { Stmt_for_body6[i0, i1, i2] -> MemRef_A[i0, 0, i2] };
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define void @foo(i64 %n, i64 %m, i64 %o, double* nocapture %A) {
+entry:
+  %cmp35 = icmp sgt i64 %n, 0
+  br i1 %cmp35, label %for.cond1.preheader.lr.ph, label %for.end18
+
+for.cond1.preheader.lr.ph:                        ; preds = %entry
+  %cmp233 = icmp sgt i64 %m, 0
+  %cmp531 = icmp sgt i64 %o, 0
+  %0 = mul nuw i64 %o, %m
+  br label %for.cond1.preheader
+
+for.cond1.preheader:                              ; preds = %for.inc16, %for.cond1.preheader.lr.ph
+  %i.036 = phi i64 [ 0, %for.cond1.preheader.lr.ph ], [ %inc17, %for.inc16 ]
+  br i1 %cmp233, label %for.cond4.preheader.lr.ph, label %for.inc16
+
+for.cond4.preheader.lr.ph:                        ; preds = %for.cond1.preheader
+  %add7 = add nsw i64 %i.036, 3
+  %1 = mul nsw i64 %add7, %0
+  %add = add i64 %1, 7
+  %2 = mul nsw i64 %i.036, %0
+  br label %for.cond4.preheader
+
+for.cond4.preheader:                              ; preds = %for.inc13, %for.cond4.preheader.lr.ph
+  %j.034 = phi i64 [ 4, %for.cond4.preheader.lr.ph ], [ %inc14, %for.inc13 ]
+  br i1 %cmp531, label %for.body6.lr.ph, label %for.inc13
+
+for.body6.lr.ph:                                  ; preds = %for.cond4.preheader
+  %sub = add nsw i64 %j.034, -4
+  %3 = mul nsw i64 %sub, %o
+  %arrayidx.sum = add i64 %add, %3
+  br label %for.body6
+
+for.body6:                                        ; preds = %for.body6, %for.body6.lr.ph
+  %k.032 = phi i64 [ 0, %for.body6.lr.ph ], [ %inc, %for.body6 ]
+  %arrayidx8.sum = add i64 %arrayidx.sum, %k.032
+  %arrayidx9 = getelementptr inbounds double* %A, i64 %arrayidx8.sum
+  store double 1.000000e+00, double* %arrayidx9, align 8
+  %arrayidx10.sum = add i64 %k.032, %2
+  %arrayidx12 = getelementptr inbounds double* %A, i64 %arrayidx10.sum
+  store double 2.000000e+00, double* %arrayidx12, align 8
+  %inc = add nsw i64 %k.032, 1
+  %osub = sub nsw i64 %o, 7
+  %exitcond = icmp eq i64 %inc, %osub
+  br i1 %exitcond, label %for.inc13, label %for.body6
+
+for.inc13:                                        ; preds = %for.body6, %for.cond4.preheader
+  %inc14 = add nsw i64 %j.034, 1
+  %exitcond37 = icmp eq i64 %inc14, %m
+  br i1 %exitcond37, label %for.inc16, label %for.cond4.preheader
+
+for.inc16:                                        ; preds = %for.inc13, %for.cond1.preheader
+  %inc17 = add nsw i64 %i.036, 1
+  %nsub = sub nsw i64 %n, 3
+  %exitcond38 = icmp eq i64 %inc17, %nsub
+  br i1 %exitcond38, label %for.end18, label %for.cond1.preheader
+
+for.end18:                                        ; preds = %for.inc16, %entry
+  ret void
+}
diff --git a/rc1/test/ScopInfo/independent-blocks-never-stop-on-big-scop.ll b/rc1/test/ScopInfo/independent-blocks-never-stop-on-big-scop.ll
new file mode 100644
index 0000000..f40c39a
--- /dev/null
+++ b/rc1/test/ScopInfo/independent-blocks-never-stop-on-big-scop.ll
@@ -0,0 +1,200 @@
+; RUN: opt %loadPolly -polly-independent %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @main() nounwind uwtable readnone {
+  %arr = alloca [100 x i32], align 16
+  br label %1
+
+; <label>:1                                       ; preds = %1, %0
+  %indvars.iv3 = phi i64 [ 0, %0 ], [ %indvars.iv.next4, %1 ]
+  %2 = getelementptr inbounds [100 x i32]* %arr, i64 0, i64 %indvars.iv3
+  %3 = trunc i64 %indvars.iv3 to i32
+  store i32 %3, i32* %2, align 4, !tbaa !0
+  %indvars.iv.next4 = add i64 %indvars.iv3, 1
+  %lftr.wideiv5 = trunc i64 %indvars.iv.next4 to i32
+  %exitcond6 = icmp eq i32 %lftr.wideiv5, 100
+  br i1 %exitcond6, label %.preheader, label %1
+
+.preheader:                                       ; preds = %.preheader, %1
+  %indvars.iv = phi i64 [ %indvars.iv.next, %.preheader ], [ 0, %1 ]
+  %4 = getelementptr inbounds [100 x i32]* %arr, i64 0, i64 %indvars.iv
+  %5 = load i32* %4, align 4, !tbaa !0
+  %6 = xor i32 %5, -1
+  %7 = shl i32 %5, 15
+  %8 = add nsw i32 %7, %6
+  %9 = ashr i32 %8, 12
+  %10 = xor i32 %9, %8
+  %11 = mul i32 %10, 9
+  %12 = ashr i32 %11, 4
+  %13 = xor i32 %12, %11
+  %14 = mul nsw i32 %13, 20571
+  %15 = ashr i32 %14, 16
+  %16 = xor i32 %15, %14
+  %17 = xor i32 %16, -1
+  %18 = shl i32 %16, 15
+  %19 = add nsw i32 %18, %17
+  %20 = ashr i32 %19, 12
+  %21 = xor i32 %20, %19
+  %22 = mul i32 %21, 5
+  %23 = ashr i32 %22, 4
+  %24 = xor i32 %23, %22
+  %25 = mul nsw i32 %24, 20576
+  %26 = ashr i32 %25, 16
+  %27 = xor i32 %26, %25
+  %28 = xor i32 %27, -1
+  %29 = shl i32 %27, 15
+  %30 = add nsw i32 %29, %28
+  %31 = ashr i32 %30, 12
+  %32 = xor i32 %31, %30
+  %33 = mul i32 %32, 5
+  %34 = ashr i32 %33, 4
+  %35 = xor i32 %34, %33
+  %36 = mul nsw i32 %35, 2057
+  %37 = ashr i32 %36, 16
+  %38 = xor i32 %37, %36
+  %39 = xor i32 %38, -1
+  %40 = shl i32 %38, 15
+  %41 = add nsw i32 %40, %39
+  %42 = ashr i32 %41, 12
+  %43 = xor i32 %42, %41
+  %44 = mul i32 %43, 5
+  %45 = ashr i32 %44, 4
+  %46 = xor i32 %45, %44
+  %47 = mul nsw i32 %46, 20572
+  %48 = ashr i32 %47, 16
+  %49 = xor i32 %48, %47
+  %50 = xor i32 %49, -1
+  %51 = shl i32 %49, 15
+  %52 = add nsw i32 %51, %50
+  %53 = ashr i32 %52, 12
+  %54 = xor i32 %53, %52
+  %55 = mul i32 %54, 5
+  %56 = ashr i32 %55, 4
+  %57 = xor i32 %56, %55
+  %58 = mul nsw i32 %57, 2051
+  %59 = ashr i32 %58, 16
+  %60 = xor i32 %59, %58
+  %61 = xor i32 %60, -1
+  %62 = shl i32 %60, 15
+  %63 = add nsw i32 %62, %61
+  %64 = ashr i32 %63, 12
+  %65 = xor i32 %64, %63
+  %66 = mul i32 %65, 5
+  %67 = ashr i32 %66, 4
+  %68 = xor i32 %67, %66
+  %69 = mul nsw i32 %68, 2057
+  %70 = ashr i32 %69, 16
+  %71 = xor i32 %70, %69
+  %72 = xor i32 %71, -1
+  %73 = shl i32 %71, 15
+  %74 = add nsw i32 %73, %72
+  %75 = ashr i32 %74, 12
+  %76 = xor i32 %75, %74
+  %77 = mul i32 %76, 5
+  %78 = ashr i32 %77, 4
+  %79 = xor i32 %78, %77
+  %80 = mul nsw i32 %79, 205
+  %81 = ashr i32 %80, 17
+  %82 = xor i32 %81, %80
+  %83 = xor i32 %82, -1
+  %84 = shl i32 %82, 15
+  %85 = add nsw i32 %84, %83
+  %86 = ashr i32 %85, 12
+  %87 = xor i32 %86, %85
+  %88 = mul i32 %87, 5
+  %89 = ashr i32 %88, 4
+  %90 = xor i32 %89, %88
+  %91 = mul nsw i32 %90, 2057
+  %92 = ashr i32 %91, 16
+  %93 = xor i32 %92, %91
+  %94 = xor i32 %93, -1
+  %95 = shl i32 %93, 15
+  %96 = add nsw i32 %95, %94
+  %97 = ashr i32 %96, 12
+  %98 = xor i32 %97, %96
+  %99 = mul i32 %98, 5
+  %100 = ashr i32 %99, 3
+  %101 = xor i32 %100, %99
+  %102 = mul nsw i32 %101, 20571
+  %103 = ashr i32 %102, 16
+  %104 = xor i32 %103, %102
+  %105 = xor i32 %104, -1
+  %106 = shl i32 %104, 15
+  %107 = add nsw i32 %106, %105
+  %108 = ashr i32 %107, 12
+  %109 = xor i32 %108, %107
+  %110 = mul i32 %109, 5
+  %111 = ashr i32 %110, 4
+  %112 = xor i32 %111, %110
+  %113 = mul nsw i32 %112, 2057
+  %114 = ashr i32 %113, 16
+  %115 = xor i32 %114, %113
+  %116 = xor i32 %115, -1
+  %117 = shl i32 %115, 15
+  %118 = add nsw i32 %117, %116
+  %119 = ashr i32 %118, 12
+  %120 = xor i32 %119, %118
+  %121 = mul i32 %120, 5
+  %122 = ashr i32 %121, 4
+  %123 = xor i32 %122, %121
+  %124 = mul nsw i32 %123, 20572
+  %125 = ashr i32 %124, 16
+  %126 = xor i32 %125, %124
+  %127 = xor i32 %126, -1
+  %128 = shl i32 %126, 15
+  %129 = add nsw i32 %128, %127
+  %130 = ashr i32 %129, 12
+  %131 = xor i32 %130, %129
+  %132 = mul i32 %131, 5
+  %133 = ashr i32 %132, 4
+  %134 = xor i32 %133, %132
+  %135 = mul nsw i32 %134, 2057
+  %136 = ashr i32 %135, 16
+  %137 = xor i32 %136, %135
+  %138 = xor i32 %137, -1
+  %139 = shl i32 %137, 15
+  %140 = add nsw i32 %139, %138
+  %141 = ashr i32 %140, 12
+  %142 = xor i32 %141, %140
+  %143 = mul i32 %142, 5
+  %144 = ashr i32 %143, 4
+  %145 = xor i32 %144, %143
+  %146 = mul nsw i32 %145, 2057
+  %147 = ashr i32 %146, 16
+  %148 = xor i32 %147, %146
+  %149 = xor i32 %148, -1
+  %150 = shl i32 %148, 15
+  %151 = add nsw i32 %150, %149
+  %152 = ashr i32 %151, 12
+  %153 = xor i32 %152, %151
+  %154 = mul i32 %153, 5
+  %155 = ashr i32 %154, 4
+  %156 = xor i32 %155, %154
+  %157 = mul nsw i32 %156, 2057
+  %158 = ashr i32 %157, 16
+  %159 = xor i32 %158, %157
+  %160 = xor i32 %159, -1
+  %161 = shl i32 %159, 15
+  %162 = add nsw i32 %161, %160
+  %163 = ashr i32 %162, 12
+  %164 = xor i32 %163, %162
+  %165 = mul i32 %164, 5
+  %166 = ashr i32 %165, 4
+  %167 = xor i32 %166, %165
+  %168 = mul nsw i32 %167, 2057
+  %169 = ashr i32 %168, 16
+  %170 = xor i32 %169, %168
+  store i32 %170, i32* %4, align 4, !tbaa !0
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+  %exitcond = icmp eq i32 %lftr.wideiv, 100
+  br i1 %exitcond, label %171, label %.preheader
+
+; <label>:171                                     ; preds = %.preheader
+  ret i32 0
+}
+
+!0 = metadata !{metadata !"int", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
diff --git a/rc1/test/ScopInfo/integers.ll b/rc1/test/ScopInfo/integers.ll
new file mode 100644
index 0000000..f36bf1f
--- /dev/null
+++ b/rc1/test/ScopInfo/integers.ll
@@ -0,0 +1,123 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+; Check that we correctly convert integers to isl values.
+
+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"
+
+; Large positive integer
+define void @f(i1024* nocapture %a) nounwind {
+entry:
+  br label %bb
+
+bb:
+  %indvar = phi i1024 [ 0, %entry ], [ %indvar.next, %bb ]
+  %scevgep = getelementptr i1024* %a, i1024 %indvar
+  store i1024 %indvar, i1024* %scevgep, align 8
+  %indvar.next = add nsw i1024 %indvar, 1
+  %exitcond = icmp eq i1024 %indvar, 123456000000000000000000000
+; CHECK:  'bb => return' in function 'f'
+; CHECK: i0 <= 123456000000000000000000000
+  br i1 %exitcond, label %return, label %bb
+
+return:
+  ret void
+}
+
+; Normal positive integer
+define void @f2(i32* nocapture %a) nounwind {
+entry:
+  br label %bb
+
+bb:
+  %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ]
+  %scevgep = getelementptr i32* %a, i32 %indvar
+  store i32 %indvar, i32* %scevgep, align 8
+  %indvar.next = add nsw i32 %indvar, 1
+  %exitcond = icmp eq i32 %indvar, 123456
+; CHECK:  'bb => return' in function 'f2'
+; CHECK: i0 <= 123456
+  br i1 %exitcond, label %return, label %bb
+
+return:
+  ret void
+}
+
+; Normal negative integer
+define void @f3(i32* nocapture %a, i32 %n) nounwind {
+entry:
+  br label %bb
+
+bb:
+  %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ]
+  %scevgep = getelementptr i32* %a, i32 %indvar
+  store i32 %indvar, i32* %scevgep, align 8
+  %indvar.next = add nsw i32 %indvar, 1
+  %sub = sub i32 %n, 123456
+  %exitcond = icmp eq i32 %indvar, %sub
+; CHECK:  'bb => return' in function 'f3'
+; CHECK: -123456
+  br i1 %exitcond, label %return, label %bb
+
+return:
+  ret void
+}
+
+; Large negative integer
+define void @f4(i1024* nocapture %a, i1024 %n) nounwind {
+entry:
+  br label %bb
+
+bb:
+  %indvar = phi i1024 [ 0, %entry ], [ %indvar.next, %bb ]
+  %scevgep = getelementptr i1024* %a, i1024 %indvar
+  store i1024 %indvar, i1024* %scevgep, align 8
+  %indvar.next = add nsw i1024 %indvar, 1
+  %sub = sub i1024 %n, 123456000000000000000000000000000000
+; CHECK:  'bb => return' in function 'f4'
+; CHECK: -123456000000000000000000000000000000
+  %exitcond = icmp eq i1024 %indvar, %sub
+  br i1 %exitcond, label %return, label %bb
+
+return:
+  ret void
+}
+
+define void @f5(i1023* nocapture %a, i1023 %n) nounwind {
+entry:
+  br label %bb
+
+bb:
+  %indvar = phi i1023 [ 0, %entry ], [ %indvar.next, %bb ]
+  %scevgep = getelementptr i1023* %a, i1023 %indvar
+  store i1023 %indvar, i1023* %scevgep, align 8
+  %indvar.next = add nsw i1023 %indvar, 1
+  %sub = sub i1023 %n, 123456000000000000000000000000000000
+; CHECK:  'bb => return' in function 'f5'
+; CHECK: -123456000000000000000000000000000000
+  %exitcond = icmp eq i1023 %indvar, %sub
+  br i1 %exitcond, label %return, label %bb
+
+return:
+  ret void
+}
+
+; Tiny negative integer
+define void @f6(i3* nocapture %a, i3 %n) nounwind {
+entry:
+  br label %bb
+
+bb:
+  %indvar = phi i3 [ 0, %entry ], [ %indvar.next, %bb ]
+  %scevgep = getelementptr i3* %a, i3 %indvar
+  store i3 %indvar, i3* %scevgep, align 8
+  %indvar.next = add nsw i3 %indvar, 1
+  %sub = sub i3 %n, 3
+; CHECK:  'bb => return' in function 'f6'
+; CHECK: -3
+  %exitcond = icmp eq i3 %indvar, %sub
+  br i1 %exitcond, label %return, label %bb
+
+return:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/isl_aff_out_of_bounds.ll b/rc1/test/ScopInfo/isl_aff_out_of_bounds.ll
new file mode 100644
index 0000000..877b0d0
--- /dev/null
+++ b/rc1/test/ScopInfo/isl_aff_out_of_bounds.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -basicaa -polly-detect %s
+
+; Used to fail with:
+; ../../isl/isl_aff.c:591: position out of bounds
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare double @frexp(double)
+
+define void @vorbis_lsp_to_curve(float* %lsp, i32 %m) {
+entry:
+  %q.1.reg2mem = alloca float, align 4
+  br i1 undef, label %do.body, label %while.end
+
+do.body:                                          ; preds = %do.body, %entry
+  %ftmp.0 = phi float* [ %add.ptr, %do.body ], [ %lsp, %entry ]
+  %add.ptr = getelementptr inbounds float* %ftmp.0, i64 2
+  br i1 true, label %do.end, label %do.body
+
+do.end:                                           ; preds = %do.body
+  br i1 false, label %if.end.single_exit, label %if.then
+
+if.then:                                          ; preds = %do.end
+  %0 = load float* %add.ptr, align 4
+  store float %0, float* %q.1.reg2mem, align 4
+  br label %if.end.single_exit
+
+if.end.single_exit:                               ; preds = %do.end, %if.then
+  br label %if.end
+
+if.end:                                           ; preds = %if.end.single_exit
+  %q.1.reload = load float* %q.1.reg2mem, align 4
+  %conv31 = fpext float %q.1.reload to double
+  %call32 = call double @frexp(double %conv31)
+  unreachable
+
+while.end:                                        ; preds = %entry
+  ret void
+}
diff --git a/rc1/test/ScopInfo/loop_affine_bound_0.ll b/rc1/test/ScopInfo/loop_affine_bound_0.ll
new file mode 100644
index 0000000..b950b2f
--- /dev/null
+++ b/rc1/test/ScopInfo/loop_affine_bound_0.ll
@@ -0,0 +1,64 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+; 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)
+;       a[j][i] = 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
+
+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:  p0: %N
+; CHECK:  p1: %M
+; CHECK:  Statements {
+; CHECK:    Stmt_bb1
+; CHECK:          Domain :=
+; CHECK:              [N, M] -> { Stmt_bb1[i0, i1] : i0 >= 0 and i0 <= 2 + 4N + 7M and i1 >= 0 and i1 <= 1 + 5N and N >= 0 };
+; CHECK:          Scattering :=
+; CHECK:              [N, M] -> { Stmt_bb1[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK:          MustWriteAccess := [Reduction Type: NONE]
+; CHECK:              [N, M] -> { Stmt_bb1[i0, i1] -> MemRef_a[i0 + 128i1] };
+; CHECK:  }
diff --git a/rc1/test/ScopInfo/loop_affine_bound_1.ll b/rc1/test/ScopInfo/loop_affine_bound_1.ll
new file mode 100644
index 0000000..daa598a
--- /dev/null
+++ b/rc1/test/ScopInfo/loop_affine_bound_1.ll
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+;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: p0: %N
+; CHECK: p1: %M
+; CHECK: Statements {
+; CHECK:   Stmt_bb1
+; CHECK:         Domain :=
+; CHECK:             [N, M] -> { Stmt_bb1[i0, i1] : i0 >= 0 and i0 <= 2 + 4N + 7M and i1 >= 0 and i1 <= 1 + 5N - i0 and i0 <= 1 + 5N };
+; CHECK:         Scattering :=
+; CHECK:             [N, M] -> { Stmt_bb1[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK:         MustWriteAccess := [Reduction Type: NONE]
+; CHECK:             [N, M] -> { Stmt_bb1[i0, i1] -> MemRef_a[129i0 + 128i1] };
+; CHECK: }
diff --git a/rc1/test/ScopInfo/loop_affine_bound_2.ll b/rc1/test/ScopInfo/loop_affine_bound_2.ll
new file mode 100644
index 0000000..7392eaa
--- /dev/null
+++ b/rc1/test/ScopInfo/loop_affine_bound_2.ll
@@ -0,0 +1,74 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+; 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
+  %1 = mul i64 %M, 7
+  %2 = or i64 %0, 3
+  %3 = add nsw i64 %2, %1
+  %4 = icmp sgt i64 %3, 0
+  br i1 %4, label %bb.nph8, label %return
+
+bb.nph8:                                          ; preds = %entry
+  %tmp14 = mul i64 %M, 6
+  %tmp15 = add i64 %tmp14, -9
+  %tmp20 = add i64 %1, %0
+  %tmp21 = add i64 %tmp20, 3
+  %tmp25 = mul i64 %M, -6
+  %tmp26 = mul i64 %N, 5
+  %tmp27 = add i64 %tmp25, %tmp26
+  %tmp28 = add i64 %tmp27, 11
+  %tmp35 = add i64 %tmp26, 2
+  br label %bb
+
+bb:                                               ; preds = %bb3, %bb.nph8
+  %j.07 = phi i64 [ 0, %bb.nph8 ], [ %6, %bb3 ]
+  %tmp17 = mul i64 %j.07, 897
+  %tmp24 = mul i64 %j.07, -4
+  %tmp13 = add i64 %tmp24, %tmp28
+  %tmp30 = mul i64 %j.07, 7
+  %tmp33 = add i64 %tmp30, %tmp15
+  %tmp34 = mul i64 %j.07, 3
+  %tmp36 = add i64 %tmp34, %tmp35
+  %5 = icmp sgt i64 %tmp36, %tmp33
+  br i1 %5, label %bb1, label %bb3
+
+bb1:                                              ; preds = %bb1, %bb
+  %indvar = phi i64 [ 0, %bb ], [ %indvar.next, %bb1 ]
+  %tmp16 = add i64 %indvar, %tmp15
+  %scevgep = getelementptr [128 x i64]* %a, i64 %tmp16, i64 %tmp17
+  store i64 0, i64* %scevgep
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %tmp13
+  br i1 %exitcond, label %bb3, label %bb1
+
+bb3:                                              ; preds = %bb1, %bb
+  %6 = add nsw i64 %j.07, 1
+  %exitcond22 = icmp eq i64 %6, %tmp21
+  br i1 %exitcond22, label %return, label %bb
+
+return:                                           ; preds = %bb3, %entry
+  ret void
+}
+
+; CHECK: p0: %N
+; CHECK: p1: %M
+; CHECK: Statements {
+; CHECK:   Stmt_bb1
+; CHECK:         Domain :=
+; CHECK:             [N, M] -> { Stmt_bb1[i0, i1] : i0 >= 0 and i0 <= 2 + 4N + 7M and i1 >= 0 and i1 <= 10 + 5N - 6M - 4i0 and 4i0 <= 10 + 5N - 6M };
+; CHECK:         Scattering :=
+; CHECK:             [N, M] -> { Stmt_bb1[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK:         MustWriteAccess := [Reduction Type: NONE]
+; CHECK:             [N, M] -> { Stmt_bb1[i0, i1] -> MemRef_a[-1152 + 768M + 897i0 + 128i1] };
+; CHECK: }
diff --git a/rc1/test/ScopInfo/loop_carry.ll b/rc1/test/ScopInfo/loop_carry.ll
new file mode 100644
index 0000000..125c19e
--- /dev/null
+++ b/rc1/test/ScopInfo/loop_carry.ll
@@ -0,0 +1,81 @@
+; RUN: opt %loadPolly -basicaa -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: [n] -> { : n >= -9223372036854775808 and n <= 9223372036854775807 }
+; CHECK:     Statements {
+; CHECK:     	Stmt_bb_nph
+; CHECK:             Domain :=
+; CHECK:                 [n] -> { Stmt_bb_nph[] : n >= 2 };
+; CHECK:             Scattering :=
+; CHECK:                 [n] -> { Stmt_bb_nph[] -> scattering[0, 0, 0] };
+; CHECK:             ReadAccess :=
+; CHECK:                 [n] -> { Stmt_bb_nph[] -> MemRef_a[0] };
+; CHECK:             MustWriteAccess :=
+; CHECK:                 [n] -> { Stmt_bb_nph[] -> MemRef_k_05_reg2mem[0] };
+; CHECK:             MustWriteAccess :=
+; CHECK:                 [n] -> { Stmt_bb_nph[] -> MemRef__reg2mem[0] };
+; CHECK:     	Stmt_bb
+; CHECK:             Domain :=
+; CHECK:                 [n] -> { Stmt_bb[i0] : i0 >= 0 and i0 <= -2 + n and n >= 2 };
+; CHECK:             Scattering :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> scattering[1, i0, 0] };
+; CHECK:             ReadAccess :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> MemRef__reg2mem[0] };
+; CHECK:             ReadAccess :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> MemRef_k_05_reg2mem[0] };
+; CHECK:             MustWriteAccess :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> MemRef_a[1 + i0] };
+; CHECK:             ReadAccess :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> MemRef_a[2 + 2i0] };
+; CHECK:             ReadAccess :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> MemRef_a[4 + i0] };
+; CHECK:             MustWriteAccess :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> MemRef_k_05_reg2mem[0] };
+; CHECK:             MustWriteAccess :=
+; CHECK:                 [n] -> { Stmt_bb[i0] -> MemRef__reg2mem[0] };
diff --git a/rc1/test/ScopInfo/multi-scop.ll b/rc1/test/ScopInfo/multi-scop.ll
new file mode 100644
index 0000000..5f9e670
--- /dev/null
+++ b/rc1/test/ScopInfo/multi-scop.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-detect -analyze -polly-codegen-scev < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -analyze -polly-codegen-scev < %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; This test case contains two scops.
+define void @test(i32 %l, double* %a) {
+entry:
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  %shl = shl i32 %l, 2
+  br i1 false, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.body, %entry.split
+  %j.011 = phi i32 [ 0, %entry.split ], [ %add76, %for.body ]
+  %add76 = add nsw i32 %j.011, 2
+  br i1 false, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body, %entry.split
+  br i1 undef, label %for.body81, label %for.end170
+
+for.body81:                                       ; preds = %for.body81, %for.end
+  %j.19 = phi i32 [ %shl, %for.end ], [ %add169, %for.body81 ]
+  %add13710 = or i32 %j.19, 1
+  %idxprom138 = sext i32 %add13710 to i64
+  %arrayidx139 = getelementptr inbounds double* %a, i64 %idxprom138
+  store double undef, double* %arrayidx139, align 8
+  %add169 = add nsw i32 %j.19, 2
+  br i1 false, label %for.body81, label %for.end170
+
+for.end170:                                       ; preds = %for.body81
+  ret void
+}
+
+; CHECK: Valid Region for Scop: for.body81 => for.end170
+; CHECK: Valid Region for Scop: entry.split => for.end
+
diff --git a/rc1/test/ScopInfo/multidim_2d-diagonal-matrix.ll b/rc1/test/ScopInfo/multidim_2d-diagonal-matrix.ll
new file mode 100644
index 0000000..24639b0
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_2d-diagonal-matrix.ll
@@ -0,0 +1,43 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Derived from the following code:
+;
+; void foo(long n, double A[n][n]) {
+;   for (long i = 0; i < n; i++)
+;     A[i][i] = 1.0;
+; }
+
+
+; CHECK: Assumed Context:
+; CHECK:   [n] -> {  :  }
+
+; CHECK: p0: %n
+; CHECK-NOT: p1
+
+; CHECK: Domain :=
+; CHECK:   [n] -> { Stmt_for_i[i0] : i0 >= 0 and i0 <= -1 + n };
+; CHECK: Scattering :=
+; CHECK:   [n] -> { Stmt_for_i[i0] -> scattering[0, i0, 0] };
+; CHECK: MustWriteAccess :=
+; CHECK:   [n] -> { Stmt_for_i[i0] -> MemRef_A[i0, i0] };
+
+
+define void @foo(i64 %n, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i ]
+  %tmp = mul nsw i64 %i, %n
+  %vlaarrayidx.sum = add i64 %i, %tmp
+  %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
+  store double 1.0, double* %arrayidx
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll b/rc1/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll
new file mode 100644
index 0000000..0735446
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_2d_outer_larger_than_zero.ll
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Derived from the following code:
+;
+; void foo(long n, long m, long p, double A[n][m]) {
+;   for (long i = 0; i < 100; i++)
+;     for (long j = 0; j < m; j++)
+;       A[i+p][j] = 1.0;
+; }
+
+; CHECK:  Assumed Context:
+; CHECK:  [m, p] -> {  : p >= 0 }
+; CHECK:  p0: %m
+; CHECK:  p1: %p
+; CHECK:  Statements {
+; CHECK:    Stmt_for_j
+; CHECK:          Domain :=
+; CHECK:              [m, p] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= -1 + m };
+; CHECK:          Scattering :=
+; CHECK:              [m, p] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK:          MustWriteAccess := [Reduction Type: NONE]
+; CHECK:              [m, p] -> { Stmt_for_j[i0, i1] -> MemRef_A[p + i0, i1] };
+; CHECK:  }
+
+define void @foo(i64 %n, i64 %m, i64 %p, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  %add = add nsw i64 %i, %p
+  %tmp = mul nsw i64 %add, %m
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j ]
+  %vlaarrayidx.sum = add i64 %j, %tmp
+  %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
+  store double 1.0, double* %arrayidx
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, 100
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll b/rc1/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll
new file mode 100644
index 0000000..24e5a85
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_2d_parametric_array_static_loop_bounds.ll
@@ -0,0 +1,49 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Derived from the following code:
+;
+; void foo(long n, long m, double A[n][m]) {
+;   for (long i = 0; i < 100; i++)
+;     for (long j = 0; j < 150; j++)
+;       A[i][j] = 1.0;
+; }
+; CHECK: Assumed Context:
+; CHECK: [m] -> {  : m >= 150 }
+; CHECK: p0: %m
+; CHECK: Statements {
+; CHECK:   Stmt_for_j
+; CHECK:         Domain :=
+; CHECK:             [m] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 149 };
+; CHECK:         Scattering :=
+; CHECK:             [m] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK:         MustWriteAccess := [Reduction Type: NONE]
+; CHECK:             [m] -> { Stmt_for_j[i0, i1] -> MemRef_A[i0, i1] };
+
+define void @foo(i64 %n, i64 %m, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  %tmp = mul nsw i64 %i, %m
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j ]
+  %vlaarrayidx.sum = add i64 %j, %tmp
+  %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
+  store double 1.0, double* %arrayidx
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, 150
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, 100
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll b/rc1/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll
new file mode 100644
index 0000000..63f1e77
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_3d_parametric_array_static_loop_bounds.ll
@@ -0,0 +1,65 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, long o, double A[n][m][o]) {
+;
+;   for (long i = 0; i < 100; i++)
+;     for (long j = 0; j < 150; j++)
+;       for (long k = 0; k < 200; k++)
+;         A[i][j][k] = 1.0;
+; }
+
+; CHECK:   Assumed Context:
+; CHECK:   [m, o] -> {  : m >= 150 and o >= 200 }
+; CHECK:   p0: %m
+; CHECK:   p1: %o
+; CHECK:   Statements {
+; CHECK:     Stmt_for_k
+; CHECK:           Domain :=
+; CHECK:               [m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 149 and i2 >= 0 and i2 <= 199 };
+; CHECK:           Scattering :=
+; CHECK:               [m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK:           MustWriteAccess := [Reduction Type: NONE]
+; CHECK:               [m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i1, i2] };
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j.inc ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ 0, %for.j ], [ %k.inc, %for.k.inc ]
+  %subscript0 = mul i64 %i, %m
+  %subscript1 = add i64 %j, %subscript0
+  %subscript2 = mul i64 %subscript1, %o
+  %subscript = add i64 %subscript2, %k
+  %idx = getelementptr inbounds double* %A, i64 %subscript
+  store double 1.0, double* %idx
+  br label %for.k.inc
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %k.exitcond = icmp eq i64 %k.inc, 200
+  br i1 %k.exitcond, label %for.j.inc, label %for.k
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, 150
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, 100
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll b/rc1/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll
new file mode 100644
index 0000000..3a3175d
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_ivs_and_integer_offsets_3d.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize -polly-codegen-scev < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, long o, double A[n][m][o]) {
+;
+;   for (long i = 0; i < n-3; i++)
+;     for (long j = 4; j < m; j++)
+;       for (long k = 0; k < o-7; k++)
+;         A[i+3][j-4][k+7] = 1.0;
+; }
+
+; CHECK: Assumed Context:
+; CHECK: {  :  }
+
+; CHECK: p0: %n
+; CHECK: p1: %m
+; CHECK: p2: %o
+; CHECK-NOT: p3
+
+; CHECK: Domain
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -4 + n and i1 >= 0 and i1 <= -5 + m and i2 >= 0 and i2 <= -8 + o };
+; CHECK: Scattering
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK: MustWriteAccess
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[3 + i0, i1, 7 + i2] };
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 4, %for.i ], [ %j.inc, %for.j.inc ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ 0, %for.j ], [ %k.inc, %for.k.inc ]
+  %offset0 = add nsw i64 %i, 3
+  %subscript0 = mul i64 %offset0, %m
+  %offset1 = add nsw i64 %j, -4
+  %subscript1 = add i64 %offset1, %subscript0
+  %subscript2 = mul i64 %subscript1, %o
+  %offset2 = add nsw i64 %k, 7
+  %subscript = add i64 %subscript2, %offset2
+  %idx = getelementptr inbounds double* %A, i64 %subscript
+  store double 1.0, double* %idx
+  br label %for.k.inc
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %osub = sub nsw i64 %o, 7
+  %k.exitcond = icmp eq i64 %k.inc, %osub
+  br i1 %k.exitcond, label %for.j.inc, label %for.k
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %nsub = sub nsw i64 %n, 3
+  %i.exitcond = icmp eq i64 %i.inc, %nsub
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll b/rc1/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll
new file mode 100644
index 0000000..7acb778
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_ivs_and_parameteric_offsets_3d.ll
@@ -0,0 +1,77 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, long o, double A[n][m][o], long p, long q, long r) {
+;
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;       for (long k = 0; k < o; k++)
+;         A[i+p][j+q][k+r] = 1.0;
+; }
+;
+; Access function:
+;    {{{((8 * ((((%m * %p) + %q) * %o) + %r)) + %A),+,(8 * %m * %o)}<%for.i>,+,
+;        (8 * %o)}<%for.j>,+,8}<%for.k>
+
+; CHECK: Assumed Context:
+; CHECK: [n, m, o, p, q, r] -> { : q = 0 and r = 0 and p >= 0 }
+;
+; CHECK: p0: %n
+; CHECK: p1: %m
+; CHECK: p2: %o
+; CHECK: p3: %p
+; CHECK: p4: %q
+; CHECK: p5: %r
+; CHECK-NOT: p6
+;
+; CHECK: Domain
+; CHECK:   [n, m, o, p, q, r] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m and i2 >= 0 and i2 <= -1 + o };
+; CHECK: Scattering
+; CHECK:   [n, m, o, p, q, r] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK: MustWriteAccess
+; CHECK:   [n, m, o, p, q, r] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[p + i0, q + i1, r + i2] };
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A, i64 %p, i64 %q, i64 %r) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j.inc ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ 0, %for.j ], [ %k.inc, %for.k.inc ]
+  %offset0 = add nsw i64 %i, %p
+  %subscript0 = mul i64 %offset0, %m
+  %offset1 = add nsw i64 %j, %q
+  %subscript1 = add i64 %offset1, %subscript0
+  %subscript2 = mul i64 %subscript1, %o
+  %offset2 = add nsw i64 %k, %r
+  %subscript = add i64 %subscript2, %offset2
+  %idx = getelementptr inbounds double* %A, i64 %subscript
+  store double 1.0, double* %idx
+  br label %for.k.inc
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %k.exitcond = icmp eq i64 %k.inc, %o
+  br i1 %k.exitcond, label %for.j.inc, label %for.k
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_nested_start_integer.ll b/rc1/test/ScopInfo/multidim_nested_start_integer.ll
new file mode 100644
index 0000000..da49ca0
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_nested_start_integer.ll
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize -polly-codegen-scev < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, long o, double A[n][m][o]) {
+;   for (long i = 0; i < n - 3; i++)
+;     for (long j = 4; j < m; j++)
+;       for (long k = 0; k < o - 7; k++)
+;         A[i+3][j-4][k+7] = 1.0;
+; }
+;
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
+; CHECK: p0: %n
+; CHECK: p1: %m
+; CHECK: p2: %o
+; CHECK-NOT: p3
+; CHECK: Domain
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -4 + n and i1 >= 0 and i1 <= -5 + m and i2 >= 0 and i2 <= -8 + o };
+; CHECK: Scattering
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK: MustWriteAccess
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[3 + i0, i1, 7 + i2] };
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 4, %for.i ], [ %j.inc, %for.j.inc ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ 0, %for.j ], [ %k.inc, %for.k.inc ]
+  %offset0 = add nsw i64 %i, 3
+  %subscript0 = mul i64 %offset0, %m
+  %offset1 = add nsw i64 %j, -4
+  %subscript1 = add i64 %offset1, %subscript0
+  %subscript2 = mul i64 %subscript1, %o
+  %offset2 = add nsw i64 %k, 7
+  %subscript = add i64 %subscript2, %offset2
+  %idx = getelementptr inbounds double* %A, i64 %subscript
+  store double 1.0, double* %idx
+  br label %for.k.inc
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %osub = sub nsw i64 %o, 7
+  %k.exitcond = icmp eq i64 %k.inc, %osub
+  br i1 %k.exitcond, label %for.j.inc, label %for.k
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %nsub = sub nsw i64 %n, 3
+  %i.exitcond = icmp eq i64 %i.inc, %nsub
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_nested_start_share_parameter.ll b/rc1/test/ScopInfo/multidim_nested_start_share_parameter.ll
new file mode 100644
index 0000000..142878c
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_nested_start_share_parameter.ll
@@ -0,0 +1,81 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize -polly-codegen-scev < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, long o, double A[n][m][o]) {
+;
+;   for (long i = 0; i < n-13; i++)
+;     for (long j = 14; j < m; j++)
+;       for (long k = 0; k < o-17; k++) {
+;         A[i+3][j-4][k+7] = 1.0;
+;         A[i+13][j-14][k+17] = 11.0;
+;       }
+; }
+;
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
+; CHECK: p0: %n
+; CHECK: p1: %m
+; CHECK: p2: %o
+; CHECK-NOT: p3
+;
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[3 + i0, 10 + i1, 7 + i2] };
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[13 + i0, i1, 17 + i2] };
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 14, %for.i ], [ %j.inc, %for.j.inc ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ 0, %for.j ], [ %k.inc, %for.k.inc ]
+
+  %offset0 = add nsw i64 %i, 3
+  %subscript0 = mul i64 %offset0, %m
+  %offset1 = add nsw i64 %j, -4
+  %subscript1 = add i64 %offset1, %subscript0
+  %subscript2 = mul i64 %subscript1, %o
+  %offset2 = add nsw i64 %k, 7
+  %subscript3 = add i64 %subscript2, %offset2
+  %idx = getelementptr inbounds double* %A, i64 %subscript3
+  store double 1.0, double* %idx
+
+  %offset3 = add nsw i64 %i, 13
+  %subscript4 = mul i64 %offset3, %m
+  %offset4 = add nsw i64 %j, -14
+  %subscript5 = add i64 %offset4, %subscript4
+  %subscript6 = mul i64 %subscript5, %o
+  %offset5 = add nsw i64 %k, 17
+  %subscript7 = add i64 %subscript6, %offset5
+  %idx1 = getelementptr inbounds double* %A, i64 %subscript7
+  store double 11.0, double* %idx1
+
+  br label %for.k.inc
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %osub = sub nsw i64 %o, 17
+  %k.exitcond = icmp eq i64 %k.inc, %osub
+  br i1 %k.exitcond, label %for.j.inc, label %for.k
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %nsub = sub nsw i64 %n, 13
+  %i.exitcond = icmp eq i64 %i.inc, %nsub
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_only_ivs_2d.ll b/rc1/test/ScopInfo/multidim_only_ivs_2d.ll
new file mode 100644
index 0000000..1819b27
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_only_ivs_2d.ll
@@ -0,0 +1,51 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Derived from the following code:
+;
+; void foo(long n, long m, double A[n][m]) {
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;       A[i][j] = 1.0;
+; }
+
+; CHECK: Assumed Context:
+; CHECK:   [n, m] -> {  :  }
+; CHECK: p0: %n
+; CHECK: p1: %m
+; CHECK-NOT: p3
+
+; CHECK: Domain
+; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m };
+; CHECK: Scattering
+; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> scattering[0, i0, 0, i1, 0] };
+; CHECK: MustWriteAccess
+; CHECK:   [n, m] -> { Stmt_for_j[i0, i1] -> MemRef_A[i0, i1] };
+
+define void @foo(i64 %n, i64 %m, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  %tmp = mul nsw i64 %i, %m
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j ]
+  %vlaarrayidx.sum = add i64 %j, %tmp
+  %arrayidx = getelementptr inbounds double* %A, i64 %vlaarrayidx.sum
+  store double 1.0, double* %arrayidx
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_only_ivs_3d.ll b/rc1/test/ScopInfo/multidim_only_ivs_3d.ll
new file mode 100644
index 0000000..96501bf
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_only_ivs_3d.ll
@@ -0,0 +1,66 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, long m, long o, double A[n][m][o]) {
+;
+;   for (long i = 0; i < n; i++)
+;     for (long j = 0; j < m; j++)
+;       for (long k = 0; k < o; k++)
+;         A[i][j][k] = 1.0;
+; }
+
+; CHECK: Assumed Context:
+; CHECK:   [n, m, o] -> {  :  }
+; CHECK: p0: %n
+; CHECK: p1: %m
+; CHECK: p2: %o
+; CHECK-NOT: p3
+;
+; CHECK: Domain
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m and i2 >= 0 and i2 <= -1 + o };
+; CHECK: Scattering
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK: WriteAccess
+; CHECK:   [n, m, o] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i1, i2] };
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.i ], [ %j.inc, %for.j.inc ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ 0, %for.j ], [ %k.inc, %for.k.inc ]
+  %subscript0 = mul i64 %i, %m
+  %subscript1 = add i64 %j, %subscript0
+  %subscript2 = mul i64 %subscript1, %o
+  %subscript = add i64 %subscript2, %k
+  %idx = getelementptr inbounds double* %A, i64 %subscript
+  store double 1.0, double* %idx
+  br label %for.k.inc
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %k.exitcond = icmp eq i64 %k.inc, %o
+  br i1 %k.exitcond, label %for.j.inc, label %for.k
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_only_ivs_3d_cast.ll b/rc1/test/ScopInfo/multidim_only_ivs_3d_cast.ll
new file mode 100644
index 0000000..1564c80
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_only_ivs_3d_cast.ll
@@ -0,0 +1,81 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+
+; void foo(int n, int m, int o, double A[n][m][o]) {
+;
+;   for (int i = 0; i < n; i++)
+;     for (int j = 0; j < m; j++)
+;       for (int k = 0; k < o; k++)
+;         A[i][j][k] = 1.0;
+; }
+
+; We currently fail to get the relation between the 32 and 64 bit versions of
+; m and o, such that we generate unnecessary run-time checks. This is not a
+; correctness issue, but could be improved.
+
+; CHECK: Assumed Context:
+; CHECK:  [n, m, o, p_3, p_4] -> { : p_4 >= o and p_3 >= m }
+; CHECK: p0: %n
+; CHECK: p1: %m
+; CHECK: p2: %o
+; CHECK: p3: (zext i32 %m to i64)
+; CHECK: p4: (zext i32 %o to i64)
+; CHECK-NOT: p5
+
+; CHECK: Domain
+; CHECK:   [n, m, o, p_3, p_4] -> { Stmt_for_k[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + m and i2 >= 0 and i2 <= -1 + o };
+; CHECK: Scattering
+; CHECK:   [n, m, o, p_3, p_4] -> { Stmt_for_k[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK: WriteAccess
+; CHECK:   [n, m, o, p_3, p_4] -> { Stmt_for_k[i0, i1, i2] -> MemRef_A[i0, i1, i2] };
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo(i32 %n, i32 %m, i32 %o, double* %A) {
+entry:
+  %m_zext = zext i32 %m to i64
+  %n_zext = zext i32 %o to i64
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ %i.inc, %for.i.inc ], [ 0, %entry ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ %j.inc, %for.j.inc ], [ 0, %for.i ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ %k.inc, %for.k.inc ], [ 0, %for.j ]
+  %tmp = mul i64 %i, %m_zext
+  %tmp1 = trunc i64 %j to i32
+  %tmp2 = trunc i64 %i to i32
+  %mul.us.us = mul nsw i32 %tmp1, %tmp2
+  %tmp.us.us = add i64 %j, %tmp
+  %tmp17.us.us = mul i64 %tmp.us.us, %n_zext
+  %subscript = add i64 %tmp17.us.us, %k
+  %idx = getelementptr inbounds double* %A, i64 %subscript
+  store double 1.0, double* %idx
+  br label %for.k.inc
+
+for.k.inc:
+  %k.inc = add i64 %k, 1
+  %k.inc.trunc = trunc i64 %k.inc to i32
+  %k.exitcond = icmp eq i32 %k.inc.trunc, %o
+  br i1 %k.exitcond, label %for.j.inc, label %for.k
+
+for.j.inc:
+  %j.inc = add i64 %j, 1
+  %j.inc.trunc = trunc i64 %j.inc to i32
+  %j.exitcond = icmp eq i32 %j.inc.trunc, %m
+  br i1 %j.exitcond, label %for.i.inc, label %for.j
+
+for.i.inc:
+  %i.inc = add i64 %i, 1
+  %i.inc.trunc = trunc i64 %i.inc to i32
+  %i.exitcond = icmp eq i32 %i.inc.trunc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/multidim_only_ivs_3d_reverse.ll b/rc1/test/ScopInfo/multidim_only_ivs_3d_reverse.ll
new file mode 100644
index 0000000..14ec467
--- /dev/null
+++ b/rc1/test/ScopInfo/multidim_only_ivs_3d_reverse.ll
@@ -0,0 +1,71 @@
+; RUN: opt %loadPolly -polly-scops -analyze -polly-delinearize < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; This test case checks for array access functions where the order in which the
+; loop ivs appear in the array subscript does not follow the order of the
+; the loops in which they are defined. This (very common) case caused problems
+; in the delinearization pass.
+;
+; void foo(long n, long m, long o, double A[n][m][o]) {
+;
+;   for (long i = 0; i < n; i++)
+;     for (long k = 0; k < o; k++)
+;       for (long j = 0; j < m; j++)
+;         A[i][j][k] = 1.0;
+; }
+
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
+; CHECK: p0: %n
+; CHECK: p1: %o
+; CHECK: p2: %m
+; CHECK-NOT: p3
+;
+; CHECK: Domain
+; CHECK:  [n, o, m] -> { Stmt_for_j[i0, i1, i2] : i0 >= 0 and i0 <= -1 + n and i1 >= 0 and i1 <= -1 + o and i2 >= 0 and i2 <= -1 + m };
+; CHECK: Scattering
+; CHECK:   [n, o, m] -> { Stmt_for_j[i0, i1, i2] -> scattering[0, i0, 0, i1, 0, i2, 0] };
+; CHECK: WriteAccess
+; CHECK:   [n, o, m] -> { Stmt_for_j[i0, i1, i2] -> MemRef_A[i0, i2, i1] };
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
+entry:
+  br label %for.i
+
+for.i:
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %for.i.inc ]
+  br label %for.k
+
+for.k:
+  %k = phi i64 [ 0, %for.i ], [ %k.inc, %for.k.inc ]
+  br label %for.j
+
+for.j:
+  %j = phi i64 [ 0, %for.k ], [ %j.inc, %for.j.inc ]
+  %subscript0 = mul i64 %i, %m
+  %subscript1 = add i64 %j, %subscript0
+  %subscript2 = mul i64 %subscript1, %o
+  %subscript = add i64 %subscript2, %k
+  %idx = getelementptr inbounds double* %A, i64 %subscript
+  store double 1.0, double* %idx
+  br label %for.j.inc
+
+for.j.inc:
+  %j.inc = add nsw i64 %j, 1
+  %j.exitcond = icmp eq i64 %j.inc, %m
+  br i1 %j.exitcond, label %for.k.inc, label %for.j
+
+for.k.inc:
+  %k.inc = add nsw i64 %k, 1
+  %k.exitcond = icmp eq i64 %k.inc, %o
+  br i1 %k.exitcond, label %for.i.inc, label %for.k
+
+for.i.inc:
+  %i.inc = add nsw i64 %i, 1
+  %i.exitcond = icmp eq i64 %i.inc, %n
+  br i1 %i.exitcond, label %end, label %for.i
+
+end:
+  ret void
+}
diff --git a/rc1/test/ScopInfo/non_affine_parametric_loop.ll b/rc1/test/ScopInfo/non_affine_parametric_loop.ll
new file mode 100644
index 0000000..766fe9e
--- /dev/null
+++ b/rc1/test/ScopInfo/non_affine_parametric_loop.ll
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze -polly-allow-nonaffine < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; void foo(long n, double A[], int INDEX[]) {
+;   for (long i = 0; i < n; i++)
+;     A[INDEX[i]] = i;
+; }
+
+define void @foo(i64 %n, double* noalias %A, i64* noalias %INDEX) {
+entry:
+  br label %for.body
+
+for.body:
+  %i = phi i64 [ %inc, %for.body ], [ 0, %entry ]
+  %arrayidx = getelementptr inbounds i64* %INDEX, i64 %i
+  %val = load i64* %arrayidx
+  %arrayidx1 = getelementptr inbounds double* %A, i64 %val
+  store double 1.0, double* %arrayidx1
+  %inc = add nsw i64 %i, 1
+  %exitcond = icmp eq i64 %inc, %n
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+; CHECK: p0: %n
+
+; CHECK: Domain
+; CHECK:   [n] -> { Stmt_for_body[i0] : i0 >= 0 and i0 <= -1 + n };
+; CHECK: Scattering
+; CHECK:   [n] -> { Stmt_for_body[i0] -> scattering[0, i0, 0] };
+; CHECK: ReadAccess
+; CHECK:   [n] -> { Stmt_for_body[i0] -> MemRef_INDEX[i0] };
+; CHECK: WriteAccess
+; CHECK:   [n] -> { Stmt_for_body[i0] -> MemRef_A[o0] };
diff --git a/rc1/test/ScopInfo/parameter_product.ll b/rc1/test/ScopInfo/parameter_product.ll
new file mode 100644
index 0000000..2bd9793
--- /dev/null
+++ b/rc1/test/ScopInfo/parameter_product.ll
@@ -0,0 +1,31 @@
+; RUN: opt %loadPolly -polly-scops -analyze -S < %s | FileCheck %s
+;
+; int n, m;
+; void foo(char* __restrict a)
+; {
+;   for (int i = 0; i < n*m; ++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-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @foo(i8* noalias %a, i32 %param_n, i32 %param_m) {
+entry:
+  %mul = mul nsw i32 %param_m, %param_n
+  %cmp1 = icmp sgt i32 %mul, 0
+  br i1 %cmp1, label %for.body, label %for.end
+
+for.body:
+  %i.02 = phi i32 [ %add, %for.body ], [ 0, %entry ]
+  %arrayidx = getelementptr inbounds i8* %a, i64 0
+  store i8 2, i8* %arrayidx, align 1
+  %add = add nsw i32 %i.02, 1
+  %cmp = icmp slt i32 %add, %mul
+  br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+  ret void
+}
+
+; CHECK: p0: (%param_n * %param_m)
+
diff --git a/rc1/test/ScopInfo/phi_not_grouped_at_top.ll b/rc1/test/ScopInfo/phi_not_grouped_at_top.ll
new file mode 100755
index 0000000..c5ddadb
--- /dev/null
+++ b/rc1/test/ScopInfo/phi_not_grouped_at_top.ll
@@ -0,0 +1,29 @@
+; RUN: opt %loadPolly -polly-prepare  -analyze  %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"
+
+declare i32 @funa() align 2
+
+declare i32 @generic_personality_v0(i32, i64, i8*, i8*)
+
+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
+  %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality_v0 cleanup catch i32* null
+  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
+}
diff --git a/rc1/test/ScopInfo/phi_with_invoke_edge.ll b/rc1/test/ScopInfo/phi_with_invoke_edge.ll
new file mode 100755
index 0000000..ea874ca
--- /dev/null
+++ b/rc1/test/ScopInfo/phi_with_invoke_edge.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly -polly-prepare -polly-detect  -analyze  %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"
+
+declare i32 @generic_personality_v0(i32, i64, i8*, i8*)
+
+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
+  %d = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @generic_personality_v0 cleanup catch i32* null
+  unreachable
+}
diff --git a/rc1/test/ScopInfo/reduction_alternating_base.ll b/rc1/test/ScopInfo/reduction_alternating_base.ll
new file mode 100644
index 0000000..ce98f01
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_alternating_base.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; FIXME: We cannot detect this SCoP yet but as soon as we can we should check
+;        that the reduction is detected!
+;
+; CHECK-NOT: Scattering
+;
+;    void f(int *A) {
+;      for (int i = 0; i < 1024; i++)
+;        A[i % 2] += i;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %rem = srem i32 %i.0, 2
+  %arrayidx = getelementptr inbounds i32* %A, i32 %rem
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  store i32 %add, i32* %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
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_chain_partially_outside_the_scop.ll b/rc1/test/ScopInfo/reduction_chain_partially_outside_the_scop.ll
new file mode 100644
index 0000000..248d29e
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_chain_partially_outside_the_scop.ll
@@ -0,0 +1,63 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK-NOT: Reduction like: 1
+;
+;    int c, d;
+;    void f(int *sum) {
+;      for (int i = 0; i < 1024; i++)
+;        *sum = c + d;
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+@c = common global i32 0, align 4
+@d = common global i32 0, align 4
+
+define void @loads_outside_scop(i32* %sum) {
+entry:
+  %tmp = load i32* @c, align 4
+  %tmp1 = load i32* @d, align 4
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %add = add nsw i32 %tmp, %tmp1
+  store i32 %add, i32* %sum, 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
+  ret void
+}
+
+
+define void @binop_outside_scop(i32* %sum) {
+entry:
+  %tmp = load i32* @c, align 4
+  %tmp1 = load i32* @d, align 4
+  %add = add nsw i32 %tmp, %tmp1
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  store i32 %add, i32* %sum, 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
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_disabled_multiplicative.ll b/rc1/test/ScopInfo/reduction_disabled_multiplicative.ll
new file mode 100644
index 0000000..4a3ccfa
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_disabled_multiplicative.ll
@@ -0,0 +1,52 @@
+; RUN: opt -basicaa %loadPolly -polly-scops -analyze -polly-disable-multiplicative-reductions < %s | FileCheck %s
+;
+; CHECK: ReadAccess :=       [Reduction Type: ADD
+; CHECK:     { Stmt_for_body[i0] -> MemRef_sum[0] };
+; CHECK: MustWriteAccess :=  [Reduction Type: ADD
+; CHECK:     { Stmt_for_body[i0] -> MemRef_sum[0] };
+; CHECK: ReadAccess :=       [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_prod[0] };
+; CHECK: MustWriteAccess :=  [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_prod[0] };
+;
+; int sum, prod;
+; 
+; void f() {
+;   int i;
+;   for (int i = 0; i < 100; i++) {
+;     sum += i * 3;
+;     prod *= (i + 3);
+;   }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+@sum = common global i32 0, align 4
+@prod = common global i32 0, align 4
+
+define void @f() #0 {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i1.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i1.0, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %mul = mul nsw i32 %i1.0, 3
+  %tmp = load i32* @sum, align 4
+  %add = add nsw i32 %tmp, %mul
+  store i32 %add, i32* @sum, align 4
+  %add2 = add nsw i32 %i1.0, 3
+  %tmp1 = load i32* @prod, align 4
+  %mul3 = mul nsw i32 %tmp1, %add2
+  store i32 %mul3, i32* @prod, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %i1.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_escaping_intermediate.ll b/rc1/test/ScopInfo/reduction_escaping_intermediate.ll
new file mode 100644
index 0000000..2c4f74c
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_escaping_intermediate.ll
@@ -0,0 +1,62 @@
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
+;
+; void f(int N, int * restrict sums, int * restrict escape) {
+;   int i, j;
+;   for (i = 0; i < 1024; i++) {
+;     for (j = 0; j < 1024; j++) {
+;       sums[i] += 5;
+;       escape[N - i + j] = sums[i];
+;     }
+;   }
+; }
+;
+; CHECK: Reduction Type: NONE
+; CHECK: sums
+; CHECK: Reduction Type: NONE
+; CHECK: sums
+; CHECK: Reduction Type: NONE
+; CHECK: escape
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32 %N, i32* noalias %sums, i32* noalias %escape) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc7, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc8, %for.inc7 ]
+  %exitcond1 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond1, label %for.body, label %for.end9
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %sums, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 5
+  store i32 %add, i32* %arrayidx, align 4
+  %sub = sub nsw i32 %N, %i.0
+  %add5 = add nsw i32 %sub, %j.0
+  %arrayidx6 = getelementptr inbounds i32* %escape, i32 %add5
+  store i32 %add, i32* %arrayidx6, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc7
+
+for.inc7:                                         ; preds = %for.end
+  %inc8 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end9:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_escaping_intermediate_2.ll b/rc1/test/ScopInfo/reduction_escaping_intermediate_2.ll
new file mode 100644
index 0000000..2d8c09e
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_escaping_intermediate_2.ll
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
+;
+; void f(int N, int * restrict sums, int * restrict escape) {
+;   int i, j;
+;   for (i = 0; i < 1024; i++) {
+;     for (j = 0; j < 1024; j++) {
+;       sums[i] += 5;
+;       escape[N-j] = escape[i] + sums[i-1];
+;     }
+;   }
+; }
+;
+; CHECK: Reduction Type: NONE
+; CHECK: sums
+; CHECK: Reduction Type: NONE
+; CHECK: sums
+; CHECK: Reduction Type: NONE
+; CHECK: escape
+; CHECK: Reduction Type: NONE
+; CHECK: sums
+; CHECK: Reduction Type: NONE
+; CHECK: escape
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32 %N, i32* noalias %sums, i32* noalias %escape) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+  %exitcond1 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond1, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %sums, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 5
+  store i32 %add, i32* %arrayidx, align 4
+  %arrayidx4 = getelementptr inbounds i32* %escape, i32 %i.0
+  %tmp2 = load i32* %arrayidx4, align 4
+  %sub = add nsw i32 %i.0, -1
+  %arrayidx5 = getelementptr inbounds i32* %sums, i32 %sub
+  %tmp3 = load i32* %arrayidx5, align 4
+  %add6 = add nsw i32 %tmp2, %tmp3
+  %sub7 = sub nsw i32 %N, %i.0
+  %add8 = add nsw i32 %sub7, %j.0
+  %arrayidx9 = getelementptr inbounds i32* %escape, i32 %add8
+  store i32 %add6, i32* %arrayidx9, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end
+  %inc11 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_invalid_different_operators.ll b/rc1/test/ScopInfo/reduction_invalid_different_operators.ll
new file mode 100644
index 0000000..c519c5f
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_invalid_different_operators.ll
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly -basicaa -polly-scops -analyze < %s | FileCheck %s
+;
+; int f() {
+;   int i, sum = 0, sth = 0;
+;   for (i = 0; i < 1024; i++) {
+;     sum += 5;
+;     sth = sth + sth * sth + sth;
+;     sum *= 5;
+;   }
+;   return sum + sth;
+; }
+;
+; CHECK-NOT: Reduction Type: ADD
+; CHECK-NOT: Reduction Type: MUL
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define i32 @f() {
+entry:
+  %sum.0 = alloca i32
+  %sth.0 = alloca i32
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  store i32 0, i32* %sum.0
+  store i32 0, i32* %sth.0
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.cond, %entry.split
+  %i.0 = phi i32 [ 0, %entry.split ], [ %inc, %for.cond ]
+  %sth.0.reload = load i32* %sth.0
+  %sum.0.reload = load i32* %sum.0
+  %exitcond = icmp ne i32 %i.0, 1024
+  %mul = mul nsw i32 %sth.0.reload, %sth.0.reload
+  %add1 = add nsw i32 %sth.0.reload, %mul
+  %tmp = mul i32 %sum.0.reload, 5
+  store i32 %tmp, i32* %sum.0
+  %sum.1.reload = load i32* %sum.0
+  %mul3 = add i32 %sum.1.reload, 25
+  %add2 = add nsw i32 %add1, %sth.0.reload
+  %inc = add nsw i32 %i.0, 1
+  store i32 %mul3, i32* %sum.0
+  store i32 %add2, i32* %sth.0
+  br i1 %exitcond, label %for.cond, label %for.end
+
+for.end:                                          ; preds = %for.cond
+  %sum.0.reload.2 = load i32* %sum.0
+  %sth.0.reload.2 = load i32* %sth.0
+  %add4 = add nsw i32 %sum.0.reload.2, %sth.0.reload.2
+  ret i32 %add4
+}
diff --git a/rc1/test/ScopInfo/reduction_invalid_overlapping_accesses.ll b/rc1/test/ScopInfo/reduction_invalid_overlapping_accesses.ll
new file mode 100644
index 0000000..2c0db4d
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_invalid_overlapping_accesses.ll
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; void f(int *sums) {
+;   int i, j;
+;   for (i = 0; i < 1024; i++) {
+;     for (j = 0; j < 1024; j++) {
+;       sums[i] += 5;
+;       sums[i+10] *= 5;
+;     }
+;   }
+; }
+;
+; CHECK-NOT: Reduction Type: ADD
+; CHECK-NOT: Reduction Type: MUL
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sums) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+  %exitcond1 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond1, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %sums, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 5
+  store i32 %add, i32* %arrayidx, align 4
+  %add4 = add nsw i32 %i.0, 10
+  %arrayidx5 = getelementptr inbounds i32* %sums, i32 %add4
+  %tmp2 = load i32* %arrayidx5, align 4
+  %mul = mul nsw i32 %tmp2, 5
+  store i32 %mul, i32* %arrayidx5, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %for.end
+  %inc7 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_multiple_loops_array_sum.ll b/rc1/test/ScopInfo/reduction_multiple_loops_array_sum.ll
new file mode 100644
index 0000000..7a956ac
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_multiple_loops_array_sum.ll
@@ -0,0 +1,78 @@
+; RUN: opt -basicaa %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Stmt_for_body
+; CHECK: Reduction Type: MUL
+; CHECK: MemRef_sum
+; CHECK: Reduction Type: MUL
+; CHECK: MemRef_sum
+; CHECK: Stmt_for_body3
+; CHECK: Reduction Type: NONE
+; CHECK: MemRef_A
+; CHECK: Reduction Type: ADD
+; CHECK: MemRef_sum
+; CHECK: Reduction Type: ADD
+; CHECK: MemRef_sum
+; CHECK: Stmt_for_end
+; CHECK: Reduction Type: MUL
+; CHECK: MemRef_sum
+; CHECK: Reduction Type: MUL
+; CHECK: MemRef_sum
+;
+; void f(int *restrict A, int *restrict sum) {
+;   int i, j;
+;   for (i = 0; i < 100; i++) {
+;     *sum *= 7;
+;     for (j = 0; j < 100; j++) {
+;       *sum += A[i + j];
+;     }
+;     *sum *= 5;
+;   }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %A, i32* noalias %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+  %exitcond1 = icmp ne i32 %i.0, 100
+  br i1 %exitcond1, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  %tmp = load i32* %sum, align 4
+  %mul = mul nsw i32 %tmp, 7
+  store i32 %mul, i32* %sum, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 100
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %add = add nsw i32 %i.0, %j.0
+  %arrayidx = getelementptr inbounds i32* %A, i32 %add
+  %tmp2 = load i32* %arrayidx, align 4
+  %tmp3 = load i32* %sum, align 4
+  %add4 = add nsw i32 %tmp3, %tmp2
+  store i32 %add4, i32* %sum, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  %tmp4 = load i32* %sum, align 4
+  %mul5 = mul nsw i32 %tmp4, 5
+  store i32 %mul5, i32* %sum, align 4
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %for.end
+  %inc7 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_multiple_loops_array_sum_1.ll b/rc1/test/ScopInfo/reduction_multiple_loops_array_sum_1.ll
new file mode 100644
index 0000000..4104aab
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_multiple_loops_array_sum_1.ll
@@ -0,0 +1,72 @@
+; RUN: opt -basicaa %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Stmt_for_body
+; CHECK: Reduction Type: NONE
+; CHECK: MemRef_sum_04
+; CHECK: Reduction Type: NONE
+; CHECK: MemRef_sum_12
+; CHECK: Stmt_for_inc
+; CHECK: Reduction Type: ADD
+; CHECK: MemRef_sum_12
+; CHECK: Reduction Type: NONE
+; CHECK: MemRef_A
+; CHECK: Reduction Type: ADD
+; CHECK: MemRef_sum_12
+; CHECK: Stmt_for_inc5
+; CHECK: Reduction Type: NONE
+; CHECK: MemRef_sum_12
+; CHECK: Reduction Type: NONE
+; CHECK: MemRef_sum_04
+;
+; int f(int * __restrict__ A) {
+;   int i, j, sum = 1;
+;   for (i = 0; i < 100; i++) {
+;     sum *= 7;
+;     for (j = 0; j < 100; j++) {
+;       sum += A[i+j];
+;     }
+;   }
+;   return sum;
+; }
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define i32 @f(i32* noalias %A) {
+entry:
+  %sum.04.reg2mem = alloca i32
+  %sum.12.reg2mem = alloca i32
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  store i32 0, i32* %sum.04.reg2mem
+  br label %for.body
+
+for.body:                                         ; preds = %for.inc5, %entry.split
+  %indvars.iv23 = phi i64 [ 0, %entry.split ], [ %3, %for.inc5 ]
+  %sum.04.reload = load i32* %sum.04.reg2mem
+  %mul = mul nsw i32 %sum.04.reload, 7
+  store i32 %mul, i32* %sum.12.reg2mem
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.inc, %for.body
+  %indvars.iv1 = phi i64 [ 0, %for.body ], [ %1, %for.inc ]
+  %sum.12.reload = load i32* %sum.12.reg2mem
+  %0 = add i64 %indvars.iv23, %indvars.iv1
+  %arrayidx = getelementptr i32* %A, i64 %0
+  %tmp5 = load i32* %arrayidx, align 4
+  %add4 = add nsw i32 %tmp5, %sum.12.reload
+  %1 = add nuw nsw i64 %indvars.iv1, 1
+  %exitcond1 = icmp eq i64 %1, 100
+  store i32 %add4, i32* %sum.12.reg2mem
+  br i1 %exitcond1, label %for.inc5, label %for.inc
+
+for.inc5:                                         ; preds = %for.inc
+  %2 = load i32* %sum.12.reg2mem
+  %3 = add nuw nsw i64 %indvars.iv23, 1
+  %exitcond2 = icmp eq i64 %3, 100
+  store i32 %2, i32* %sum.04.reg2mem
+  br i1 %exitcond2, label %for.end7, label %for.body
+
+for.end7:                                         ; preds = %for.inc5
+  %4 = load i32* %sum.04.reg2mem
+  ret i32 %4
+}
diff --git a/rc1/test/ScopInfo/reduction_multiple_simple_binary.ll b/rc1/test/ScopInfo/reduction_multiple_simple_binary.ll
new file mode 100644
index 0000000..49e4918
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_multiple_simple_binary.ll
@@ -0,0 +1,98 @@
+; RUN: opt -basicaa %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: ReadAccess :=       [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_A[1 + i0] };
+; CHECK: ReadAccess :=       [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_A[i0] };
+; CHECK: MustWriteAccess :=  [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_first[0] };
+; CHECK: ReadAccess :=       [Reduction Type: ADD
+; CHECK:     { Stmt_for_body[i0] -> MemRef_sum[0] };
+; CHECK: MustWriteAccess :=  [Reduction Type: ADD
+; CHECK:     { Stmt_for_body[i0] -> MemRef_sum[0] };
+; CHECK: ReadAccess :=       [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_A[-1 + i0] };
+; CHECK: ReadAccess :=       [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_A[i0] };
+; CHECK: MustWriteAccess :=  [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_middle[0] };
+; CHECK: ReadAccess :=       [Reduction Type: MUL
+; CHECK:     { Stmt_for_body[i0] -> MemRef_prod[0] };
+; CHECK: MustWriteAccess :=  [Reduction Type: MUL
+; CHECK:     { Stmt_for_body[i0] -> MemRef_prod[0] };
+; CHECK: ReadAccess :=       [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_A[-1 + i0] };
+; CHECK: ReadAccess :=       [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_A[1 + i0] };
+; CHECK: MustWriteAccess :=  [Reduction Type: NONE
+; CHECK:     { Stmt_for_body[i0] -> MemRef_last[0] };
+;
+; int first, sum, middle, prod, last;
+;
+; void f(int * restrict A) {
+;   int i;
+;   for (int i = 0; i < 100; i++) {
+;     first = A[i+1] + A[i];
+;     sum += i * 3;
+;     middle = A[i-1] + A[i];
+;     prod *= (i + 3);
+;     last = A[i-1] + A[i+1];
+;   }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+@first = common global i32 0, align 4
+@sum = common global i32 0, align 4
+@middle = common global i32 0, align 4
+@prod = common global i32 0, align 4
+@last = common global i32 0, align 4
+
+define void @f(i32* noalias %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i1.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i1.0, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %add = add nsw i32 %i1.0, 1
+  %arrayidx = getelementptr inbounds i32* %A, i32 %add
+  %tmp = load i32* %arrayidx, align 4
+  %arrayidx2 = getelementptr inbounds i32* %A, i32 %i1.0
+  %tmp1 = load i32* %arrayidx2, align 4
+  %add3 = add nsw i32 %tmp, %tmp1
+  store i32 %add3, i32* @first, align 4
+  %mul = mul nsw i32 %i1.0, 3
+  %tmp2 = load i32* @sum, align 4
+  %add4 = add nsw i32 %tmp2, %mul
+  store i32 %add4, i32* @sum, align 4
+  %sub = add nsw i32 %i1.0, -1
+  %arrayidx5 = getelementptr inbounds i32* %A, i32 %sub
+  %tmp3 = load i32* %arrayidx5, align 4
+  %arrayidx6 = getelementptr inbounds i32* %A, i32 %i1.0
+  %tmp4 = load i32* %arrayidx6, align 4
+  %add7 = add nsw i32 %tmp3, %tmp4
+  store i32 %add7, i32* @middle, align 4
+  %add8 = add nsw i32 %i1.0, 3
+  %tmp5 = load i32* @prod, align 4
+  %mul9 = mul nsw i32 %tmp5, %add8
+  store i32 %mul9, i32* @prod, align 4
+  %sub10 = add nsw i32 %i1.0, -1
+  %arrayidx11 = getelementptr inbounds i32* %A, i32 %sub10
+  %tmp6 = load i32* %arrayidx11, align 4
+  %add12 = add nsw i32 %i1.0, 1
+  %arrayidx13 = getelementptr inbounds i32* %A, i32 %add12
+  %tmp7 = load i32* %arrayidx13, align 4
+  %add14 = add nsw i32 %tmp6, %tmp7
+  store i32 %add14, i32* @last, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %inc = add nsw i32 %i1.0, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_non_overlapping_chains.ll b/rc1/test/ScopInfo/reduction_non_overlapping_chains.ll
new file mode 100644
index 0000000..ef72955
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_non_overlapping_chains.ll
@@ -0,0 +1,60 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Reduction Type: ADD
+; CHECK: Reduction Type: ADD
+; CHECK: Reduction Type: MUL
+; CHECK: Reduction Type: MUL
+;
+; void f(int *sums) {
+;   for (int i = 0; i < 1024; i++) {
+;     for (int j = 0; j < 1024; j++) {
+;       sums[i] += 5;
+;       sums[i+1024] *= 5;
+;     }
+;   }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sums) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc6, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+  %exitcond1 = icmp ne i32 %i.0, 1024
+  br i1 %exitcond1, label %for.body, label %for.end8
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %j.0, 1024
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %arrayidx = getelementptr inbounds i32* %sums, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, 5
+  store i32 %add, i32* %arrayidx, align 4
+  %add4 = add nsw i32 %i.0, 1024
+  %arrayidx5 = getelementptr inbounds i32* %sums, i32 %add4
+  %tmp2 = load i32* %arrayidx5, align 4
+  %mul = mul nsw i32 %tmp2, 5
+  store i32 %mul, i32* %arrayidx5, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %inc = add nsw i32 %j.0, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc6
+
+for.inc6:                                         ; preds = %for.end
+  %inc7 = add nsw i32 %i.0, 1
+  br label %for.cond
+
+for.end8:                                         ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_only_reduction_like_access.ll b/rc1/test/ScopInfo/reduction_only_reduction_like_access.ll
new file mode 100644
index 0000000..1cc98b0
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_only_reduction_like_access.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Reduction Type: ADD
+;
+; void f(int *sum) {
+;   for (int i = 0; i < 100; i++)
+;     sum[i] = sum[99-i] + i;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %sub = sub nsw i32 99, %i.0
+  %arrayidx = getelementptr inbounds i32* %sum, i32 %sub
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %i.0
+  %arrayidx1 = getelementptr inbounds i32* %sum, i32 %i.0
+  store i32 %add, i32* %arrayidx1, 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
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_simple_fp.ll b/rc1/test/ScopInfo/reduction_simple_fp.ll
new file mode 100644
index 0000000..41af402
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_simple_fp.ll
@@ -0,0 +1,64 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Function: f_no_fast_math
+; CHECK: Reduction Type: NONE
+; CHECK: Function: f_fast_math
+; CHECK: Reduction Type: ADD
+;
+; void f(float *sum) {
+;   for (int i = 0; i < 100; i++)
+;     *sum += 3.41 * i;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f_no_fast_math(float* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %conv = sitofp i32 %i.0 to float
+  %pi = fptrunc double 3.41 to float
+  %mul = fmul float %conv, %pi
+  %tmp = load float* %sum, align 4
+  %add = fadd float %tmp, %mul
+  store float %add, float* %sum, 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
+  ret void
+}
+
+define void @f_fast_math(float* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 100
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %conv = sitofp i32 %i.0 to float
+  %pi = fptrunc double 3.41 to float
+  %mul = fmul fast float %conv, %pi
+  %tmp = load float* %sum, align 4
+  %add = fadd fast float %tmp, %mul
+  store float %add, float* %sum, 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
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_simple_w_constant.ll b/rc1/test/ScopInfo/reduction_simple_w_constant.ll
new file mode 100644
index 0000000..ad5fdea
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_simple_w_constant.ll
@@ -0,0 +1,26 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Reduction Type: ADD
+;
+; void f(int *sum) {
+;   for (int i = 0; i <= 100; i++)
+;     sum += 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.cond, %entry
+  %i1.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
+  %sum.reload = load i32* %sum
+  %add = add nsw i32 %sum.reload, 3
+  %inc = add nsw i32 %i1.0, 1
+  store i32 %add, i32* %sum
+  %cmp = icmp slt i32 %i1.0, 100
+  br i1 %cmp, label %for.cond, label %for.end
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_simple_w_iv.ll b/rc1/test/ScopInfo/reduction_simple_w_iv.ll
new file mode 100644
index 0000000..c123c9b
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_simple_w_iv.ll
@@ -0,0 +1,27 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK: Reduction Type: ADD
+;
+; void f(int* sum) {
+;   for (int i = 0; i <= 100; i++)
+;     sum += i * 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.cond, %entr
+  %i1.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
+  %sum.reload = load i32* %sum
+  %mul = mul nsw i32 %i1.0, 3
+  %add = add nsw i32 %sum.reload, %mul
+  %inc = add nsw i32 %i1.0, 1
+  store i32 %add, i32* %sum
+  %cmp = icmp slt i32 %i1.0, 100
+  br i1 %cmp, label %for.cond, label %for.end
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
diff --git a/rc1/test/ScopInfo/reduction_two_identical_reads.ll b/rc1/test/ScopInfo/reduction_two_identical_reads.ll
new file mode 100644
index 0000000..160441b
--- /dev/null
+++ b/rc1/test/ScopInfo/reduction_two_identical_reads.ll
@@ -0,0 +1,66 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+; CHECK-NOT: Reduction like: 1
+;
+; Check that we do not mark these accesses as reduction like.
+; We do this for the case the loads are modelt with the same LLVM-IR value and
+; for the case there are different LLVM-IR values.
+;
+;    void f(int *A) {
+;      for (int i = 0; i < 1024; i++)
+;        A[i] = A[i] + A[i];
+;    }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f_one_load_case(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %add = add nsw i32 %tmp, %tmp
+  %arrayidx2 = getelementptr inbounds i32* %A, i32 %i.0
+  store i32 %add, i32* %arrayidx2, 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
+  ret void
+}
+
+define void @f_two_loads_case(i32* %A) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+  %exitcond = icmp ne i32 %i.0, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i32* %A, i32 %i.0
+  %tmp = load i32* %arrayidx, align 4
+  %arrayidxCopy = getelementptr inbounds i32* %A, i32 %i.0
+  %tmpCopy = load i32* %arrayidxCopy, align 4
+  %add = add nsw i32 %tmp, %tmpCopy
+  %arrayidx2 = getelementptr inbounds i32* %A, i32 %i.0
+  store i32 %add, i32* %arrayidx2, 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
+  ret void
+}
diff --git a/rc1/test/ScopInfo/scalar.ll b/rc1/test/ScopInfo/scalar.ll
new file mode 100644
index 0000000..ebdbc79
--- /dev/null
+++ b/rc1/test/ScopInfo/scalar.ll
@@ -0,0 +1,50 @@
+; RUN: opt %loadPolly -polly-scops -analyze -disable-polly-intra-scop-scalar-to-array < %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 void @f(i64* %a, i64 %N) {
+entry:
+  br label %for
+
+for:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.backedge ]
+  br label %S1
+
+S1:
+  %scevgep1 = getelementptr i64* %a, i64 %indvar
+  %val = load i64* %scevgep1, align 8
+  br label %S2
+
+S2:
+  %scevgep2 = getelementptr i64* %a, i64 %indvar
+  store i64 %val, i64* %scevgep2, align 8
+  br label %for.backedge
+
+for.backedge:
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp eq i64 %indvar.next, %N
+  br i1 %exitcond, label %return, label %for
+
+return:
+  ret void
+}
+
+; CHECK: Stmt_S1
+; CHECK:       Domain :=
+; CHECK:           [N] -> { Stmt_S1[i0] : i0 >= 0 and i0 <= -1 + N };
+; CHECK:       Scattering :=
+; CHECK:           [N] -> { Stmt_S1[i0] -> scattering[0, i0, 0] };
+; CHECK:       ReadAccess :=
+; CHECK:           [N] -> { Stmt_S1[i0] -> MemRef_a[i0] };
+; CHECK:       MustWriteAccess :=
+; CHECK:           [N] -> { Stmt_S1[i0] -> MemRef_val[] };
+; CHECK: Stmt_S2
+; CHECK:       Domain :=
+; CHECK:           [N] -> { Stmt_S2[i0] : i0 >= 0 and i0 <= -1 + N };
+; CHECK:       Scattering :=
+; CHECK:           [N] -> { Stmt_S2[i0] -> scattering[0, i0, 1] };
+; CHECK:       ReadAccess :=
+; CHECK:           [N] -> { Stmt_S2[i0] -> MemRef_val[] };
+; CHECK:       MustWriteAccess :=
+; CHECK:           [N] -> { Stmt_S2[i0] -> MemRef_a[i0] };
diff --git a/rc1/test/ScopInfo/simple_loop_1.ll b/rc1/test/ScopInfo/simple_loop_1.ll
new file mode 100644
index 0000000..33756ba
--- /dev/null
+++ b/rc1/test/ScopInfo/simple_loop_1.ll
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+
+; void f(int a[], int N) {
+;   int i;
+;   for (i = 0; i < N; ++i)
+;     a[i] = 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:
+  br label %bb
+
+bb:                                               ; preds = %bb, %entry
+  %i = phi i64 [ 0, %entry ], [ %i.inc, %bb ]
+  %scevgep = getelementptr i64* %a, i64 %i
+  store i64 %i, i64* %scevgep
+  %i.inc = add nsw i64 %i, 1
+  %exitcond = icmp eq i64 %i.inc, %N
+  br i1 %exitcond, label %return, label %bb
+
+return:                                           ; preds = %bb, %entry
+  ret void
+}
+
+; CHECK: Assumed Context:
+; CHECK:   {  :  }
+
+; CHECK:  Stmt_bb
+; CHECK:        Domain :=
+; CHECK:            [N] -> { Stmt_bb[i0] : i0 >= 0 and i0 <= -1 + N };
+; CHECK:        Scattering :=
+; CHECK:            [N] -> { Stmt_bb[i0] -> scattering[0, i0, 0] };
+; CHECK:        MustWriteAccess := [Reduction Type: NONE]
+; CHECK:            [N] -> { Stmt_bb[i0] -> MemRef_a[i0] };
diff --git a/rc1/test/ScopInfo/simple_nonaffine_loop.ll b/rc1/test/ScopInfo/simple_nonaffine_loop.ll
new file mode 100644
index 0000000..09182c4
--- /dev/null
+++ b/rc1/test/ScopInfo/simple_nonaffine_loop.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -polly-scops -polly-allow-nonaffine -analyze < %s | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
+@.str = private unnamed_addr constant [17 x i8] c"Random Value: %d\00", align 1
+
+define i32 @main() nounwind uwtable ssp {
+entry:
+  %A = alloca [1048576 x i32], align 16
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %0 = phi i32 [ 0, %entry.split ], [ %1, %for.body ]
+  %mul = mul i32 %0, 2
+  %mul1 = mul nsw i32 %0, %0
+  %idxprom1 = zext i32 %mul1 to i64
+  %arrayidx = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom1
+  store i32 %mul, i32* %arrayidx, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  %call = call i32 @rand() nounwind
+  %rem = srem i32 %call, 1024
+  %mul2 = shl nsw i32 %rem, 10
+  %idxprom3 = sext i32 %mul2 to i64
+  %arrayidx4 = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom3
+  %2 = load i32* %arrayidx4, align 16
+  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i64 0, i64 0), i32 %2) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @rand()
+; CHECK:                { Stmt_for_body[i0] -> MemRef_A[o0] };
diff --git a/rc1/test/ScopInfo/simple_nonaffine_loop_not.ll b/rc1/test/ScopInfo/simple_nonaffine_loop_not.ll
new file mode 100644
index 0000000..979eb15
--- /dev/null
+++ b/rc1/test/ScopInfo/simple_nonaffine_loop_not.ll
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | not FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.7.2"
+
+@.str = private unnamed_addr constant [17 x i8] c"Random Value: %d\00", align 1
+
+define i32 @main() nounwind uwtable ssp {
+entry:
+  %A = alloca [1048576 x i32], align 16
+  br label %entry.split
+
+entry.split:                                      ; preds = %entry
+  br label %for.body
+
+for.body:                                         ; preds = %entry.split, %for.body
+  %0 = phi i32 [ 0, %entry.split ], [ %1, %for.body ]
+  %mul = mul i32 %0, 2
+  %mul1 = mul nsw i32 %0, %0
+  %idxprom1 = zext i32 %mul1 to i64
+  %arrayidx = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom1
+  store i32 %mul, i32* %arrayidx, align 4
+  %1 = add nsw i32 %0, 1
+  %exitcond = icmp ne i32 %1, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:                                          ; preds = %for.body
+  %call = call i32 @rand() nounwind
+  %rem = srem i32 %call, 1024
+  %mul2 = shl nsw i32 %rem, 10
+  %idxprom3 = sext i32 %mul2 to i64
+  %arrayidx4 = getelementptr inbounds [1048576 x i32]* %A, i64 0, i64 %idxprom3
+  %2 = load i32* %arrayidx4, align 16
+  %call5 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([17 x i8]* @.str, i64 0, i64 0), i32 %2) nounwind
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @rand()
+; CHECK:                { Stmt_for_body[i0] -> MemRef_A[o0] };
diff --git a/rc1/test/ScopInfo/smax.ll b/rc1/test/ScopInfo/smax.ll
new file mode 100644
index 0000000..73998df
--- /dev/null
+++ b/rc1/test/ScopInfo/smax.ll
@@ -0,0 +1,26 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:32-n32-S64"
+target triple = "thumbv7-none-linux-gnueabi"
+
+define void @foo(i32 * noalias %data, i32 * noalias %ptr, i32 %x_pos, i32 %w) {
+entry:
+  br label %for.body
+
+for.body:
+  %x = phi i32 [ 0, %entry ], [ %x.inc, %for.body ]
+  %add = add nsw i32 %x, %x_pos
+  %cmp1 = icmp sgt i32 %add, %w
+  %cond = select i1 %cmp1, i32 %w, i32 %add
+  %arrayidx = getelementptr inbounds i32* %ptr, i32 %cond
+  store i32 1, i32* %arrayidx
+  %x.inc = add nsw i32 %x, 1
+  %cmp = icmp slt i32 %x.inc, 2
+  br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+  ret void
+}
+
+; We check that there are only two parameters, but not a third one that
+; represents the smax() expression. This test case comes from PR 18155.
+; CHECK: [w, x_pos]
diff --git a/rc1/test/ScopInfo/undef_in_cond.ll b/rc1/test/ScopInfo/undef_in_cond.ll
new file mode 100644
index 0000000..815968e
--- /dev/null
+++ b/rc1/test/ScopInfo/undef_in_cond.ll
@@ -0,0 +1,23 @@
+; RUN: opt %loadPolly -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-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: Invalid Scop!
diff --git a/rc1/test/TempScop/inter_bb_scalar_dep.ll b/rc1/test/TempScop/inter_bb_scalar_dep.ll
new file mode 100644
index 0000000..e83bf5b
--- /dev/null
+++ b/rc1/test/TempScop/inter_bb_scalar_dep.ll
@@ -0,0 +1,54 @@
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -disable-polly-intra-scop-scalar-to-array -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir  -polly-codegen-scev -disable-polly-intra-scop-scalar-to-array -analyze < %s | FileCheck %s
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     init = *init_ptr;
+;     for (i = 0; i < N; ++i) {
+;       A[i] = init + 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"
+
+; Function Attrs: nounwind
+define void @f(i64* noalias %A, i64 %N, i64* noalias %init_ptr) #0 {
+entry:
+  br label %for.i
+
+for.i:                                            ; preds = %for.i.end, %entry
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:                                       ; preds = %for.i
+  %init = load i64* %init_ptr
+; CHECK: BB: entry.next
+; CHECK: Read init_ptr[0]
+; CHECK: Write init[0]
+  br label %for.j
+
+for.j:                                            ; preds = %for.j, %entry.next
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %init_plus_two = add i64 %init, 2
+; CHECK: Read init[0]
+; CHECK: Write A[{0,+,8}<%for.j>]
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_plus_two, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:                                        ; preds = %for.j
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:                                           ; preds = %for.i.end
+  ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/rc1/test/TempScop/intra_and_inter_bb_scalar_dep.ll b/rc1/test/TempScop/intra_and_inter_bb_scalar_dep.ll
new file mode 100644
index 0000000..ce4c49f
--- /dev/null
+++ b/rc1/test/TempScop/intra_and_inter_bb_scalar_dep.ll
@@ -0,0 +1,58 @@
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -disable-polly-intra-scop-scalar-to-array -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -polly-codegen-scev -disable-polly-intra-scop-scalar-to-array -analyze < %s | FileCheck %s
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     init = *init_ptr;
+;     for (i = 0; i < N; ++i) {
+;       init2 = *init_ptr;
+;       A[i] = init + init2;
+;     }
+;   }
+; }
+
+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"
+
+; Function Attrs: nounwind
+define void @f(i64* noalias %A, i64 %N, i64* noalias %init_ptr) #0 {
+entry:
+  br label %for.i
+
+for.i:                                            ; preds = %for.i.end, %entry
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:                                       ; preds = %for.i
+  %init = load i64* %init_ptr
+; CHECK: BB: entry.next
+; CHECK: Read init_ptr[0]
+; CHECK: Write init[0]
+  br label %for.j
+
+for.j:                                            ; preds = %for.j, %entry.next
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %init_2 = load i64* %init_ptr
+  %init_sum = add i64 %init, %init_2
+; CHECK: BB: for.j
+; CHECK: Read init[0]
+; CHECK: Read init_ptr[0]
+; CHECK: Write A[{0,+,8}<%for.j>]
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_sum, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:                                        ; preds = %for.j
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:                                           ; preds = %for.i.end
+  ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/rc1/test/TempScop/intra_bb_scalar_dep.ll b/rc1/test/TempScop/intra_bb_scalar_dep.ll
new file mode 100644
index 0000000..d6e4211
--- /dev/null
+++ b/rc1/test/TempScop/intra_bb_scalar_dep.ll
@@ -0,0 +1,52 @@
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -disable-polly-intra-scop-scalar-to-array -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir  -polly-codegen-scev -disable-polly-intra-scop-scalar-to-array -analyze < %s | FileCheck %s
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     for (i = 0; i < N; ++i) {
+;       init = *init_ptr;
+;       A[i] = init + 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"
+
+; Function Attrs: nounwind
+define void @f(i64* noalias %A, i64 %N, i64* noalias %init_ptr) #0 {
+entry:
+  br label %for.i
+
+for.i:                                            ; preds = %for.i.end, %entry
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:                                       ; preds = %for.i
+  br label %for.j
+
+for.j:                                            ; preds = %for.j, %entry.next
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %init = load i64* %init_ptr
+  %init_plus_two = add i64 %init, 2
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_plus_two, i64* %scevgep
+; CHECK: BB: for.j
+; CHECK: Read init_ptr[0]
+; CHECK: Write A[{0,+,8}<%for.j>]
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:                                        ; preds = %for.j
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:                                           ; preds = %for.i.end
+  ret void
+}
+
+attributes #0 = { nounwind }
diff --git a/rc1/test/TempScop/not-a-reduction.ll b/rc1/test/TempScop/not-a-reduction.ll
new file mode 100644
index 0000000..1e1e328
--- /dev/null
+++ b/rc1/test/TempScop/not-a-reduction.ll
@@ -0,0 +1,51 @@
+; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s 2>&1 | not FileCheck %s
+
+;#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];
+;	}
+;}
+
+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
diff --git a/rc1/test/TempScop/scalar_to_array.ll b/rc1/test/TempScop/scalar_to_array.ll
new file mode 100644
index 0000000..c2225c4
--- /dev/null
+++ b/rc1/test/TempScop/scalar_to_array.ll
@@ -0,0 +1,186 @@
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -disable-polly-intra-scop-scalar-to-array -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -disable-polly-intra-scop-scalar-to-array -polly-codegen-scev -analyze < %s | FileCheck %s
+
+; ModuleID = 'scalar_to_array.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"
+
+@A = common global [1024 x float] zeroinitializer, align 8
+
+; CHECK: empty
+; Function Attrs: nounwind
+define i32 @empty() #0 {
+entry:
+  fence seq_cst
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body, label %return
+
+for.body:                                         ; preds = %for.cond
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:                                           ; preds = %for.cond
+  fence seq_cst
+  ret i32 0
+}
+
+; CHECK: array_access
+; Function Attrs: nounwind
+define i32 @array_access() #0 {
+entry:
+  fence seq_cst
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body, label %return
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %float = uitofp i64 %indvar to float
+  store float %float, float* %arrayidx
+  br label %for.inc
+; CHECK: BB: for.body
+; CHECK-NOT: Read
+; CHECK: Write A[{0,+,4}<%for.cond>]
+
+for.inc:                                          ; preds = %for.body
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:                                           ; preds = %for.cond
+  fence seq_cst
+  ret i32 0
+}
+
+; Function Attrs: nounwind
+; CHECK: intra_scop_dep
+define i32 @intra_scop_dep() #0 {
+entry:
+  fence seq_cst
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body.a, label %return
+
+for.body.a:                                       ; preds = %for.cond
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %scalar = load float* %arrayidx
+  br label %for.body.b
+; CHECK: BB: for.body.a
+; CHECK: Read A[{0,+,4}<%for.cond>]
+; CHECK: Write scalar[0]
+
+for.body.b:                                       ; preds = %for.body.a
+  %arrayidx2 = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %float = uitofp i64 %indvar to float
+  %sum = fadd float %scalar, %float
+  store float %sum, float* %arrayidx2
+  br label %for.inc
+; CHECK: BB: for.body.b
+; CHECK: Read scalar[0]
+; CHECK: Write A[{0,+,4}<%for.cond>]
+
+for.inc:                                          ; preds = %for.body.b
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:                                           ; preds = %for.cond
+  fence seq_cst
+  ret i32 0
+}
+
+; It is not possible to have a scop which accesses a scalar element that is
+; a global variable. All global variables are pointers containing possibly
+; a single element. Hence they do not need to be handled anyways.
+; Please note that this is still required when scalar to array rewritting is
+; disabled.
+
+; CHECK: use_after_scop
+; Function Attrs: nounwind
+define i32 @use_after_scop() #0 {
+entry:
+  %scalar.s2a = alloca float
+  fence seq_cst
+  br label %for.head
+
+for.head:                                         ; preds = %for.inc, %entry
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %entry ]
+  br label %for.body
+
+for.body:                                         ; preds = %for.head
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  %scalar = load float* %arrayidx
+  store float %scalar, float* %scalar.s2a
+; Escaped uses are still required to be rewritten to stack variable.
+; CHECK: BB: for.body
+; CHECK: Read A[{0,+,4}<%for.head>]
+; CHECK: Write scalar.s2a[0]
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %indvar.next = add i64 %indvar, 1
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.head, label %for.after
+
+for.after:                                        ; preds = %for.inc
+  %scalar.loadoutside = load float* %scalar.s2a
+  fence seq_cst
+  %return_value = fptosi float %scalar.loadoutside to i32
+  br label %return
+
+return:                                           ; preds = %for.after
+  ret i32 %return_value
+}
+
+; We currently do not transform scalar references, that have only read accesses
+; in the scop. There are two reasons for this:
+;
+;  o We don't introduce additional memory references which may yield to compile
+;    time overhead.
+;  o For integer values, such a translation may block the use of scalar
+;    evolution on those values.
+;
+; CHECK: before_scop
+; Function Attrs: nounwind
+define i32 @before_scop() #0 {
+entry:
+  br label %preheader
+
+preheader:                                        ; preds = %entry
+  %scalar = fadd float 4.000000e+00, 5.000000e+00
+  fence seq_cst
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %preheader
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %preheader ]
+  %exitcond = icmp ne i64 %indvar, 1024
+  br i1 %exitcond, label %for.body, label %return
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr [1024 x float]* @A, i64 0, i64 %indvar
+  store float %scalar, float* %arrayidx
+  br label %for.inc
+; CHECK: BB: for.body
+; CHECK: Write A[{0,+,4}<%for.cond>]
+
+for.inc:                                          ; preds = %for.body
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond
+
+return:                                           ; preds = %for.cond
+  fence seq_cst
+  ret i32 0
+}
+
+attributes #0 = { nounwind }
diff --git a/rc1/test/TempScop/tempscop-printing.ll b/rc1/test/TempScop/tempscop-printing.ll
new file mode 100644
index 0000000..04b5c67
--- /dev/null
+++ b/rc1/test/TempScop/tempscop-printing.ll
@@ -0,0 +1,94 @@
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -basicaa -polly-analyze-ir -analyze -disable-polly-intra-scop-scalar-to-array < %s | FileCheck %s -check-prefix=SCALARACCESS
+
+; void f(long A[], int N, int *init_ptr) {
+;   long i, j;
+;
+;   for (i = 0; i < N; ++i) {
+;     init = *init_ptr;
+;     for (i = 0; i < N; ++i) {
+;       A[i] = init + 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* noalias %A, i64 %N, i64* noalias %init_ptr) nounwind {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:
+; CHECK: BB: entry.next
+; SCALARACCESS: BB: entry.next
+  %init = load i64* %init_ptr
+; CHECK:  Read init_ptr[0]
+; CHECK:  Write init.s2a[0]
+; SCALARACCESS: Read init_ptr[0]
+; SCALARACCESS:  Write init[0]
+  br label %for.j
+
+for.j:
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+; CHECK: BB: for.j
+; CHECK: Read init.s2a[0]
+; CHECK: Write A[{0,+,8}<%for.j>]
+
+; SCALARACCESS: BB: for.j
+; SCALARACCESS: Read init
+; SCALARACCESS: Write A[{0,+,8}<%for.j>]
+  %init_plus_two = add i64 %init, 2
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init_plus_two, i64* %scevgep
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:
+  ret void
+}
+
+define void @g(i64* noalias %A, i64 %N, i64* noalias %init_ptr) nounwind {
+entry:
+  br label %for.i
+
+for.i:
+  %indvar.i = phi i64 [ 0, %entry ], [ %indvar.i.next, %for.i.end ]
+  %indvar.i.next = add nsw i64 %indvar.i, 1
+  br label %entry.next
+
+entry.next:
+; SCALARACCESS: BB: entry.next
+  %init = load i64* %init_ptr
+; SCALARACCESS: Read init_ptr[0]
+; SCALARACCESS:  Write init[0]
+  br label %for.j
+
+for.j:
+; SCALARACCESS: BB: for.j
+  %indvar.j = phi i64 [ 0, %entry.next ], [ %indvar.j.next, %for.j ]
+  %scevgep = getelementptr i64* %A, i64 %indvar.j
+  store i64 %init, i64* %scevgep
+; SCALARACCESS: Read init
+; SCALARACCESS: Write A[{0,+,8}<%for.j>]
+  %indvar.j.next = add nsw i64 %indvar.j, 1
+  %exitcond.j = icmp eq i64 %indvar.j.next, %N
+  br i1 %exitcond.j, label %for.i.end, label %for.j
+
+for.i.end:
+  %exitcond.i = icmp eq i64 %indvar.i.next, %N
+  br i1 %exitcond.i, label %return, label %for.i
+
+return:
+  ret void
+}
diff --git a/rc1/test/create_ll.sh b/rc1/test/create_ll.sh
new file mode 100755
index 0000000..ddd4d17
--- /dev/null
+++ b/rc1/test/create_ll.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+LLFILE=`echo $1 | sed -e 's/\.c/.ll/g'`
+LLFILE_TMP=${LLFILE}.tmp
+
+# The number of lines to cut of the LLVM-IR file clang produces.
+CUT_N_LINES=9
+
+clang -c -S -emit-llvm -O0 $1 -o ${LLFILE}
+
+opt -correlated-propagation -mem2reg -instcombine -loop-simplify -indvars \
+-instnamer ${LLFILE} -S -o ${LLFILE_TMP}
+
+# Insert a header into the new testcase containing a sample RUN line a FIXME and
+# an XFAIL. Then insert the formated C code and finally the LLVM-IR without
+# attributes, the module ID or the target triple.
+echo '; RUN: opt %loadPolly -analyze < %s | FileCheck %s' > ${LLFILE}
+echo ';' >> ${LLFILE}
+echo '; FIXME: Edit the run line and add checks!' >> ${LLFILE}
+echo ';' >> ${LLFILE}
+echo '; XFAIL: *' >> ${LLFILE}
+echo ';' >> ${LLFILE}
+clang-format $1 | sed -e 's/^/;    /' >> ${LLFILE}
+echo ';' >> ${LLFILE}
+
+cat ${LLFILE_TMP} | sed -e 's/ \#0//' >> ${LLFILE}
+sed -i".tmp" '/; Function Attrs:/d' ${LLFILE}
+sed -i".tmp" '/; ModuleID =/d' ${LLFILE}
+sed -i".tmp" '/target triple/d' ${LLFILE}
+
+head --lines=-${CUT_N_LINES} ${LLFILE} > ${LLFILE_TMP}
+
+mv ${LLFILE_TMP} ${LLFILE}
diff --git a/rc1/test/lit.cfg b/rc1/test/lit.cfg
new file mode 100644
index 0000000..0d7eb3b
--- /dev/null
+++ b/rc1/test/lit.cfg
@@ -0,0 +1,126 @@
+# -*clang- Python -*-
+
+import os
+import platform
+import re
+
+import lit.formats
+import lit.util
+
+# 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_config.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_config.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_config.params.get('polly_site_config', None)
+    if site_cfg and os.path.exists(site_cfg):
+        lit_config.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_config.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_config.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_config.fatal('No site specific configuration available!')
+
+    # Okay, that worked. Notify the user of the automagic, and reconfigure.
+    lit_config.note('using out-of-tree build at %r' % polly_obj_root)
+    lit_config.load_config(config, site_cfg)
+    raise SystemExit
+
+# opt knows whether it is compiled with -DNDEBUG.
+import subprocess
+try:
+    opt_cmd = subprocess.Popen([os.path.join(llvm_tools_dir, 'opt'), '-version'],
+                           stdout = subprocess.PIPE)
+except OSError, why:
+    print "Could not find opt in " + llvm_tools_dir
+    exit(42)
+
+if re.search(r'with assertions', opt_cmd.stdout.read()):
+    config.available_features.add('asserts')
+opt_cmd.wait()
+
+try:
+    llvm_config_cmd = subprocess.Popen([os.path.join(llvm_tools_dir,
+                                                     'llvm-config'),
+                                        '--targets-built'],
+                                       stdout = subprocess.PIPE)
+except OSError, why:
+    print "Could not find llvm-config in " + llvm_tools_dir
+    exit(42)
+
+if re.search(r'NVPTX', llvm_config_cmd.stdout.read()):
+    config.available_features.add('nvptx-registered-target')
+llvm_config_cmd.wait()
diff --git a/rc1/test/lit.site.cfg.in b/rc1/test/lit.site.cfg.in
new file mode 100644
index 0000000..9cfbca1
--- /dev/null
+++ b/rc1/test/lit.site.cfg.in
@@ -0,0 +1,47 @@
+## 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.polly_lib_dir = "@POLLY_LIB_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+config.enable_gpgpu_codegen = "@CUDALIB_FOUND@"
+config.cloog_found = "@CLOOG_FOUND@"
+config.link_polly_into_tools = "@LINK_POLLY_INTO_TOOLS@"
+
+## Check the current platform with regex
+import re
+EAT_ERR_ON_X86 = ' '
+if (re.match(r'^x86_64*', '@TARGET_TRIPLE@') == None) :
+  EAT_ERR_ON_X86 = '|| echo \"error is eaten\"'
+
+# 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_config.params
+    config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
+except KeyError,e:
+    key, = e.args
+    lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+if config.link_polly_into_tools == '' or \
+   config.link_polly_into_tools.lower() == '0' or \
+   config.link_polly_into_tools.lower() == 'n' or \
+   config.link_polly_into_tools.lower() == 'no' or \
+   config.link_polly_into_tools.lower() == 'off' or \
+   config.link_polly_into_tools.lower() == 'false' or \
+   config.link_polly_into_tools.lower() == 'notfound' or \
+   config.link_polly_into_tools.lower() == 'link_polly_into_tools-notfound':
+    config.substitutions.append(('%loadPolly', '-load '
+                                 + config.polly_lib_dir + '/LLVMPolly@LLVM_SHLIBEXT@'))
+else:
+    config.substitutions.append(('%loadPolly', ''))
+
+config.substitutions.append(('%defaultOpts', ' -basicaa -polly-prepare'))
+config.substitutions.append(('%polybenchOpts', ' -O3 -loop-simplify -indvars '))
+config.substitutions.append(('%vector-opt', '-polly-vectorizer=polly'))
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@POLLY_SOURCE_DIR@/test/lit.cfg")
diff --git a/rc1/test/polly.ll b/rc1/test/polly.ll
new file mode 100644
index 0000000..c09f983
--- /dev/null
+++ b/rc1/test/polly.ll
@@ -0,0 +1,12 @@
+; 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
diff --git a/rc1/tools/CMakeLists.txt b/rc1/tools/CMakeLists.txt
new file mode 100644
index 0000000..4ce60e1
--- /dev/null
+++ b/rc1/tools/CMakeLists.txt
@@ -0,0 +1,5 @@
+if (CUDALIB_FOUND)
+  add_subdirectory(GPURuntime)
+endif (CUDALIB_FOUND)
+
+set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE)
diff --git a/rc1/tools/GPURuntime/CMakeLists.txt b/rc1/tools/GPURuntime/CMakeLists.txt
new file mode 100644
index 0000000..822e4de
--- /dev/null
+++ b/rc1/tools/GPURuntime/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(MODULE TRUE)
+set(LLVM_NO_RTTI 1)
+
+add_polly_library(GPURuntime
+  GPUJIT.c
+  )
+
+set_target_properties(GPURuntime
+  PROPERTIES
+  LINKER_LANGUAGE C
+  PREFIX "lib"
+  )
diff --git a/rc1/tools/GPURuntime/GPUJIT.c b/rc1/tools/GPURuntime/GPUJIT.c
new file mode 100644
index 0000000..a03ebe9
--- /dev/null
+++ b/rc1/tools/GPURuntime/GPUJIT.c
@@ -0,0 +1,431 @@
+/******************** GPUJIT.cpp - GPUJIT Execution Engine                     \
+ * ********************/
+/*                                                                            */
+/*                     The LLVM Compiler Infrastructure                       */
+/*                                                                            */
+/* This file is dual licensed under the MIT and the University of Illinois    */
+/* Open Source License. See LICENSE.TXT for details.                         */
+/*                                                                            */
+/******************************************************************************/
+/*                                                                            */
+/*  This file implements GPUJIT, a ptx string execution engine for GPU.       */
+/*                                                                            */
+/******************************************************************************/
+
+#include "GPUJIT.h"
+#include <cuda.h>
+#include <cuda_runtime.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+/* Define Polly's GPGPU data types. */
+struct PollyGPUContextT {
+  CUcontext Cuda;
+};
+
+struct PollyGPUModuleT {
+  CUmodule Cuda;
+};
+
+struct PollyGPUFunctionT {
+  CUfunction Cuda;
+};
+
+struct PollyGPUDeviceT {
+  CUdevice Cuda;
+};
+
+struct PollyGPUDevicePtrT {
+  CUdeviceptr Cuda;
+};
+
+struct PollyGPUEventT {
+  cudaEvent_t Cuda;
+};
+
+/* Dynamic library handles for the CUDA and CUDA runtime library. */
+static void *HandleCuda;
+static void *HandleCudaRT;
+
+/* Type-defines of function pointer to CUDA driver APIs. */
+typedef CUresult CUDAAPI CuMemAllocFcnTy(CUdeviceptr *, size_t);
+static CuMemAllocFcnTy *CuMemAllocFcnPtr;
+
+typedef CUresult CUDAAPI CuFuncSetBlockShapeFcnTy(CUfunction, int, int, int);
+static CuFuncSetBlockShapeFcnTy *CuFuncSetBlockShapeFcnPtr;
+
+typedef CUresult CUDAAPI
+CuParamSetvFcnTy(CUfunction, int, void *, unsigned int);
+static CuParamSetvFcnTy *CuParamSetvFcnPtr;
+
+typedef CUresult CUDAAPI CuParamSetSizeFcnTy(CUfunction, unsigned int);
+static CuParamSetSizeFcnTy *CuParamSetSizeFcnPtr;
+
+typedef CUresult CUDAAPI CuLaunchGridFcnTy(CUfunction, int, int);
+static CuLaunchGridFcnTy *CuLaunchGridFcnPtr;
+
+typedef CUresult CUDAAPI CuMemcpyDtoHFcnTy(void *, CUdeviceptr, size_t);
+static CuMemcpyDtoHFcnTy *CuMemcpyDtoHFcnPtr;
+
+typedef CUresult CUDAAPI CuMemcpyHtoDFcnTy(CUdeviceptr, const void *, size_t);
+static CuMemcpyHtoDFcnTy *CuMemcpyHtoDFcnPtr;
+
+typedef CUresult CUDAAPI CuMemFreeFcnTy(CUdeviceptr);
+static CuMemFreeFcnTy *CuMemFreeFcnPtr;
+
+typedef CUresult CUDAAPI CuModuleUnloadFcnTy(CUmodule);
+static CuModuleUnloadFcnTy *CuModuleUnloadFcnPtr;
+
+typedef CUresult CUDAAPI CuCtxDestroyFcnTy(CUcontext);
+static CuCtxDestroyFcnTy *CuCtxDestroyFcnPtr;
+
+typedef CUresult CUDAAPI CuInitFcnTy(unsigned int);
+static CuInitFcnTy *CuInitFcnPtr;
+
+typedef CUresult CUDAAPI CuDeviceGetCountFcnTy(int *);
+static CuDeviceGetCountFcnTy *CuDeviceGetCountFcnPtr;
+
+typedef CUresult CUDAAPI CuCtxCreateFcnTy(CUcontext *, unsigned int, CUdevice);
+static CuCtxCreateFcnTy *CuCtxCreateFcnPtr;
+
+typedef CUresult CUDAAPI CuDeviceGetFcnTy(CUdevice *, int);
+static CuDeviceGetFcnTy *CuDeviceGetFcnPtr;
+
+typedef CUresult CUDAAPI CuModuleLoadDataExFcnTy(
+    CUmodule *, const void *, unsigned int, CUjit_option *, void **);
+static CuModuleLoadDataExFcnTy *CuModuleLoadDataExFcnPtr;
+
+typedef CUresult CUDAAPI
+CuModuleGetFunctionFcnTy(CUfunction *, CUmodule, const char *);
+static CuModuleGetFunctionFcnTy *CuModuleGetFunctionFcnPtr;
+
+typedef CUresult CUDAAPI CuDeviceComputeCapabilityFcnTy(int *, int *, CUdevice);
+static CuDeviceComputeCapabilityFcnTy *CuDeviceComputeCapabilityFcnPtr;
+
+typedef CUresult CUDAAPI CuDeviceGetNameFcnTy(char *, int, CUdevice);
+static CuDeviceGetNameFcnTy *CuDeviceGetNameFcnPtr;
+
+/* Type-defines of function pointer ot CUDA runtime APIs. */
+typedef cudaError_t CUDARTAPI CudaEventCreateFcnTy(cudaEvent_t *);
+static CudaEventCreateFcnTy *CudaEventCreateFcnPtr;
+
+typedef cudaError_t CUDARTAPI CudaEventRecordFcnTy(cudaEvent_t, cudaStream_t);
+static CudaEventRecordFcnTy *CudaEventRecordFcnPtr;
+
+typedef cudaError_t CUDARTAPI CudaEventSynchronizeFcnTy(cudaEvent_t);
+static CudaEventSynchronizeFcnTy *CudaEventSynchronizeFcnPtr;
+
+typedef cudaError_t CUDARTAPI
+CudaEventElapsedTimeFcnTy(float *, cudaEvent_t, cudaEvent_t);
+static CudaEventElapsedTimeFcnTy *CudaEventElapsedTimeFcnPtr;
+
+typedef cudaError_t CUDARTAPI CudaEventDestroyFcnTy(cudaEvent_t);
+static CudaEventDestroyFcnTy *CudaEventDestroyFcnPtr;
+
+typedef cudaError_t CUDARTAPI CudaThreadSynchronizeFcnTy(void);
+static CudaThreadSynchronizeFcnTy *CudaThreadSynchronizeFcnPtr;
+
+static void *getAPIHandle(void *Handle, const char *FuncName) {
+  char *Err;
+  void *FuncPtr;
+  dlerror();
+  FuncPtr = dlsym(Handle, FuncName);
+  if ((Err = dlerror()) != 0) {
+    fprintf(stdout, "Load CUDA driver API failed: %s. \n", Err);
+    return 0;
+  }
+  return FuncPtr;
+}
+
+static int initialDeviceAPILibraries() {
+  HandleCuda = dlopen("libcuda.so", RTLD_LAZY);
+  if (!HandleCuda) {
+    printf("Cannot open library: %s. \n", dlerror());
+    return 0;
+  }
+
+  HandleCudaRT = dlopen("libcudart.so", RTLD_LAZY);
+  if (!HandleCudaRT) {
+    printf("Cannot open library: %s. \n", dlerror());
+    return 0;
+  }
+
+  return 1;
+}
+
+static int initialDeviceAPIs() {
+  if (initialDeviceAPILibraries() == 0)
+    return 0;
+
+  /* Get function pointer to CUDA Driver APIs.
+   *
+   * Note that compilers conforming to the ISO C standard are required to
+   * generate a warning if a conversion from a void * pointer to a function
+   * pointer is attempted as in the following statements. The warning
+   * of this kind of cast may not be emitted by clang and new versions of gcc
+   * as it is valid on POSIX 2008.
+   */
+  CuFuncSetBlockShapeFcnPtr = (CuFuncSetBlockShapeFcnTy *)getAPIHandle(
+      HandleCuda, "cuFuncSetBlockShape");
+
+  CuParamSetvFcnPtr =
+      (CuParamSetvFcnTy *)getAPIHandle(HandleCuda, "cuParamSetv");
+
+  CuParamSetSizeFcnPtr =
+      (CuParamSetSizeFcnTy *)getAPIHandle(HandleCuda, "cuParamSetSize");
+
+  CuLaunchGridFcnPtr =
+      (CuLaunchGridFcnTy *)getAPIHandle(HandleCuda, "cuLaunchGrid");
+
+  CuMemAllocFcnPtr =
+      (CuMemAllocFcnTy *)getAPIHandle(HandleCuda, "cuMemAlloc_v2");
+
+  CuMemFreeFcnPtr = (CuMemFreeFcnTy *)getAPIHandle(HandleCuda, "cuMemFree_v2");
+
+  CuMemcpyDtoHFcnPtr =
+      (CuMemcpyDtoHFcnTy *)getAPIHandle(HandleCuda, "cuMemcpyDtoH_v2");
+
+  CuMemcpyHtoDFcnPtr =
+      (CuMemcpyHtoDFcnTy *)getAPIHandle(HandleCuda, "cuMemcpyHtoD_v2");
+
+  CuModuleUnloadFcnPtr =
+      (CuModuleUnloadFcnTy *)getAPIHandle(HandleCuda, "cuModuleUnload");
+
+  CuCtxDestroyFcnPtr =
+      (CuCtxDestroyFcnTy *)getAPIHandle(HandleCuda, "cuCtxDestroy");
+
+  CuInitFcnPtr = (CuInitFcnTy *)getAPIHandle(HandleCuda, "cuInit");
+
+  CuDeviceGetCountFcnPtr =
+      (CuDeviceGetCountFcnTy *)getAPIHandle(HandleCuda, "cuDeviceGetCount");
+
+  CuDeviceGetFcnPtr =
+      (CuDeviceGetFcnTy *)getAPIHandle(HandleCuda, "cuDeviceGet");
+
+  CuCtxCreateFcnPtr =
+      (CuCtxCreateFcnTy *)getAPIHandle(HandleCuda, "cuCtxCreate_v2");
+
+  CuModuleLoadDataExFcnPtr =
+      (CuModuleLoadDataExFcnTy *)getAPIHandle(HandleCuda, "cuModuleLoadDataEx");
+
+  CuModuleGetFunctionFcnPtr = (CuModuleGetFunctionFcnTy *)getAPIHandle(
+      HandleCuda, "cuModuleGetFunction");
+
+  CuDeviceComputeCapabilityFcnPtr =
+      (CuDeviceComputeCapabilityFcnTy *)getAPIHandle(
+          HandleCuda, "cuDeviceComputeCapability");
+
+  CuDeviceGetNameFcnPtr =
+      (CuDeviceGetNameFcnTy *)getAPIHandle(HandleCuda, "cuDeviceGetName");
+
+  /* Get function pointer to CUDA Runtime APIs. */
+  CudaEventCreateFcnPtr =
+      (CudaEventCreateFcnTy *)getAPIHandle(HandleCudaRT, "cudaEventCreate");
+
+  CudaEventRecordFcnPtr =
+      (CudaEventRecordFcnTy *)getAPIHandle(HandleCudaRT, "cudaEventRecord");
+
+  CudaEventSynchronizeFcnPtr = (CudaEventSynchronizeFcnTy *)getAPIHandle(
+      HandleCudaRT, "cudaEventSynchronize");
+
+  CudaEventElapsedTimeFcnPtr = (CudaEventElapsedTimeFcnTy *)getAPIHandle(
+      HandleCudaRT, "cudaEventElapsedTime");
+
+  CudaEventDestroyFcnPtr =
+      (CudaEventDestroyFcnTy *)getAPIHandle(HandleCudaRT, "cudaEventDestroy");
+
+  CudaThreadSynchronizeFcnPtr = (CudaThreadSynchronizeFcnTy *)getAPIHandle(
+      HandleCudaRT, "cudaThreadSynchronize");
+
+  return 1;
+}
+
+void polly_initDevice(PollyGPUContext **Context, PollyGPUDevice **Device) {
+  int Major = 0, Minor = 0, DeviceID = 0;
+  char DeviceName[256];
+  int DeviceCount = 0;
+
+  /* Get API handles. */
+  if (initialDeviceAPIs() == 0) {
+    fprintf(stdout, "Getting the \"handle\" for the CUDA driver API failed.\n");
+    exit(-1);
+  }
+
+  if (CuInitFcnPtr(0) != CUDA_SUCCESS) {
+    fprintf(stdout, "Initializing the CUDA driver API failed.\n");
+    exit(-1);
+  }
+
+  /* Get number of devices that supports CUDA. */
+  CuDeviceGetCountFcnPtr(&DeviceCount);
+  if (DeviceCount == 0) {
+    fprintf(stdout, "There is no device supporting CUDA.\n");
+    exit(-1);
+  }
+
+  /* We select the 1st device as default. */
+  *Device = malloc(sizeof(PollyGPUDevice));
+  if (*Device == 0) {
+    fprintf(stdout, "Allocate memory for Polly GPU device failed.\n");
+    exit(-1);
+  }
+  CuDeviceGetFcnPtr(&((*Device)->Cuda), 0);
+
+  /* Get compute capabilities and the device name. */
+  CuDeviceComputeCapabilityFcnPtr(&Major, &Minor, (*Device)->Cuda);
+  CuDeviceGetNameFcnPtr(DeviceName, 256, (*Device)->Cuda);
+  fprintf(stderr, "> Running on GPU device %d : %s.\n", DeviceID, DeviceName);
+
+  /* Create context on the device. */
+  *Context = malloc(sizeof(PollyGPUContext));
+  if (*Context == 0) {
+    fprintf(stdout, "Allocate memory for Polly GPU context failed.\n");
+    exit(-1);
+  }
+  CuCtxCreateFcnPtr(&((*Context)->Cuda), 0, (*Device)->Cuda);
+}
+
+void polly_getPTXModule(void *PTXBuffer, PollyGPUModule **Module) {
+  *Module = malloc(sizeof(PollyGPUModule));
+  if (*Module == 0) {
+    fprintf(stdout, "Allocate memory for Polly GPU module failed.\n");
+    exit(-1);
+  }
+
+  if (CuModuleLoadDataExFcnPtr(&((*Module)->Cuda), PTXBuffer, 0, 0, 0) !=
+          CUDA_SUCCESS) {
+    fprintf(stdout, "Loading ptx assembly text failed.\n");
+    exit(-1);
+  }
+}
+
+void polly_getPTXKernelEntry(const char *KernelName, PollyGPUModule *Module,
+                             PollyGPUFunction **Kernel) {
+  *Kernel = malloc(sizeof(PollyGPUFunction));
+  if (*Kernel == 0) {
+    fprintf(stdout, "Allocate memory for Polly GPU kernel failed.\n");
+    exit(-1);
+  }
+
+  /* Locate the kernel entry point. */
+  if (CuModuleGetFunctionFcnPtr(&((*Kernel)->Cuda), Module->Cuda, KernelName) !=
+          CUDA_SUCCESS) {
+    fprintf(stdout, "Loading kernel function failed.\n");
+    exit(-1);
+  }
+}
+
+void polly_startTimerByCudaEvent(PollyGPUEvent **Start, PollyGPUEvent **Stop) {
+  *Start = malloc(sizeof(PollyGPUEvent));
+  if (*Start == 0) {
+    fprintf(stdout, "Allocate memory for Polly GPU start timer failed.\n");
+    exit(-1);
+  }
+  CudaEventCreateFcnPtr(&((*Start)->Cuda));
+
+  *Stop = malloc(sizeof(PollyGPUEvent));
+  if (*Stop == 0) {
+    fprintf(stdout, "Allocate memory for Polly GPU stop timer failed.\n");
+    exit(-1);
+  }
+  CudaEventCreateFcnPtr(&((*Stop)->Cuda));
+
+  /* Record the start time. */
+  CudaEventRecordFcnPtr((*Start)->Cuda, 0);
+}
+
+void polly_stopTimerByCudaEvent(PollyGPUEvent *Start, PollyGPUEvent *Stop,
+                                float *ElapsedTimes) {
+  /* Record the end time. */
+  CudaEventRecordFcnPtr(Stop->Cuda, 0);
+  CudaEventSynchronizeFcnPtr(Start->Cuda);
+  CudaEventSynchronizeFcnPtr(Stop->Cuda);
+  CudaEventElapsedTimeFcnPtr(ElapsedTimes, Start->Cuda, Stop->Cuda);
+  CudaEventDestroyFcnPtr(Start->Cuda);
+  CudaEventDestroyFcnPtr(Stop->Cuda);
+  fprintf(stderr, "Processing time: %f (ms).\n", *ElapsedTimes);
+
+  free(Start);
+  free(Stop);
+}
+
+void polly_allocateMemoryForHostAndDevice(
+    void **HostData, PollyGPUDevicePtr **DevData, int MemSize) {
+  if ((*HostData = (int *)malloc(MemSize)) == 0) {
+    fprintf(stdout, "Could not allocate host memory.\n");
+    exit(-1);
+  }
+
+  *DevData = malloc(sizeof(PollyGPUDevicePtr));
+  if (*DevData == 0) {
+    fprintf(stdout, "Allocate memory for GPU device memory pointer failed.\n");
+    exit(-1);
+  }
+  CuMemAllocFcnPtr(&((*DevData)->Cuda), MemSize);
+}
+
+void polly_copyFromHostToDevice(PollyGPUDevicePtr *DevData, void *HostData,
+                                int MemSize) {
+  CUdeviceptr CuDevData = DevData->Cuda;
+  CuMemcpyHtoDFcnPtr(CuDevData, HostData, MemSize);
+}
+
+void polly_copyFromDeviceToHost(void *HostData, PollyGPUDevicePtr *DevData,
+                                int MemSize) {
+  if (CuMemcpyDtoHFcnPtr(HostData, DevData->Cuda, MemSize) != CUDA_SUCCESS) {
+    fprintf(stdout, "Copying results from device to host memory failed.\n");
+    exit(-1);
+  }
+}
+
+void polly_setKernelParameters(PollyGPUFunction *Kernel, int BlockWidth,
+                               int BlockHeight, PollyGPUDevicePtr *DevData) {
+  int ParamOffset = 0;
+
+  CuFuncSetBlockShapeFcnPtr(Kernel->Cuda, BlockWidth, BlockHeight, 1);
+  CuParamSetvFcnPtr(Kernel->Cuda, ParamOffset, &(DevData->Cuda),
+                    sizeof(DevData->Cuda));
+  ParamOffset += sizeof(DevData->Cuda);
+  CuParamSetSizeFcnPtr(Kernel->Cuda, ParamOffset);
+}
+
+void polly_launchKernel(PollyGPUFunction *Kernel, int GridWidth,
+                        int GridHeight) {
+  if (CuLaunchGridFcnPtr(Kernel->Cuda, GridWidth, GridHeight) != CUDA_SUCCESS) {
+    fprintf(stdout, "Launching CUDA kernel failed.\n");
+    exit(-1);
+  }
+  CudaThreadSynchronizeFcnPtr();
+  fprintf(stdout, "CUDA kernel launched.\n");
+}
+
+void polly_cleanupGPGPUResources(
+    void *HostData, PollyGPUDevicePtr *DevData, PollyGPUModule *Module,
+    PollyGPUContext *Context, PollyGPUFunction *Kernel) {
+  if (HostData) {
+    free(HostData);
+    HostData = 0;
+  }
+
+  if (DevData->Cuda) {
+    CuMemFreeFcnPtr(DevData->Cuda);
+    free(DevData);
+  }
+
+  if (Module->Cuda) {
+    CuModuleUnloadFcnPtr(Module->Cuda);
+    free(Module);
+  }
+
+  if (Context->Cuda) {
+    CuCtxDestroyFcnPtr(Context->Cuda);
+    free(Context);
+  }
+
+  if (Kernel) {
+    free(Kernel);
+  }
+
+  dlclose(HandleCuda);
+  dlclose(HandleCudaRT);
+}
diff --git a/rc1/tools/GPURuntime/GPUJIT.h b/rc1/tools/GPURuntime/GPUJIT.h
new file mode 100644
index 0000000..5ed41ce
--- /dev/null
+++ b/rc1/tools/GPURuntime/GPUJIT.h
@@ -0,0 +1,106 @@
+/******************************************************************************/
+/*                                                                            */
+/*                     The LLVM Compiler Infrastructure                       */
+/*                                                                            */
+/* This file is dual licensed under the MIT and the University of Illinois    */
+/* Open Source License. See LICENSE.TXT for details.                          */
+/*                                                                            */
+/******************************************************************************/
+/*                                                                            */
+/*  This file defines GPUJIT.                                                 */
+/*                                                                            */
+/******************************************************************************/
+
+#ifndef GPUJIT_H_
+#define GPUJIT_H_
+
+/*
+ * The following demostrates how we can use the GPURuntime library to
+ * execute a GPU kernel.
+ *
+ * char KernelString[] = "\n\
+ *   .version 1.4\n\
+ *   .target sm_10, map_f64_to_f32\n\
+ *   .entry _Z8myKernelPi (\n\
+ *   .param .u64 __cudaparm__Z8myKernelPi_data)\n\
+ *   {\n\
+ *     .reg .u16 %rh<4>;\n\
+ *     .reg .u32 %r<5>;\n\
+ *     .reg .u64 %rd<6>;\n\
+ *     cvt.u32.u16     %r1, %tid.x;\n\
+ *     mov.u16         %rh1, %ctaid.x;\n\
+ *     mov.u16         %rh2, %ntid.x;\n\
+ *     mul.wide.u16    %r2, %rh1, %rh2;\n\
+ *     add.u32         %r3, %r1, %r2;\n\
+ *     ld.param.u64    %rd1, [__cudaparm__Z8myKernelPi_data];\n\
+ *     cvt.s64.s32     %rd2, %r3;\n\
+ *     mul.wide.s32    %rd3, %r3, 4;\n\
+ *     add.u64         %rd4, %rd1, %rd3;\n\
+ *     st.global.s32   [%rd4+0], %r3;\n\
+ *     exit;\n\
+ *   }\n\
+ * ";
+ *
+ * const char *Entry = "_Z8myKernelPi";
+ *
+ * int main() {
+ *   PollyGPUContext *Context;
+ *   PollyGPUModule *Module;
+ *   PollyGPUFunction *Kernel;
+ *   PollyGPUDevice *Device;
+ *   PollyGPUDevicePtr *PtrDevData;
+ *   int *HostData;
+ *   PollyGPUEvent *Start;
+ *   PollyGPUEvent *Stop;
+ *   float *ElapsedTime;
+ *   int MemSize;
+ *   int BlockWidth = 16;
+ *   int BlockHeight = 16;
+ *   int GridWidth = 8;
+ *   int GridHeight = 8;
+ *
+ *   MemSize = 256*64*sizeof(int);
+ *   polly_initDevice(&Context, &Device);
+ *   polly_getPTXModule(KernelString, &Module);
+ *   polly_getPTXKernelEntry(Entry, Module, &Kernel);
+ *   polly_allocateMemoryForHostAndDevice(&HostData, &DevData, MemSize);
+ *   polly_setKernelParameters(Kernel, BlockWidth, BlockHeight, DevData);
+ *   polly_startTimerByCudaEvent(&Start, &Stop);
+ *   polly_launchKernel(Kernel, GridWidth, GridHeight);
+ *   polly_copyFromDeviceToHost(HostData, DevData, MemSize);
+ *   polly_stopTimerByCudaEvent(Start, Stop, ElapsedTime);
+ *   polly_cleanupGPGPUResources(HostData, DevData, Module, Context, Kernel);
+ * }
+ *
+ */
+
+typedef struct PollyGPUContextT PollyGPUContext;
+typedef struct PollyGPUModuleT PollyGPUModule;
+typedef struct PollyGPUFunctionT PollyGPUFunction;
+typedef struct PollyGPUDeviceT PollyGPUDevice;
+typedef struct PollyGPUDevicePtrT PollyGPUDevicePtr;
+typedef struct PollyGPUEventT PollyGPUEvent;
+
+void polly_initDevice(PollyGPUContext **Context, PollyGPUDevice **Device);
+void polly_getPTXModule(void *PTXBuffer, PollyGPUModule **Module);
+void polly_getPTXKernelEntry(const char *KernelName, PollyGPUModule *Module,
+                             PollyGPUFunction **Kernel);
+void polly_startTimerByCudaEvent(PollyGPUEvent **Start, PollyGPUEvent **Stop);
+void polly_stopTimerByCudaEvent(PollyGPUEvent *Start, PollyGPUEvent *Stop,
+                                float *ElapsedTimes);
+void polly_copyFromHostToDevice(PollyGPUDevicePtr *DevData, void *HostData,
+                                int MemSize);
+void polly_copyFromDeviceToHost(void *HostData, PollyGPUDevicePtr *DevData,
+                                int MemSize);
+void polly_allocateMemoryForHostAndDevice(void **HostData,
+                                          PollyGPUDevicePtr **DevData,
+                                          int MemSize);
+void polly_setKernelParameters(PollyGPUFunction *Kernel, int BlockWidth,
+                               int BlockHeight, PollyGPUDevicePtr *DevData);
+void polly_launchKernel(PollyGPUFunction *Kernel, int GridWidth,
+                        int GridHeight);
+void polly_cleanupGPGPUResources(void *HostData, PollyGPUDevicePtr *DevData,
+                                 PollyGPUModule *Module,
+                                 PollyGPUContext *Context,
+                                 PollyGPUFunction *Kernel);
+#endif /* GPUJIT_H_ */
diff --git a/rc1/tools/GPURuntime/LICENSE.TXT b/rc1/tools/GPURuntime/LICENSE.TXT
new file mode 100644
index 0000000..e2461ab
--- /dev/null
+++ b/rc1/tools/GPURuntime/LICENSE.TXT
@@ -0,0 +1,75 @@
+==============================================================================
+GPURuntime License
+==============================================================================
+
+The GPURuntime library is dual licensed under both the University of Illinois
+"BSD-Like" license and the MIT license.  As a user of this code you may choose
+to use it under either license.  As a contributor, you agree to allow your code
+to be used under both.
+
+Full text of the relevant licenses is included below.
+
+==============================================================================
+
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+
+All rights reserved.
+
+Developed by:
+
+    Polly Team
+
+    http://polly.llvm.org
+
+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 LLVM Team, University of Illinois at
+      Urbana-Champaign, 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.
+
+==============================================================================
+
+Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in 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:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+AUTHORS 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 IN
+THE SOFTWARE.
+
diff --git a/rc1/tools/GPURuntime/Makefile b/rc1/tools/GPURuntime/Makefile
new file mode 100644
index 0000000..4822f70
--- /dev/null
+++ b/rc1/tools/GPURuntime/Makefile
@@ -0,0 +1,16 @@
+##===- polly/lib/GPURuntime/Makefile -----------------------*- Makefile -*-===##
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+LIBRARYNAME = libGPURuntime
+LOADABLE_MODULE = 1
+
+include $(LEVEL)/Makefile.config
+CPP.Flags += $(POLLY_INC)
+include $(LEVEL)/Makefile.common
diff --git a/rc1/tools/Makefile b/rc1/tools/Makefile
new file mode 100644
index 0000000..21b6a42
--- /dev/null
+++ b/rc1/tools/Makefile
@@ -0,0 +1,20 @@
+##===- 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.config
+
+# GPU Runtime Support
+ifeq ($(CUDALIB_FOUND), yes)
+ DIRS += GPURuntime
+endif
+
+include $(LEVEL)/Makefile.common
diff --git a/rc1/utils/argparse.py b/rc1/utils/argparse.py
new file mode 100644
index 0000000..a060129
--- /dev/null
+++ b/rc1/utils/argparse.py
@@ -0,0 +1,2353 @@
+# -*- coding: utf-8 -*-
+
+# Copyright © 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy
+# of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""Command-line parsing library
+
+This module is an optparse-inspired command-line parsing library that:
+
+    - handles both optional and positional arguments
+    - produces highly informative usage messages
+    - supports parsers that dispatch to sub-parsers
+
+The following is a simple usage example that sums integers from the
+command-line and writes the result to a file::
+
+    parser = argparse.ArgumentParser(
+        description='sum the integers at the command line')
+    parser.add_argument(
+        'integers', metavar='int', nargs='+', type=int,
+        help='an integer to be summed')
+    parser.add_argument(
+        '--log', default=sys.stdout, type=argparse.FileType('w'),
+        help='the file where the sum should be written')
+    args = parser.parse_args()
+    args.log.write('%s' % sum(args.integers))
+    args.log.close()
+
+The module contains the following public classes:
+
+    - ArgumentParser -- The main entry point for command-line parsing. As the
+        example above shows, the add_argument() method is used to populate
+        the parser with actions for optional and positional arguments. Then
+        the parse_args() method is invoked to convert the args at the
+        command-line into an object with attributes.
+
+    - ArgumentError -- The exception raised by ArgumentParser objects when
+        there are errors with the parser's actions. Errors raised while
+        parsing the command-line are caught by ArgumentParser and emitted
+        as command-line messages.
+
+    - FileType -- A factory for defining types of files to be created. As the
+        example above shows, instances of FileType are typically passed as
+        the type= argument of add_argument() calls.
+
+    - Action -- The base class for parser actions. Typically actions are
+        selected by passing strings like 'store_true' or 'append_const' to
+        the action= argument of add_argument(). However, for greater
+        customization of ArgumentParser actions, subclasses of Action may
+        be defined and passed as the action= argument.
+
+    - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
+        ArgumentDefaultsHelpFormatter -- Formatter classes which
+        may be passed as the formatter_class= argument to the
+        ArgumentParser constructor. HelpFormatter is the default,
+        RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
+        not to change the formatting for help text, and
+        ArgumentDefaultsHelpFormatter adds information about argument defaults
+        to the help.
+
+All other classes in this module are considered implementation details.
+(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
+considered public as object names -- the API of the formatter objects is
+still considered an implementation detail.)
+"""
+
+__version__ = '1.1'
+__all__ = [
+    'ArgumentParser',
+    'ArgumentError',
+    'Namespace',
+    'Action',
+    'FileType',
+    'HelpFormatter',
+    'RawDescriptionHelpFormatter',
+    'RawTextHelpFormatter',
+    'ArgumentDefaultsHelpFormatter',
+]
+
+
+import copy as _copy
+import os as _os
+import re as _re
+import sys as _sys
+import textwrap as _textwrap
+
+from gettext import gettext as _
+
+try:
+    _set = set
+except NameError:
+    from sets import Set as _set
+
+try:
+    _basestring = basestring
+except NameError:
+    _basestring = str
+
+try:
+    _sorted = sorted
+except NameError:
+
+    def _sorted(iterable, reverse=False):
+        result = list(iterable)
+        result.sort()
+        if reverse:
+            result.reverse()
+        return result
+
+
+def _callable(obj):
+    return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
+
+# silence Python 2.6 buggy warnings about Exception.message
+if _sys.version_info[:2] == (2, 6):
+    import warnings
+    warnings.filterwarnings(
+        action='ignore',
+        message='BaseException.message has been deprecated as of Python 2.6',
+        category=DeprecationWarning,
+        module='argparse')
+
+
+SUPPRESS = '==SUPPRESS=='
+
+OPTIONAL = '?'
+ZERO_OR_MORE = '*'
+ONE_OR_MORE = '+'
+PARSER = 'A...'
+REMAINDER = '...'
+
+# =============================
+# Utility functions and classes
+# =============================
+
+class _AttributeHolder(object):
+    """Abstract base class that provides __repr__.
+
+    The __repr__ method returns a string in the format::
+        ClassName(attr=name, attr=name, ...)
+    The attributes are determined either by a class-level attribute,
+    '_kwarg_names', or by inspecting the instance __dict__.
+    """
+
+    def __repr__(self):
+        type_name = type(self).__name__
+        arg_strings = []
+        for arg in self._get_args():
+            arg_strings.append(repr(arg))
+        for name, value in self._get_kwargs():
+            arg_strings.append('%s=%r' % (name, value))
+        return '%s(%s)' % (type_name, ', '.join(arg_strings))
+
+    def _get_kwargs(self):
+        return _sorted(self.__dict__.items())
+
+    def _get_args(self):
+        return []
+
+
+def _ensure_value(namespace, name, value):
+    if getattr(namespace, name, None) is None:
+        setattr(namespace, name, value)
+    return getattr(namespace, name)
+
+
+# ===============
+# Formatting Help
+# ===============
+
+class HelpFormatter(object):
+    """Formatter for generating usage messages and argument help strings.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def __init__(self,
+                 prog,
+                 indent_increment=2,
+                 max_help_position=24,
+                 width=None):
+
+        # default setting for width
+        if width is None:
+            try:
+                width = int(_os.environ['COLUMNS'])
+            except (KeyError, ValueError):
+                width = 80
+            width -= 2
+
+        self._prog = prog
+        self._indent_increment = indent_increment
+        self._max_help_position = max_help_position
+        self._width = width
+
+        self._current_indent = 0
+        self._level = 0
+        self._action_max_length = 0
+
+        self._root_section = self._Section(self, None)
+        self._current_section = self._root_section
+
+        self._whitespace_matcher = _re.compile(r'\s+')
+        self._long_break_matcher = _re.compile(r'\n\n\n+')
+
+    # ===============================
+    # Section and indentation methods
+    # ===============================
+    def _indent(self):
+        self._current_indent += self._indent_increment
+        self._level += 1
+
+    def _dedent(self):
+        self._current_indent -= self._indent_increment
+        assert self._current_indent >= 0, 'Indent decreased below 0.'
+        self._level -= 1
+
+    class _Section(object):
+
+        def __init__(self, formatter, parent, heading=None):
+            self.formatter = formatter
+            self.parent = parent
+            self.heading = heading
+            self.items = []
+
+        def format_help(self):
+            # format the indented section
+            if self.parent is not None:
+                self.formatter._indent()
+            join = self.formatter._join_parts
+            for func, args in self.items:
+                func(*args)
+            item_help = join([func(*args) for func, args in self.items])
+            if self.parent is not None:
+                self.formatter._dedent()
+
+            # return nothing if the section was empty
+            if not item_help:
+                return ''
+
+            # add the heading if the section was non-empty
+            if self.heading is not SUPPRESS and self.heading is not None:
+                current_indent = self.formatter._current_indent
+                heading = '%*s%s:\n' % (current_indent, '', self.heading)
+            else:
+                heading = ''
+
+            # join the section-initial newline, the heading and the help
+            return join(['\n', heading, item_help, '\n'])
+
+    def _add_item(self, func, args):
+        self._current_section.items.append((func, args))
+
+    # ========================
+    # Message building methods
+    # ========================
+    def start_section(self, heading):
+        self._indent()
+        section = self._Section(self, self._current_section, heading)
+        self._add_item(section.format_help, [])
+        self._current_section = section
+
+    def end_section(self):
+        self._current_section = self._current_section.parent
+        self._dedent()
+
+    def add_text(self, text):
+        if text is not SUPPRESS and text is not None:
+            self._add_item(self._format_text, [text])
+
+    def add_usage(self, usage, actions, groups, prefix=None):
+        if usage is not SUPPRESS:
+            args = usage, actions, groups, prefix
+            self._add_item(self._format_usage, args)
+
+    def add_argument(self, action):
+        if action.help is not SUPPRESS:
+
+            # find all invocations
+            get_invocation = self._format_action_invocation
+            invocations = [get_invocation(action)]
+            for subaction in self._iter_indented_subactions(action):
+                invocations.append(get_invocation(subaction))
+
+            # update the maximum item length
+            invocation_length = max([len(s) for s in invocations])
+            action_length = invocation_length + self._current_indent
+            self._action_max_length = max(self._action_max_length,
+                                          action_length)
+
+            # add the item to the list
+            self._add_item(self._format_action, [action])
+
+    def add_arguments(self, actions):
+        for action in actions:
+            self.add_argument(action)
+
+    # =======================
+    # Help-formatting methods
+    # =======================
+    def format_help(self):
+        help = self._root_section.format_help()
+        if help:
+            help = self._long_break_matcher.sub('\n\n', help)
+            help = help.strip('\n') + '\n'
+        return help
+
+    def _join_parts(self, part_strings):
+        return ''.join([part
+                        for part in part_strings
+                        if part and part is not SUPPRESS])
+
+    def _format_usage(self, usage, actions, groups, prefix):
+        if prefix is None:
+            prefix = _('usage: ')
+
+        # if usage is specified, use that
+        if usage is not None:
+            usage = usage % dict(prog=self._prog)
+
+        # if no optionals or positionals are available, usage is just prog
+        elif usage is None and not actions:
+            usage = '%(prog)s' % dict(prog=self._prog)
+
+        # if optionals and positionals are available, calculate usage
+        elif usage is None:
+            prog = '%(prog)s' % dict(prog=self._prog)
+
+            # split optionals from positionals
+            optionals = []
+            positionals = []
+            for action in actions:
+                if action.option_strings:
+                    optionals.append(action)
+                else:
+                    positionals.append(action)
+
+            # build full usage string
+            format = self._format_actions_usage
+            action_usage = format(optionals + positionals, groups)
+            usage = ' '.join([s for s in [prog, action_usage] if s])
+
+            # wrap the usage parts if it's too long
+            text_width = self._width - self._current_indent
+            if len(prefix) + len(usage) > text_width:
+
+                # break usage into wrappable parts
+                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
+                opt_usage = format(optionals, groups)
+                pos_usage = format(positionals, groups)
+                opt_parts = _re.findall(part_regexp, opt_usage)
+                pos_parts = _re.findall(part_regexp, pos_usage)
+                assert ' '.join(opt_parts) == opt_usage
+                assert ' '.join(pos_parts) == pos_usage
+
+                # helper for wrapping lines
+                def get_lines(parts, indent, prefix=None):
+                    lines = []
+                    line = []
+                    if prefix is not None:
+                        line_len = len(prefix) - 1
+                    else:
+                        line_len = len(indent) - 1
+                    for part in parts:
+                        if line_len + 1 + len(part) > text_width:
+                            lines.append(indent + ' '.join(line))
+                            line = []
+                            line_len = len(indent) - 1
+                        line.append(part)
+                        line_len += len(part) + 1
+                    if line:
+                        lines.append(indent + ' '.join(line))
+                    if prefix is not None:
+                        lines[0] = lines[0][len(indent):]
+                    return lines
+
+                # if prog is short, follow it with optionals or positionals
+                if len(prefix) + len(prog) <= 0.75 * text_width:
+                    indent = ' ' * (len(prefix) + len(prog) + 1)
+                    if opt_parts:
+                        lines = get_lines([prog] + opt_parts, indent, prefix)
+                        lines.extend(get_lines(pos_parts, indent))
+                    elif pos_parts:
+                        lines = get_lines([prog] + pos_parts, indent, prefix)
+                    else:
+                        lines = [prog]
+
+                # if prog is long, put it on its own line
+                else:
+                    indent = ' ' * len(prefix)
+                    parts = opt_parts + pos_parts
+                    lines = get_lines(parts, indent)
+                    if len(lines) > 1:
+                        lines = []
+                        lines.extend(get_lines(opt_parts, indent))
+                        lines.extend(get_lines(pos_parts, indent))
+                    lines = [prog] + lines
+
+                # join lines into usage
+                usage = '\n'.join(lines)
+
+        # prefix with 'usage:'
+        return '%s%s\n\n' % (prefix, usage)
+
+    def _format_actions_usage(self, actions, groups):
+        # find group indices and identify actions in groups
+        group_actions = _set()
+        inserts = {}
+        for group in groups:
+            try:
+                start = actions.index(group._group_actions[0])
+            except ValueError:
+                continue
+            else:
+                end = start + len(group._group_actions)
+                if actions[start:end] == group._group_actions:
+                    for action in group._group_actions:
+                        group_actions.add(action)
+                    if not group.required:
+                        inserts[start] = '['
+                        inserts[end] = ']'
+                    else:
+                        inserts[start] = '('
+                        inserts[end] = ')'
+                    for i in range(start + 1, end):
+                        inserts[i] = '|'
+
+        # collect all actions format strings
+        parts = []
+        for i, action in enumerate(actions):
+
+            # suppressed arguments are marked with None
+            # remove | separators for suppressed arguments
+            if action.help is SUPPRESS:
+                parts.append(None)
+                if inserts.get(i) == '|':
+                    inserts.pop(i)
+                elif inserts.get(i + 1) == '|':
+                    inserts.pop(i + 1)
+
+            # produce all arg strings
+            elif not action.option_strings:
+                part = self._format_args(action, action.dest)
+
+                # if it's in a group, strip the outer []
+                if action in group_actions:
+                    if part[0] == '[' and part[-1] == ']':
+                        part = part[1:-1]
+
+                # add the action string to the list
+                parts.append(part)
+
+            # produce the first way to invoke the option in brackets
+            else:
+                option_string = action.option_strings[0]
+
+                # if the Optional doesn't take a value, format is:
+                #    -s or --long
+                if action.nargs == 0:
+                    part = '%s' % option_string
+
+                # if the Optional takes a value, format is:
+                #    -s ARGS or --long ARGS
+                else:
+                    default = action.dest.upper()
+                    args_string = self._format_args(action, default)
+                    part = '%s %s' % (option_string, args_string)
+
+                # make it look optional if it's not required or in a group
+                if not action.required and action not in group_actions:
+                    part = '[%s]' % part
+
+                # add the action string to the list
+                parts.append(part)
+
+        # insert things at the necessary indices
+        for i in _sorted(inserts, reverse=True):
+            parts[i:i] = [inserts[i]]
+
+        # join all the action items with spaces
+        text = ' '.join([item for item in parts if item is not None])
+
+        # clean up separators for mutually exclusive groups
+        open = r'[\[(]'
+        close = r'[\])]'
+        text = _re.sub(r'(%s) ' % open, r'\1', text)
+        text = _re.sub(r' (%s)' % close, r'\1', text)
+        text = _re.sub(r'%s *%s' % (open, close), r'', text)
+        text = _re.sub(r'\(([^|]*)\)', r'\1', text)
+        text = text.strip()
+
+        # return the text
+        return text
+
+    def _format_text(self, text):
+        if '%(prog)' in text:
+            text = text % dict(prog=self._prog)
+        text_width = self._width - self._current_indent
+        indent = ' ' * self._current_indent
+        return self._fill_text(text, text_width, indent) + '\n\n'
+
+    def _format_action(self, action):
+        # determine the required width and the entry label
+        help_position = min(self._action_max_length + 2,
+                            self._max_help_position)
+        help_width = self._width - help_position
+        action_width = help_position - self._current_indent - 2
+        action_header = self._format_action_invocation(action)
+
+        # ho nelp; start on same line and add a final newline
+        if not action.help:
+            tup = self._current_indent, '', action_header
+            action_header = '%*s%s\n' % tup
+
+        # short action name; start on the same line and pad two spaces
+        elif len(action_header) <= action_width:
+            tup = self._current_indent, '', action_width, action_header
+            action_header = '%*s%-*s  ' % tup
+            indent_first = 0
+
+        # long action name; start on the next line
+        else:
+            tup = self._current_indent, '', action_header
+            action_header = '%*s%s\n' % tup
+            indent_first = help_position
+
+        # collect the pieces of the action help
+        parts = [action_header]
+
+        # if there was help for the action, add lines of help text
+        if action.help:
+            help_text = self._expand_help(action)
+            help_lines = self._split_lines(help_text, help_width)
+            parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
+            for line in help_lines[1:]:
+                parts.append('%*s%s\n' % (help_position, '', line))
+
+        # or add a newline if the description doesn't end with one
+        elif not action_header.endswith('\n'):
+            parts.append('\n')
+
+        # if there are any sub-actions, add their help as well
+        for subaction in self._iter_indented_subactions(action):
+            parts.append(self._format_action(subaction))
+
+        # return a single string
+        return self._join_parts(parts)
+
+    def _format_action_invocation(self, action):
+        if not action.option_strings:
+            metavar, = self._metavar_formatter(action, action.dest)(1)
+            return metavar
+
+        else:
+            parts = []
+
+            # if the Optional doesn't take a value, format is:
+            #    -s, --long
+            if action.nargs == 0:
+                parts.extend(action.option_strings)
+
+            # if the Optional takes a value, format is:
+            #    -s ARGS, --long ARGS
+            else:
+                default = action.dest.upper()
+                args_string = self._format_args(action, default)
+                for option_string in action.option_strings:
+                    parts.append('%s %s' % (option_string, args_string))
+
+            return ', '.join(parts)
+
+    def _metavar_formatter(self, action, default_metavar):
+        if action.metavar is not None:
+            result = action.metavar
+        elif action.choices is not None:
+            choice_strs = [str(choice) for choice in action.choices]
+            result = '{%s}' % ','.join(choice_strs)
+        else:
+            result = default_metavar
+
+        def format(tuple_size):
+            if isinstance(result, tuple):
+                return result
+            else:
+                return (result, ) * tuple_size
+        return format
+
+    def _format_args(self, action, default_metavar):
+        get_metavar = self._metavar_formatter(action, default_metavar)
+        if action.nargs is None:
+            result = '%s' % get_metavar(1)
+        elif action.nargs == OPTIONAL:
+            result = '[%s]' % get_metavar(1)
+        elif action.nargs == ZERO_OR_MORE:
+            result = '[%s [%s ...]]' % get_metavar(2)
+        elif action.nargs == ONE_OR_MORE:
+            result = '%s [%s ...]' % get_metavar(2)
+        elif action.nargs == REMAINDER:
+            result = '...'
+        elif action.nargs == PARSER:
+            result = '%s ...' % get_metavar(1)
+        else:
+            formats = ['%s' for _ in range(action.nargs)]
+            result = ' '.join(formats) % get_metavar(action.nargs)
+        return result
+
+    def _expand_help(self, action):
+        params = dict(vars(action), prog=self._prog)
+        for name in list(params):
+            if params[name] is SUPPRESS:
+                del params[name]
+        for name in list(params):
+            if hasattr(params[name], '__name__'):
+                params[name] = params[name].__name__
+        if params.get('choices') is not None:
+            choices_str = ', '.join([str(c) for c in params['choices']])
+            params['choices'] = choices_str
+        return self._get_help_string(action) % params
+
+    def _iter_indented_subactions(self, action):
+        try:
+            get_subactions = action._get_subactions
+        except AttributeError:
+            pass
+        else:
+            self._indent()
+            for subaction in get_subactions():
+                yield subaction
+            self._dedent()
+
+    def _split_lines(self, text, width):
+        text = self._whitespace_matcher.sub(' ', text).strip()
+        return _textwrap.wrap(text, width)
+
+    def _fill_text(self, text, width, indent):
+        text = self._whitespace_matcher.sub(' ', text).strip()
+        return _textwrap.fill(text, width, initial_indent=indent,
+                                           subsequent_indent=indent)
+
+    def _get_help_string(self, action):
+        return action.help
+
+
+class RawDescriptionHelpFormatter(HelpFormatter):
+    """Help message formatter which retains any formatting in descriptions.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _fill_text(self, text, width, indent):
+        return ''.join([indent + line for line in text.splitlines(True)])
+
+
+class RawTextHelpFormatter(RawDescriptionHelpFormatter):
+    """Help message formatter which retains formatting of all help text.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _split_lines(self, text, width):
+        return text.splitlines()
+
+
+class ArgumentDefaultsHelpFormatter(HelpFormatter):
+    """Help message formatter which adds default values to argument help.
+
+    Only the name of this class is considered a public API. All the methods
+    provided by the class are considered an implementation detail.
+    """
+
+    def _get_help_string(self, action):
+        help = action.help
+        if '%(default)' not in action.help:
+            if action.default is not SUPPRESS:
+                defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
+                if action.option_strings or action.nargs in defaulting_nargs:
+                    help += ' (default: %(default)s)'
+        return help
+
+
+# =====================
+# Options and Arguments
+# =====================
+
+def _get_action_name(argument):
+    if argument is None:
+        return None
+    elif argument.option_strings:
+        return  '/'.join(argument.option_strings)
+    elif argument.metavar not in (None, SUPPRESS):
+        return argument.metavar
+    elif argument.dest not in (None, SUPPRESS):
+        return argument.dest
+    else:
+        return None
+
+
+class ArgumentError(Exception):
+    """An error from creating or using an argument (optional or positional).
+
+    The string value of this exception is the message, augmented with
+    information about the argument that caused it.
+    """
+
+    def __init__(self, argument, message):
+        self.argument_name = _get_action_name(argument)
+        self.message = message
+
+    def __str__(self):
+        if self.argument_name is None:
+            format = '%(message)s'
+        else:
+            format = 'argument %(argument_name)s: %(message)s'
+        return format % dict(message=self.message,
+                             argument_name=self.argument_name)
+
+
+class ArgumentTypeError(Exception):
+    """An error from trying to convert a command line string to a type."""
+    pass
+
+
+# ==============
+# Action classes
+# ==============
+
+class Action(_AttributeHolder):
+    """Information about how to convert command line strings to Python objects.
+
+    Action objects are used by an ArgumentParser to represent the information
+    needed to parse a single argument from one or more strings from the
+    command line. The keyword arguments to the Action constructor are also
+    all attributes of Action instances.
+
+    Keyword Arguments:
+
+        - option_strings -- A list of command-line option strings which
+            should be associated with this action.
+
+        - dest -- The name of the attribute to hold the created object(s)
+
+        - nargs -- The number of command-line arguments that should be
+            consumed. By default, one argument will be consumed and a single
+            value will be produced.  Other values include:
+                - N (an integer) consumes N arguments (and produces a list)
+                - '?' consumes zero or one arguments
+                - '*' consumes zero or more arguments (and produces a list)
+                - '+' consumes one or more arguments (and produces a list)
+            Note that the difference between the default and nargs=1 is that
+            with the default, a single value will be produced, while with
+            nargs=1, a list containing a single value will be produced.
+
+        - const -- The value to be produced if the option is specified and the
+            option uses an action that takes no values.
+
+        - default -- The value to be produced if the option is not specified.
+
+        - type -- The type which the command-line arguments should be converted
+            to, should be one of 'string', 'int', 'float', 'complex' or a
+            callable object that accepts a single string argument. If None,
+            'string' is assumed.
+
+        - choices -- A container of values that should be allowed. If not None,
+            after a command-line argument has been converted to the appropriate
+            type, an exception will be raised if it is not a member of this
+            collection.
+
+        - required -- True if the action must always be specified at the
+            command line. This is only meaningful for optional command-line
+            arguments.
+
+        - help -- The help string describing the argument.
+
+        - metavar -- The name to be used for the option's argument with the
+            help string. If None, the 'dest' value will be used as the name.
+    """
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        self.option_strings = option_strings
+        self.dest = dest
+        self.nargs = nargs
+        self.const = const
+        self.default = default
+        self.type = type
+        self.choices = choices
+        self.required = required
+        self.help = help
+        self.metavar = metavar
+
+    def _get_kwargs(self):
+        names = [
+            'option_strings',
+            'dest',
+            'nargs',
+            'const',
+            'default',
+            'type',
+            'choices',
+            'help',
+            'metavar',
+        ]
+        return [(name, getattr(self, name)) for name in names]
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        raise NotImplementedError(_('.__call__() not defined'))
+
+
+class _StoreAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        if nargs == 0:
+            raise ValueError('nargs for store actions must be > 0; if you '
+                             'have nothing to store, actions such as store '
+                             'true or store const may be more appropriate')
+        if const is not None and nargs != OPTIONAL:
+            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+        super(_StoreAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=nargs,
+            const=const,
+            default=default,
+            type=type,
+            choices=choices,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        setattr(namespace, self.dest, values)
+
+
+class _StoreConstAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 const,
+                 default=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        super(_StoreConstAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            const=const,
+            default=default,
+            required=required,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        setattr(namespace, self.dest, self.const)
+
+
+class _StoreTrueAction(_StoreConstAction):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=False,
+                 required=False,
+                 help=None):
+        super(_StoreTrueAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            const=True,
+            default=default,
+            required=required,
+            help=help)
+
+
+class _StoreFalseAction(_StoreConstAction):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=True,
+                 required=False,
+                 help=None):
+        super(_StoreFalseAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            const=False,
+            default=default,
+            required=required,
+            help=help)
+
+
+class _AppendAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 nargs=None,
+                 const=None,
+                 default=None,
+                 type=None,
+                 choices=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        if nargs == 0:
+            raise ValueError('nargs for append actions must be > 0; if arg '
+                             'strings are not supplying the value to append, '
+                             'the append const action may be more appropriate')
+        if const is not None and nargs != OPTIONAL:
+            raise ValueError('nargs must be %r to supply const' % OPTIONAL)
+        super(_AppendAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=nargs,
+            const=const,
+            default=default,
+            type=type,
+            choices=choices,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+        items.append(values)
+        setattr(namespace, self.dest, items)
+
+
+class _AppendConstAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 const,
+                 default=None,
+                 required=False,
+                 help=None,
+                 metavar=None):
+        super(_AppendConstAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            const=const,
+            default=default,
+            required=required,
+            help=help,
+            metavar=metavar)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        items = _copy.copy(_ensure_value(namespace, self.dest, []))
+        items.append(self.const)
+        setattr(namespace, self.dest, items)
+
+
+class _CountAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest,
+                 default=None,
+                 required=False,
+                 help=None):
+        super(_CountAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=0,
+            default=default,
+            required=required,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        new_count = _ensure_value(namespace, self.dest, 0) + 1
+        setattr(namespace, self.dest, new_count)
+
+
+class _HelpAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 dest=SUPPRESS,
+                 default=SUPPRESS,
+                 help=None):
+        super(_HelpAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            default=default,
+            nargs=0,
+            help=help)
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser.print_help()
+        parser.exit()
+
+
+class _VersionAction(Action):
+
+    def __init__(self,
+                 option_strings,
+                 version=None,
+                 dest=SUPPRESS,
+                 default=SUPPRESS,
+                 help=None):
+        super(_VersionAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            default=default,
+            nargs=0,
+            help=help)
+        self.version = version
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        version = self.version
+        if version is None:
+            version = parser.version
+        formatter = parser._get_formatter()
+        formatter.add_text(version)
+        parser.exit(message=formatter.format_help())
+
+
+class _SubParsersAction(Action):
+
+    class _ChoicesPseudoAction(Action):
+
+        def __init__(self, name, help):
+            sup = super(_SubParsersAction._ChoicesPseudoAction, self)
+            sup.__init__(option_strings=[], dest=name, help=help)
+
+    def __init__(self,
+                 option_strings,
+                 prog,
+                 parser_class,
+                 dest=SUPPRESS,
+                 help=None,
+                 metavar=None):
+
+        self._prog_prefix = prog
+        self._parser_class = parser_class
+        self._name_parser_map = {}
+        self._choices_actions = []
+
+        super(_SubParsersAction, self).__init__(
+            option_strings=option_strings,
+            dest=dest,
+            nargs=PARSER,
+            choices=self._name_parser_map,
+            help=help,
+            metavar=metavar)
+
+    def add_parser(self, name, **kwargs):
+        # set prog from the existing prefix
+        if kwargs.get('prog') is None:
+            kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
+
+        # create a pseudo-action to hold the choice help
+        if 'help' in kwargs:
+            help = kwargs.pop('help')
+            choice_action = self._ChoicesPseudoAction(name, help)
+            self._choices_actions.append(choice_action)
+
+        # create the parser and add it to the map
+        parser = self._parser_class(**kwargs)
+        self._name_parser_map[name] = parser
+        return parser
+
+    def _get_subactions(self):
+        return self._choices_actions
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        parser_name = values[0]
+        arg_strings = values[1:]
+
+        # set the parser name if requested
+        if self.dest is not SUPPRESS:
+            setattr(namespace, self.dest, parser_name)
+
+        # select the parser
+        try:
+            parser = self._name_parser_map[parser_name]
+        except KeyError:
+            tup = parser_name, ', '.join(self._name_parser_map)
+            msg = _('unknown parser %r (choices: %s)' % tup)
+            raise ArgumentError(self, msg)
+
+        # parse all the remaining options into the namespace
+        parser.parse_args(arg_strings, namespace)
+
+
+# ==============
+# Type classes
+# ==============
+
+class FileType(object):
+    """Factory for creating file object types
+
+    Instances of FileType are typically passed as type= arguments to the
+    ArgumentParser add_argument() method.
+
+    Keyword Arguments:
+        - mode -- A string indicating how the file is to be opened. Accepts the
+            same values as the builtin open() function.
+        - bufsize -- The file's desired buffer size. Accepts the same values as
+            the builtin open() function.
+    """
+
+    def __init__(self, mode='r', bufsize=None):
+        self._mode = mode
+        self._bufsize = bufsize
+
+    def __call__(self, string):
+        # the special argument "-" means sys.std{in,out}
+        if string == '-':
+            if 'r' in self._mode:
+                return _sys.stdin
+            elif 'w' in self._mode:
+                return _sys.stdout
+            else:
+                msg = _('argument "-" with mode %r' % self._mode)
+                raise ValueError(msg)
+
+        # all other arguments are used as file names
+        if self._bufsize:
+            return open(string, self._mode, self._bufsize)
+        else:
+            return open(string, self._mode)
+
+    def __repr__(self):
+        args = [self._mode, self._bufsize]
+        args_str = ', '.join([repr(arg) for arg in args if arg is not None])
+        return '%s(%s)' % (type(self).__name__, args_str)
+
+# ===========================
+# Optional and Positional Parsing
+# ===========================
+
+class Namespace(_AttributeHolder):
+    """Simple object for storing attributes.
+
+    Implements equality by attribute names and values, and provides a simple
+    string representation.
+    """
+
+    def __init__(self, **kwargs):
+        for name in kwargs:
+            setattr(self, name, kwargs[name])
+
+    def __eq__(self, other):
+        return vars(self) == vars(other)
+
+    def __ne__(self, other):
+        return not (self == other)
+
+    def __contains__(self, key):
+        return key in self.__dict__
+
+
+class _ActionsContainer(object):
+
+    def __init__(self,
+                 description,
+                 prefix_chars,
+                 argument_default,
+                 conflict_handler):
+        super(_ActionsContainer, self).__init__()
+
+        self.description = description
+        self.argument_default = argument_default
+        self.prefix_chars = prefix_chars
+        self.conflict_handler = conflict_handler
+
+        # set up registries
+        self._registries = {}
+
+        # register actions
+        self.register('action', None, _StoreAction)
+        self.register('action', 'store', _StoreAction)
+        self.register('action', 'store_const', _StoreConstAction)
+        self.register('action', 'store_true', _StoreTrueAction)
+        self.register('action', 'store_false', _StoreFalseAction)
+        self.register('action', 'append', _AppendAction)
+        self.register('action', 'append_const', _AppendConstAction)
+        self.register('action', 'count', _CountAction)
+        self.register('action', 'help', _HelpAction)
+        self.register('action', 'version', _VersionAction)
+        self.register('action', 'parsers', _SubParsersAction)
+
+        # raise an exception if the conflict handler is invalid
+        self._get_handler()
+
+        # action storage
+        self._actions = []
+        self._option_string_actions = {}
+
+        # groups
+        self._action_groups = []
+        self._mutually_exclusive_groups = []
+
+        # defaults storage
+        self._defaults = {}
+
+        # determines whether an "option" looks like a negative number
+        self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
+
+        # whether or not there are any optionals that look like negative
+        # numbers -- uses a list so it can be shared and edited
+        self._has_negative_number_optionals = []
+
+    # ====================
+    # Registration methods
+    # ====================
+    def register(self, registry_name, value, object):
+        registry = self._registries.setdefault(registry_name, {})
+        registry[value] = object
+
+    def _registry_get(self, registry_name, value, default=None):
+        return self._registries[registry_name].get(value, default)
+
+    # ==================================
+    # Namespace default accessor methods
+    # ==================================
+    def set_defaults(self, **kwargs):
+        self._defaults.update(kwargs)
+
+        # if these defaults match any existing arguments, replace
+        # the previous default on the object with the new one
+        for action in self._actions:
+            if action.dest in kwargs:
+                action.default = kwargs[action.dest]
+
+    def get_default(self, dest):
+        for action in self._actions:
+            if action.dest == dest and action.default is not None:
+                return action.default
+        return self._defaults.get(dest, None)
+
+
+    # =======================
+    # Adding argument actions
+    # =======================
+    def add_argument(self, *args, **kwargs):
+        """
+        add_argument(dest, ..., name=value, ...)
+        add_argument(option_string, option_string, ..., name=value, ...)
+        """
+
+        # if no positional args are supplied or only one is supplied and
+        # it doesn't look like an option string, parse a positional
+        # argument
+        chars = self.prefix_chars
+        if not args or len(args) == 1 and args[0][0] not in chars:
+            if args and 'dest' in kwargs:
+                raise ValueError('dest supplied twice for positional argument')
+            kwargs = self._get_positional_kwargs(*args, **kwargs)
+
+        # otherwise, we're adding an optional argument
+        else:
+            kwargs = self._get_optional_kwargs(*args, **kwargs)
+
+        # if no default was supplied, use the parser-level default
+        if 'default' not in kwargs:
+            dest = kwargs['dest']
+            if dest in self._defaults:
+                kwargs['default'] = self._defaults[dest]
+            elif self.argument_default is not None:
+                kwargs['default'] = self.argument_default
+
+        # create the action object, and add it to the parser
+        action_class = self._pop_action_class(kwargs)
+        if not _callable(action_class):
+            raise ValueError('unknown action "%s"' % action_class)
+        action = action_class(**kwargs)
+
+        # raise an error if the action type is not callable
+        type_func = self._registry_get('type', action.type, action.type)
+        if not _callable(type_func):
+            raise ValueError('%r is not callable' % type_func)
+
+        return self._add_action(action)
+
+    def add_argument_group(self, *args, **kwargs):
+        group = _ArgumentGroup(self, *args, **kwargs)
+        self._action_groups.append(group)
+        return group
+
+    def add_mutually_exclusive_group(self, **kwargs):
+        group = _MutuallyExclusiveGroup(self, **kwargs)
+        self._mutually_exclusive_groups.append(group)
+        return group
+
+    def _add_action(self, action):
+        # resolve any conflicts
+        self._check_conflict(action)
+
+        # add to actions list
+        self._actions.append(action)
+        action.container = self
+
+        # index the action by any option strings it has
+        for option_string in action.option_strings:
+            self._option_string_actions[option_string] = action
+
+        # set the flag if any option strings look like negative numbers
+        for option_string in action.option_strings:
+            if self._negative_number_matcher.match(option_string):
+                if not self._has_negative_number_optionals:
+                    self._has_negative_number_optionals.append(True)
+
+        # return the created action
+        return action
+
+    def _remove_action(self, action):
+        self._actions.remove(action)
+
+    def _add_container_actions(self, container):
+        # collect groups by titles
+        title_group_map = {}
+        for group in self._action_groups:
+            if group.title in title_group_map:
+                msg = _('cannot merge actions - two groups are named %r')
+                raise ValueError(msg % (group.title))
+            title_group_map[group.title] = group
+
+        # map each action to its group
+        group_map = {}
+        for group in container._action_groups:
+
+            # if a group with the title exists, use that, otherwise
+            # create a new group matching the container's group
+            if group.title not in title_group_map:
+                title_group_map[group.title] = self.add_argument_group(
+                    title=group.title,
+                    description=group.description,
+                    conflict_handler=group.conflict_handler)
+
+            # map the actions to their new group
+            for action in group._group_actions:
+                group_map[action] = title_group_map[group.title]
+
+        # add container's mutually exclusive groups
+        # NOTE: if add_mutually_exclusive_group ever gains title= and
+        # description= then this code will need to be expanded as above
+        for group in container._mutually_exclusive_groups:
+            mutex_group = self.add_mutually_exclusive_group(
+                required=group.required)
+
+            # map the actions to their new mutex group
+            for action in group._group_actions:
+                group_map[action] = mutex_group
+
+        # add all actions to this container or their group
+        for action in container._actions:
+            group_map.get(action, self)._add_action(action)
+
+    def _get_positional_kwargs(self, dest, **kwargs):
+        # make sure required is not specified
+        if 'required' in kwargs:
+            msg = _("'required' is an invalid argument for positionals")
+            raise TypeError(msg)
+
+        # mark positional arguments as required if at least one is
+        # always required
+        if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
+            kwargs['required'] = True
+        if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
+            kwargs['required'] = True
+
+        # return the keyword arguments with no option strings
+        return dict(kwargs, dest=dest, option_strings=[])
+
+    def _get_optional_kwargs(self, *args, **kwargs):
+        # determine short and long option strings
+        option_strings = []
+        long_option_strings = []
+        for option_string in args:
+            # error on strings that don't start with an appropriate prefix
+            if not option_string[0] in self.prefix_chars:
+                msg = _('invalid option string %r: '
+                        'must start with a character %r')
+                tup = option_string, self.prefix_chars
+                raise ValueError(msg % tup)
+
+            # strings starting with two prefix characters are long options
+            option_strings.append(option_string)
+            if option_string[0] in self.prefix_chars:
+                if len(option_string) > 1:
+                    if option_string[1] in self.prefix_chars:
+                        long_option_strings.append(option_string)
+
+        # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
+        dest = kwargs.pop('dest', None)
+        if dest is None:
+            if long_option_strings:
+                dest_option_string = long_option_strings[0]
+            else:
+                dest_option_string = option_strings[0]
+            dest = dest_option_string.lstrip(self.prefix_chars)
+            if not dest:
+                msg = _('dest= is required for options like %r')
+                raise ValueError(msg % option_string)
+            dest = dest.replace('-', '_')
+
+        # return the updated keyword arguments
+        return dict(kwargs, dest=dest, option_strings=option_strings)
+
+    def _pop_action_class(self, kwargs, default=None):
+        action = kwargs.pop('action', default)
+        return self._registry_get('action', action, action)
+
+    def _get_handler(self):
+        # determine function from conflict handler string
+        handler_func_name = '_handle_conflict_%s' % self.conflict_handler
+        try:
+            return getattr(self, handler_func_name)
+        except AttributeError:
+            msg = _('invalid conflict_resolution value: %r')
+            raise ValueError(msg % self.conflict_handler)
+
+    def _check_conflict(self, action):
+
+        # find all options that conflict with this option
+        confl_optionals = []
+        for option_string in action.option_strings:
+            if option_string in self._option_string_actions:
+                confl_optional = self._option_string_actions[option_string]
+                confl_optionals.append((option_string, confl_optional))
+
+        # resolve any conflicts
+        if confl_optionals:
+            conflict_handler = self._get_handler()
+            conflict_handler(action, confl_optionals)
+
+    def _handle_conflict_error(self, action, conflicting_actions):
+        message = _('conflicting option string(s): %s')
+        conflict_string = ', '.join([option_string
+                                     for option_string, action
+                                     in conflicting_actions])
+        raise ArgumentError(action, message % conflict_string)
+
+    def _handle_conflict_resolve(self, action, conflicting_actions):
+
+        # remove all conflicting options
+        for option_string, action in conflicting_actions:
+
+            # remove the conflicting option
+            action.option_strings.remove(option_string)
+            self._option_string_actions.pop(option_string, None)
+
+            # if the option now has no option string, remove it from the
+            # container holding it
+            if not action.option_strings:
+                action.container._remove_action(action)
+
+
+class _ArgumentGroup(_ActionsContainer):
+
+    def __init__(self, container, title=None, description=None, **kwargs):
+        # add any missing keyword arguments by checking the container
+        update = kwargs.setdefault
+        update('conflict_handler', container.conflict_handler)
+        update('prefix_chars', container.prefix_chars)
+        update('argument_default', container.argument_default)
+        super_init = super(_ArgumentGroup, self).__init__
+        super_init(description=description, **kwargs)
+
+        # group attributes
+        self.title = title
+        self._group_actions = []
+
+        # share most attributes with the container
+        self._registries = container._registries
+        self._actions = container._actions
+        self._option_string_actions = container._option_string_actions
+        self._defaults = container._defaults
+        self._has_negative_number_optionals = \
+            container._has_negative_number_optionals
+
+    def _add_action(self, action):
+        action = super(_ArgumentGroup, self)._add_action(action)
+        self._group_actions.append(action)
+        return action
+
+    def _remove_action(self, action):
+        super(_ArgumentGroup, self)._remove_action(action)
+        self._group_actions.remove(action)
+
+
+class _MutuallyExclusiveGroup(_ArgumentGroup):
+
+    def __init__(self, container, required=False):
+        super(_MutuallyExclusiveGroup, self).__init__(container)
+        self.required = required
+        self._container = container
+
+    def _add_action(self, action):
+        if action.required:
+            msg = _('mutually exclusive arguments must be optional')
+            raise ValueError(msg)
+        action = self._container._add_action(action)
+        self._group_actions.append(action)
+        return action
+
+    def _remove_action(self, action):
+        self._container._remove_action(action)
+        self._group_actions.remove(action)
+
+
+class ArgumentParser(_AttributeHolder, _ActionsContainer):
+    """Object for parsing command line strings into Python objects.
+
+    Keyword Arguments:
+        - prog -- The name of the program (default: sys.argv[0])
+        - usage -- A usage message (default: auto-generated from arguments)
+        - description -- A description of what the program does
+        - epilog -- Text following the argument descriptions
+        - parents -- Parsers whose arguments should be copied into this one
+        - formatter_class -- HelpFormatter class for printing help messages
+        - prefix_chars -- Characters that prefix optional arguments
+        - fromfile_prefix_chars -- Characters that prefix files containing
+            additional arguments
+        - argument_default -- The default value for all arguments
+        - conflict_handler -- String indicating how to handle conflicts
+        - add_help -- Add a -h/-help option
+    """
+
+    def __init__(self,
+                 prog=None,
+                 usage=None,
+                 description=None,
+                 epilog=None,
+                 version=None,
+                 parents=[],
+                 formatter_class=HelpFormatter,
+                 prefix_chars='-',
+                 fromfile_prefix_chars=None,
+                 argument_default=None,
+                 conflict_handler='error',
+                 add_help=True):
+
+        if version is not None:
+            import warnings
+            warnings.warn(
+                """The "version" argument to ArgumentParser is deprecated. """
+                """Please use """
+                """"add_argument(..., action='version', version="N", ...)" """
+                """instead""", DeprecationWarning)
+
+        superinit = super(ArgumentParser, self).__init__
+        superinit(description=description,
+                  prefix_chars=prefix_chars,
+                  argument_default=argument_default,
+                  conflict_handler=conflict_handler)
+
+        # default setting for prog
+        if prog is None:
+            prog = _os.path.basename(_sys.argv[0])
+
+        self.prog = prog
+        self.usage = usage
+        self.epilog = epilog
+        self.version = version
+        self.formatter_class = formatter_class
+        self.fromfile_prefix_chars = fromfile_prefix_chars
+        self.add_help = add_help
+
+        add_group = self.add_argument_group
+        self._positionals = add_group(_('positional arguments'))
+        self._optionals = add_group(_('optional arguments'))
+        self._subparsers = None
+
+        # register types
+        def identity(string):
+            return string
+        self.register('type', None, identity)
+
+        # add help and version arguments if necessary
+        # (using explicit default to override global argument_default)
+        if self.add_help:
+            self.add_argument(
+                '-h', '--help', action='help', default=SUPPRESS,
+                help=_('show this help message and exit'))
+        if self.version:
+            self.add_argument(
+                '-v', '--version', action='version', default=SUPPRESS,
+                version=self.version,
+                help=_("show program's version number and exit"))
+
+        # add parent arguments and defaults
+        for parent in parents:
+            self._add_container_actions(parent)
+            try:
+                defaults = parent._defaults
+            except AttributeError:
+                pass
+            else:
+                self._defaults.update(defaults)
+
+    # =======================
+    # Pretty __repr__ methods
+    # =======================
+    def _get_kwargs(self):
+        names = [
+            'prog',
+            'usage',
+            'description',
+            'version',
+            'formatter_class',
+            'conflict_handler',
+            'add_help',
+        ]
+        return [(name, getattr(self, name)) for name in names]
+
+    # ==================================
+    # Optional/Positional adding methods
+    # ==================================
+    def add_subparsers(self, **kwargs):
+        if self._subparsers is not None:
+            self.error(_('cannot have multiple subparser arguments'))
+
+        # add the parser class to the arguments if it's not present
+        kwargs.setdefault('parser_class', type(self))
+
+        if 'title' in kwargs or 'description' in kwargs:
+            title = _(kwargs.pop('title', 'subcommands'))
+            description = _(kwargs.pop('description', None))
+            self._subparsers = self.add_argument_group(title, description)
+        else:
+            self._subparsers = self._positionals
+
+        # prog defaults to the usage message of this parser, skipping
+        # optional arguments and with no "usage:" prefix
+        if kwargs.get('prog') is None:
+            formatter = self._get_formatter()
+            positionals = self._get_positional_actions()
+            groups = self._mutually_exclusive_groups
+            formatter.add_usage(self.usage, positionals, groups, '')
+            kwargs['prog'] = formatter.format_help().strip()
+
+        # create the parsers action and add it to the positionals list
+        parsers_class = self._pop_action_class(kwargs, 'parsers')
+        action = parsers_class(option_strings=[], **kwargs)
+        self._subparsers._add_action(action)
+
+        # return the created parsers action
+        return action
+
+    def _add_action(self, action):
+        if action.option_strings:
+            self._optionals._add_action(action)
+        else:
+            self._positionals._add_action(action)
+        return action
+
+    def _get_optional_actions(self):
+        return [action
+                for action in self._actions
+                if action.option_strings]
+
+    def _get_positional_actions(self):
+        return [action
+                for action in self._actions
+                if not action.option_strings]
+
+    # =====================================
+    # Command line argument parsing methods
+    # =====================================
+    def parse_args(self, args=None, namespace=None):
+        args, argv = self.parse_known_args(args, namespace)
+        if argv:
+            msg = _('unrecognized arguments: %s')
+            self.error(msg % ' '.join(argv))
+        return args
+
+    def parse_known_args(self, args=None, namespace=None):
+        # args default to the system args
+        if args is None:
+            args = _sys.argv[1:]
+
+        # default Namespace built from parser defaults
+        if namespace is None:
+            namespace = Namespace()
+
+        # add any action defaults that aren't present
+        for action in self._actions:
+            if action.dest is not SUPPRESS:
+                if not hasattr(namespace, action.dest):
+                    if action.default is not SUPPRESS:
+                        default = action.default
+                        if isinstance(action.default, _basestring):
+                            default = self._get_value(action, default)
+                        setattr(namespace, action.dest, default)
+
+        # add any parser defaults that aren't present
+        for dest in self._defaults:
+            if not hasattr(namespace, dest):
+                setattr(namespace, dest, self._defaults[dest])
+
+        # parse the arguments and exit if there are any errors
+        try:
+            return self._parse_known_args(args, namespace)
+        except ArgumentError:
+            err = _sys.exc_info()[1]
+            self.error(str(err))
+
+    def _parse_known_args(self, arg_strings, namespace):
+        # replace arg strings that are file references
+        if self.fromfile_prefix_chars is not None:
+            arg_strings = self._read_args_from_files(arg_strings)
+
+        # map all mutually exclusive arguments to the other arguments
+        # they can't occur with
+        action_conflicts = {}
+        for mutex_group in self._mutually_exclusive_groups:
+            group_actions = mutex_group._group_actions
+            for i, mutex_action in enumerate(mutex_group._group_actions):
+                conflicts = action_conflicts.setdefault(mutex_action, [])
+                conflicts.extend(group_actions[:i])
+                conflicts.extend(group_actions[i + 1:])
+
+        # find all option indices, and determine the arg_string_pattern
+        # which has an 'O' if there is an option at an index,
+        # an 'A' if there is an argument, or a '-' if there is a '--'
+        option_string_indices = {}
+        arg_string_pattern_parts = []
+        arg_strings_iter = iter(arg_strings)
+        for i, arg_string in enumerate(arg_strings_iter):
+
+            # all args after -- are non-options
+            if arg_string == '--':
+                arg_string_pattern_parts.append('-')
+                for arg_string in arg_strings_iter:
+                    arg_string_pattern_parts.append('A')
+
+            # otherwise, add the arg to the arg strings
+            # and note the index if it was an option
+            else:
+                option_tuple = self._parse_optional(arg_string)
+                if option_tuple is None:
+                    pattern = 'A'
+                else:
+                    option_string_indices[i] = option_tuple
+                    pattern = 'O'
+                arg_string_pattern_parts.append(pattern)
+
+        # join the pieces together to form the pattern
+        arg_strings_pattern = ''.join(arg_string_pattern_parts)
+
+        # converts arg strings to the appropriate and then takes the action
+        seen_actions = _set()
+        seen_non_default_actions = _set()
+
+        def take_action(action, argument_strings, option_string=None):
+            seen_actions.add(action)
+            argument_values = self._get_values(action, argument_strings)
+
+            # error if this argument is not allowed with other previously
+            # seen arguments, assuming that actions that use the default
+            # value don't really count as "present"
+            if argument_values is not action.default:
+                seen_non_default_actions.add(action)
+                for conflict_action in action_conflicts.get(action, []):
+                    if conflict_action in seen_non_default_actions:
+                        msg = _('not allowed with argument %s')
+                        action_name = _get_action_name(conflict_action)
+                        raise ArgumentError(action, msg % action_name)
+
+            # take the action if we didn't receive a SUPPRESS value
+            # (e.g. from a default)
+            if argument_values is not SUPPRESS:
+                action(self, namespace, argument_values, option_string)
+
+        # function to convert arg_strings into an optional action
+        def consume_optional(start_index):
+
+            # get the optional identified at this index
+            option_tuple = option_string_indices[start_index]
+            action, option_string, explicit_arg = option_tuple
+
+            # identify additional optionals in the same arg string
+            # (e.g. -xyz is the same as -x -y -z if no args are required)
+            match_argument = self._match_argument
+            action_tuples = []
+            while True:
+
+                # if we found no optional action, skip it
+                if action is None:
+                    extras.append(arg_strings[start_index])
+                    return start_index + 1
+
+                # if there is an explicit argument, try to match the
+                # optional's string arguments to only this
+                if explicit_arg is not None:
+                    arg_count = match_argument(action, 'A')
+
+                    # if the action is a single-dash option and takes no
+                    # arguments, try to parse more single-dash options out
+                    # of the tail of the option string
+                    chars = self.prefix_chars
+                    if arg_count == 0 and option_string[1] not in chars:
+                        action_tuples.append((action, [], option_string))
+                        for char in self.prefix_chars:
+                            option_string = char + explicit_arg[0]
+                            explicit_arg = explicit_arg[1:] or None
+                            optionals_map = self._option_string_actions
+                            if option_string in optionals_map:
+                                action = optionals_map[option_string]
+                                break
+                        else:
+                            msg = _('ignored explicit argument %r')
+                            raise ArgumentError(action, msg % explicit_arg)
+
+                    # if the action expect exactly one argument, we've
+                    # successfully matched the option; exit the loop
+                    elif arg_count == 1:
+                        stop = start_index + 1
+                        args = [explicit_arg]
+                        action_tuples.append((action, args, option_string))
+                        break
+
+                    # error if a double-dash option did not use the
+                    # explicit argument
+                    else:
+                        msg = _('ignored explicit argument %r')
+                        raise ArgumentError(action, msg % explicit_arg)
+
+                # if there is no explicit argument, try to match the
+                # optional's string arguments with the following strings
+                # if successful, exit the loop
+                else:
+                    start = start_index + 1
+                    selected_patterns = arg_strings_pattern[start:]
+                    arg_count = match_argument(action, selected_patterns)
+                    stop = start + arg_count
+                    args = arg_strings[start:stop]
+                    action_tuples.append((action, args, option_string))
+                    break
+
+            # add the Optional to the list and return the index at which
+            # the Optional's string args stopped
+            assert action_tuples
+            for action, args, option_string in action_tuples:
+                take_action(action, args, option_string)
+            return stop
+
+        # the list of Positionals left to be parsed; this is modified
+        # by consume_positionals()
+        positionals = self._get_positional_actions()
+
+        # function to convert arg_strings into positional actions
+        def consume_positionals(start_index):
+            # match as many Positionals as possible
+            match_partial = self._match_arguments_partial
+            selected_pattern = arg_strings_pattern[start_index:]
+            arg_counts = match_partial(positionals, selected_pattern)
+
+            # slice off the appropriate arg strings for each Positional
+            # and add the Positional and its args to the list
+            for action, arg_count in zip(positionals, arg_counts):
+                args = arg_strings[start_index: start_index + arg_count]
+                start_index += arg_count
+                take_action(action, args)
+
+            # slice off the Positionals that we just parsed and return the
+            # index at which the Positionals' string args stopped
+            positionals[:] = positionals[len(arg_counts):]
+            return start_index
+
+        # consume Positionals and Optionals alternately, until we have
+        # passed the last option string
+        extras = []
+        start_index = 0
+        if option_string_indices:
+            max_option_string_index = max(option_string_indices)
+        else:
+            max_option_string_index = -1
+        while start_index <= max_option_string_index:
+
+            # consume any Positionals preceding the next option
+            next_option_string_index = min([
+                index
+                for index in option_string_indices
+                if index >= start_index])
+            if start_index != next_option_string_index:
+                positionals_end_index = consume_positionals(start_index)
+
+                # only try to parse the next optional if we didn't consume
+                # the option string during the positionals parsing
+                if positionals_end_index > start_index:
+                    start_index = positionals_end_index
+                    continue
+                else:
+                    start_index = positionals_end_index
+
+            # if we consumed all the positionals we could and we're not
+            # at the index of an option string, there were extra arguments
+            if start_index not in option_string_indices:
+                strings = arg_strings[start_index:next_option_string_index]
+                extras.extend(strings)
+                start_index = next_option_string_index
+
+            # consume the next optional and any arguments for it
+            start_index = consume_optional(start_index)
+
+        # consume any positionals following the last Optional
+        stop_index = consume_positionals(start_index)
+
+        # if we didn't consume all the argument strings, there were extras
+        extras.extend(arg_strings[stop_index:])
+
+        # if we didn't use all the Positional objects, there were too few
+        # arg strings supplied.
+        if positionals:
+            self.error(_('too few arguments'))
+
+        # make sure all required actions were present
+        for action in self._actions:
+            if action.required:
+                if action not in seen_actions:
+                    name = _get_action_name(action)
+                    self.error(_('argument %s is required') % name)
+
+        # make sure all required groups had one option present
+        for group in self._mutually_exclusive_groups:
+            if group.required:
+                for action in group._group_actions:
+                    if action in seen_non_default_actions:
+                        break
+
+                # if no actions were used, report the error
+                else:
+                    names = [_get_action_name(action)
+                             for action in group._group_actions
+                             if action.help is not SUPPRESS]
+                    msg = _('one of the arguments %s is required')
+                    self.error(msg % ' '.join(names))
+
+        # return the updated namespace and the extra arguments
+        return namespace, extras
+
+    def _read_args_from_files(self, arg_strings):
+        # expand arguments referencing files
+        new_arg_strings = []
+        for arg_string in arg_strings:
+
+            # for regular arguments, just add them back into the list
+            if arg_string[0] not in self.fromfile_prefix_chars:
+                new_arg_strings.append(arg_string)
+
+            # replace arguments referencing files with the file content
+            else:
+                try:
+                    args_file = open(arg_string[1:])
+                    try:
+                        arg_strings = []
+                        for arg_line in args_file.read().splitlines():
+                            for arg in self.convert_arg_line_to_args(arg_line):
+                                arg_strings.append(arg)
+                        arg_strings = self._read_args_from_files(arg_strings)
+                        new_arg_strings.extend(arg_strings)
+                    finally:
+                        args_file.close()
+                except IOError:
+                    err = _sys.exc_info()[1]
+                    self.error(str(err))
+
+        # return the modified argument list
+        return new_arg_strings
+
+    def convert_arg_line_to_args(self, arg_line):
+        return [arg_line]
+
+    def _match_argument(self, action, arg_strings_pattern):
+        # match the pattern for this action to the arg strings
+        nargs_pattern = self._get_nargs_pattern(action)
+        match = _re.match(nargs_pattern, arg_strings_pattern)
+
+        # raise an exception if we weren't able to find a match
+        if match is None:
+            nargs_errors = {
+                None: _('expected one argument'),
+                OPTIONAL: _('expected at most one argument'),
+                ONE_OR_MORE: _('expected at least one argument'),
+            }
+            default = _('expected %s argument(s)') % action.nargs
+            msg = nargs_errors.get(action.nargs, default)
+            raise ArgumentError(action, msg)
+
+        # return the number of arguments matched
+        return len(match.group(1))
+
+    def _match_arguments_partial(self, actions, arg_strings_pattern):
+        # progressively shorten the actions list by slicing off the
+        # final actions until we find a match
+        result = []
+        for i in range(len(actions), 0, -1):
+            actions_slice = actions[:i]
+            pattern = ''.join([self._get_nargs_pattern(action)
+                               for action in actions_slice])
+            match = _re.match(pattern, arg_strings_pattern)
+            if match is not None:
+                result.extend([len(string) for string in match.groups()])
+                break
+
+        # return the list of arg string counts
+        return result
+
+    def _parse_optional(self, arg_string):
+        # if it's an empty string, it was meant to be a positional
+        if not arg_string:
+            return None
+
+        # if it doesn't start with a prefix, it was meant to be positional
+        if not arg_string[0] in self.prefix_chars:
+            return None
+
+        # if the option string is present in the parser, return the action
+        if arg_string in self._option_string_actions:
+            action = self._option_string_actions[arg_string]
+            return action, arg_string, None
+
+        # if it's just a single character, it was meant to be positional
+        if len(arg_string) == 1:
+            return None
+
+        # if the option string before the "=" is present, return the action
+        if '=' in arg_string:
+            option_string, explicit_arg = arg_string.split('=', 1)
+            if option_string in self._option_string_actions:
+                action = self._option_string_actions[option_string]
+                return action, option_string, explicit_arg
+
+        # search through all possible prefixes of the option string
+        # and all actions in the parser for possible interpretations
+        option_tuples = self._get_option_tuples(arg_string)
+
+        # if multiple actions match, the option string was ambiguous
+        if len(option_tuples) > 1:
+            options = ', '.join([option_string
+                for action, option_string, explicit_arg in option_tuples])
+            tup = arg_string, options
+            self.error(_('ambiguous option: %s could match %s') % tup)
+
+        # if exactly one action matched, this segmentation is good,
+        # so return the parsed action
+        elif len(option_tuples) == 1:
+            option_tuple, = option_tuples
+            return option_tuple
+
+        # if it was not found as an option, but it looks like a negative
+        # number, it was meant to be positional
+        # unless there are negative-number-like options
+        if self._negative_number_matcher.match(arg_string):
+            if not self._has_negative_number_optionals:
+                return None
+
+        # if it contains a space, it was meant to be a positional
+        if ' ' in arg_string:
+            return None
+
+        # it was meant to be an optional but there is no such option
+        # in this parser (though it might be a valid option in a subparser)
+        return None, arg_string, None
+
+    def _get_option_tuples(self, option_string):
+        result = []
+
+        # option strings starting with two prefix characters are only
+        # split at the '='
+        chars = self.prefix_chars
+        if option_string[0] in chars and option_string[1] in chars:
+            if '=' in option_string:
+                option_prefix, explicit_arg = option_string.split('=', 1)
+            else:
+                option_prefix = option_string
+                explicit_arg = None
+            for option_string in self._option_string_actions:
+                if option_string.startswith(option_prefix):
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, explicit_arg
+                    result.append(tup)
+
+        # single character options can be concatenated with their arguments
+        # but multiple character options always have to have their argument
+        # separate
+        elif option_string[0] in chars and option_string[1] not in chars:
+            option_prefix = option_string
+            explicit_arg = None
+            short_option_prefix = option_string[:2]
+            short_explicit_arg = option_string[2:]
+
+            for option_string in self._option_string_actions:
+                if option_string == short_option_prefix:
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, short_explicit_arg
+                    result.append(tup)
+                elif option_string.startswith(option_prefix):
+                    action = self._option_string_actions[option_string]
+                    tup = action, option_string, explicit_arg
+                    result.append(tup)
+
+        # shouldn't ever get here
+        else:
+            self.error(_('unexpected option string: %s') % option_string)
+
+        # return the collected option tuples
+        return result
+
+    def _get_nargs_pattern(self, action):
+        # in all examples below, we have to allow for '--' args
+        # which are represented as '-' in the pattern
+        nargs = action.nargs
+
+        # the default (None) is assumed to be a single argument
+        if nargs is None:
+            nargs_pattern = '(-*A-*)'
+
+        # allow zero or one arguments
+        elif nargs == OPTIONAL:
+            nargs_pattern = '(-*A?-*)'
+
+        # allow zero or more arguments
+        elif nargs == ZERO_OR_MORE:
+            nargs_pattern = '(-*[A-]*)'
+
+        # allow one or more arguments
+        elif nargs == ONE_OR_MORE:
+            nargs_pattern = '(-*A[A-]*)'
+
+        # allow any number of options or arguments
+        elif nargs == REMAINDER:
+            nargs_pattern = '([-AO]*)'
+
+        # allow one argument followed by any number of options or arguments
+        elif nargs == PARSER:
+            nargs_pattern = '(-*A[-AO]*)'
+
+        # all others should be integers
+        else:
+            nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
+
+        # if this is an optional action, -- is not allowed
+        if action.option_strings:
+            nargs_pattern = nargs_pattern.replace('-*', '')
+            nargs_pattern = nargs_pattern.replace('-', '')
+
+        # return the pattern
+        return nargs_pattern
+
+    # ========================
+    # Value conversion methods
+    # ========================
+    def _get_values(self, action, arg_strings):
+        # for everything but PARSER args, strip out '--'
+        if action.nargs not in [PARSER, REMAINDER]:
+            arg_strings = [s for s in arg_strings if s != '--']
+
+        # optional argument produces a default when not present
+        if not arg_strings and action.nargs == OPTIONAL:
+            if action.option_strings:
+                value = action.const
+            else:
+                value = action.default
+            if isinstance(value, _basestring):
+                value = self._get_value(action, value)
+                self._check_value(action, value)
+
+        # when nargs='*' on a positional, if there were no command-line
+        # args, use the default if it is anything other than None
+        elif (not arg_strings and action.nargs == ZERO_OR_MORE and
+              not action.option_strings):
+            if action.default is not None:
+                value = action.default
+            else:
+                value = arg_strings
+            self._check_value(action, value)
+
+        # single argument or optional argument produces a single value
+        elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
+            arg_string, = arg_strings
+            value = self._get_value(action, arg_string)
+            self._check_value(action, value)
+
+        # REMAINDER arguments convert all values, checking none
+        elif action.nargs == REMAINDER:
+            value = [self._get_value(action, v) for v in arg_strings]
+
+        # PARSER arguments convert all values, but check only the first
+        elif action.nargs == PARSER:
+            value = [self._get_value(action, v) for v in arg_strings]
+            self._check_value(action, value[0])
+
+        # all other types of nargs produce a list
+        else:
+            value = [self._get_value(action, v) for v in arg_strings]
+            for v in value:
+                self._check_value(action, v)
+
+        # return the converted value
+        return value
+
+    def _get_value(self, action, arg_string):
+        type_func = self._registry_get('type', action.type, action.type)
+        if not _callable(type_func):
+            msg = _('%r is not callable')
+            raise ArgumentError(action, msg % type_func)
+
+        # convert the value to the appropriate type
+        try:
+            result = type_func(arg_string)
+
+        # ArgumentTypeErrors indicate errors
+        except ArgumentTypeError:
+            name = getattr(action.type, '__name__', repr(action.type))
+            msg = str(_sys.exc_info()[1])
+            raise ArgumentError(action, msg)
+
+        # TypeErrors or ValueErrors also indicate errors
+        except (TypeError, ValueError):
+            name = getattr(action.type, '__name__', repr(action.type))
+            msg = _('invalid %s value: %r')
+            raise ArgumentError(action, msg % (name, arg_string))
+
+        # return the converted value
+        return result
+
+    def _check_value(self, action, value):
+        # converted value must be one of the choices (if specified)
+        if action.choices is not None and value not in action.choices:
+            tup = value, ', '.join(map(repr, action.choices))
+            msg = _('invalid choice: %r (choose from %s)') % tup
+            raise ArgumentError(action, msg)
+
+    # =======================
+    # Help-formatting methods
+    # =======================
+    def format_usage(self):
+        formatter = self._get_formatter()
+        formatter.add_usage(self.usage, self._actions,
+                            self._mutually_exclusive_groups)
+        return formatter.format_help()
+
+    def format_help(self):
+        formatter = self._get_formatter()
+
+        # usage
+        formatter.add_usage(self.usage, self._actions,
+                            self._mutually_exclusive_groups)
+
+        # description
+        formatter.add_text(self.description)
+
+        # positionals, optionals and user-defined groups
+        for action_group in self._action_groups:
+            formatter.start_section(action_group.title)
+            formatter.add_text(action_group.description)
+            formatter.add_arguments(action_group._group_actions)
+            formatter.end_section()
+
+        # epilog
+        formatter.add_text(self.epilog)
+
+        # determine help from format above
+        return formatter.format_help()
+
+    def format_version(self):
+        import warnings
+        warnings.warn(
+            'The format_version method is deprecated -- the "version" '
+            'argument to ArgumentParser is no longer supported.',
+            DeprecationWarning)
+        formatter = self._get_formatter()
+        formatter.add_text(self.version)
+        return formatter.format_help()
+
+    def _get_formatter(self):
+        return self.formatter_class(prog=self.prog)
+
+    # =====================
+    # Help-printing methods
+    # =====================
+    def print_usage(self, file=None):
+        if file is None:
+            file = _sys.stdout
+        self._print_message(self.format_usage(), file)
+
+    def print_help(self, file=None):
+        if file is None:
+            file = _sys.stdout
+        self._print_message(self.format_help(), file)
+
+    def print_version(self, file=None):
+        import warnings
+        warnings.warn(
+            'The print_version method is deprecated -- the "version" '
+            'argument to ArgumentParser is no longer supported.',
+            DeprecationWarning)
+        self._print_message(self.format_version(), file)
+
+    def _print_message(self, message, file=None):
+        if message:
+            if file is None:
+                file = _sys.stderr
+            file.write(message)
+
+    # ===============
+    # Exiting methods
+    # ===============
+    def exit(self, status=0, message=None):
+        if message:
+            self._print_message(message, _sys.stderr)
+        _sys.exit(status)
+
+    def error(self, message):
+        """error(message: string)
+
+        Prints a usage message incorporating the message to stderr and
+        exits.
+
+        If you override this in a subclass, it should not return -- it
+        should either exit or raise an exception.
+        """
+        self.print_usage(_sys.stderr)
+        self.exit(2, _('%s: error: %s\n') % (self.prog, message))
diff --git a/rc1/utils/check_format.sh b/rc1/utils/check_format.sh
new file mode 100755
index 0000000..120a6a2
--- /dev/null
+++ b/rc1/utils/check_format.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+CLANG_FORMAT=${CLANG_FORMAT}
+
+if [ "${CLANG_FORMAT}x" = "x" ]; then
+  CLANG_FORMAT=`which clang-format`
+  if [ "${CLANG_FORMAT}x" = "x" ]; then
+     echo "Error: cannot find clang-format in your path"
+     exit 1
+  fi
+fi
+
+OK=0
+
+for ARG in "$@"
+  do
+    ${CLANG_FORMAT} $ARG | diff -u $ARG -
+
+    if [[ $? -eq 1 ]]; then
+      OK=1
+    fi
+  done
+
+if [[ $OK -eq "1" ]]; then
+  echo "Error: clang-format reported formatting differences"
+  exit 1
+else
+  echo "OK: clang-format reported no formatting differences"
+  exit 0
+fi
+
diff --git a/rc1/utils/checkout_cloog.sh b/rc1/utils/checkout_cloog.sh
new file mode 100755
index 0000000..0957005
--- /dev/null
+++ b/rc1/utils/checkout_cloog.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+CLOOG_HASH="22643c94eba7b010ae4401c347289f4f52b9cd2b"
+ISL_HASH="163646566efd07086ed4fbe99ecbf8d5bb8ebca0"
+
+PWD=`pwd`
+
+check_command_line() {
+  if [ $# -eq 1 ]
+  then
+    CLOOG_DIR="${1}"
+  else
+      echo "Usage: " ${0} '<Directory to checkout CLooG>'
+      exit 1
+  fi
+}
+
+check_cloog_directory() {
+  if ! [ -e ${CLOOG_DIR} ]
+  then
+    echo :: Directory "'${CLOOG_DIR}'" does not exists. Trying to create it.
+    if ! mkdir -p "${CLOOG_DIR}"
+    then exit 1
+    fi
+  fi
+
+  if ! [ -d ${CLOOG_DIR} ]
+  then
+    echo "'${CLOOG_DIR}'" is not a directory
+    exit 1
+  fi
+
+  # Make it absolute
+  cd ${CLOOG_DIR}
+  CLOOG_DIR=`pwd`
+
+  if ! [ -e "${CLOOG_DIR}/.git" ]
+  then
+    echo ":: No git checkout found"
+    IS_GIT=0
+  else
+    echo ":: Existing git repo found"
+    IS_GIT=1
+  fi
+}
+
+complain() {
+  echo "$@"
+  exit 1
+}
+
+run() {
+  $cmdPre $*
+  if [ $? != 0 ]
+    then
+    complain $* failed
+  fi
+}
+
+check_command_line $@
+check_cloog_directory
+
+ISL_DIR=${CLOOG_DIR}/isl
+
+if [ ${IS_GIT} -eq 0 ]
+then
+  echo :: Performing initial checkout
+  # Remove the existing CLooG and ISL dirs to avoid crashing older git versions.
+  cd ${CLOOG_DIR}/..
+  run rmdir "${CLOOG_DIR}"
+  run git clone http://repo.or.cz/r/cloog.git ${CLOOG_DIR}
+  run rmdir "${ISL_DIR}"
+  run git clone http://repo.or.cz/r/isl.git ${ISL_DIR}
+fi
+
+echo :: Fetch versions required by Polly
+run cd ${CLOOG_DIR}
+run git remote update
+run cd isl
+run git remote update
+
+echo :: Setting CLooG version
+run cd ${CLOOG_DIR}
+run git reset --hard "${CLOOG_HASH}"
+
+echo :: Setting isl version
+run cd ${ISL_DIR}
+run git reset --hard "${ISL_HASH}"
+
+echo :: Generating configure
+run cd ${CLOOG_DIR}
+run ./autogen.sh
+
+echo :: If you install cloog/isl the first time run "'./configure'" followed by
+echo :: "'make'" and "'make install'", otherwise, just call "'make'" and
+echo :: "'make'" install.
diff --git a/rc1/utils/jscop2cloog.py b/rc1/utils/jscop2cloog.py
new file mode 100755
index 0000000..668f085
--- /dev/null
+++ b/rc1/utils/jscop2cloog.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+import argparse, os
+import json
+
+def getDomains(scop):
+  statements = scop['statements'];
+  numStatements = len(statements)
+
+  output = "%s\n\n" % str(numStatements)
+
+  for statement in scop['statements']:
+    output += "%s\n\n" % statement['domain']
+    output += "0  0  0               # for future options\n\n"
+
+
+  return output
+
+def getSchedules(scop):
+  statements = scop['statements'];
+  numStatements = len(statements)
+
+  output = "%s\n\n" % str(numStatements)
+
+  for statement in scop['statements']:
+    output += "%s\n\n" % statement['schedule']
+
+  return output
+
+def writeCloog(scop):
+  template = """
+# ---------------------- CONTEXT ----------------------
+c # language is C
+
+# Context (no constraints on two parameters)
+%s
+
+0 # We do not want to set manually the parameter names
+
+# --------------------- STATEMENTS --------------------
+%s
+
+0 # We do not want to set manually the iterator names
+
+# --------------------- SCATTERING --------------------
+%s
+
+0 # We do not want to set manually the scattering dimension names
+"""
+
+  context = scop['context']
+  domains = getDomains(scop)
+  schedules = getSchedules(scop)
+  print template % (context, domains, schedules)
+
+def __main__():
+  description = 'Translate JSCoP into iscc input'
+  parser = argparse.ArgumentParser(description)
+  parser.add_argument('inputFile', metavar='N', type=file,
+                      help='The JSCoP file')
+
+  args = parser.parse_args()
+  inputFile = args.inputFile
+  scop = json.load(inputFile)
+
+  writeCloog(scop)
+
+__main__()
+
diff --git a/rc1/utils/pyscop/isl.py b/rc1/utils/pyscop/isl.py
new file mode 100644
index 0000000..0c8de2f
--- /dev/null
+++ b/rc1/utils/pyscop/isl.py
@@ -0,0 +1,578 @@
+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']
diff --git a/rc1/utils/pyscop/jscop2iscc.py b/rc1/utils/pyscop/jscop2iscc.py
new file mode 100755
index 0000000..3267e8e
--- /dev/null
+++ b/rc1/utils/pyscop/jscop2iscc.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+import argparse, isl, os
+import json
+
+def printDomain(scop):
+
+  domain = isl.USet('{}')
+
+  for statement in scop['statements']:
+    domain = domain.union(isl.USet(statement['domain']))
+
+  print "D :=",
+  print str(domain) + ";"
+
+def printAccesses(scop):
+
+  read = isl.UMap('{}')
+
+  for statement in scop['statements']:
+    for access in statement['accesses']:
+      if access['kind'] == 'read':
+        read = read.union(isl.UMap(access['relation']))
+
+  print "R :=",
+  print str(read) + ";"
+
+  write = isl.UMap('{}')
+
+  for statement in scop['statements']:
+    for access in statement['accesses']:
+      if access['kind'] == 'write':
+        write = write.union(isl.UMap(access['relation']))
+
+  print "W :=",
+  print str(write) + ";"
+
+def printSchedule(scop):
+
+  schedule = isl.UMap('{}')
+
+  for statement in scop['statements']:
+    schedule = schedule.union(isl.UMap(statement['schedule']))
+
+  print "S :=",
+  print str(schedule) + ";"
+
+def __main__():
+  description = 'Translate JSCoP into iscc input'
+  parser = argparse.ArgumentParser(description)
+  parser.add_argument('inputFile', metavar='N', type=file,
+                      help='The JSCoP file')
+
+  args = parser.parse_args()
+  inputFile = args.inputFile
+  scop = json.load(inputFile)
+
+  printDomain(scop)
+  printAccesses(scop)
+  printSchedule(scop)
+
+  print 'R := R * D;'
+  print 'W := W * D;'
+  print 'Dep := (last W before R under S)[0];'
+  print 'schedule D respecting Dep minimizing Dep;'
+
+
+__main__()
+
diff --git a/rc1/utils/pyscop/pyscop.py b/rc1/utils/pyscop/pyscop.py
new file mode 100644
index 0000000..a7c3481
--- /dev/null
+++ b/rc1/utils/pyscop/pyscop.py
@@ -0,0 +1,68 @@
+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)
diff --git a/rc1/utils/update_format.sh b/rc1/utils/update_format.sh
new file mode 100755
index 0000000..9226fc6
--- /dev/null
+++ b/rc1/utils/update_format.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+CLANG_FORMAT=${CLANG_FORMAT}
+
+if [ "${CLANG_FORMAT}x" = "x" ]; then
+  CLANG_FORMAT=`which clang-format`
+  if [ "${CLANG_FORMAT}x" = "x" ]; then
+     echo "Error: cannot find clang-format in your path"
+     exit 1
+  fi
+fi
+
+for ARG in "$@"
+  do
+    ${CLANG_FORMAT} -i $ARG
+  done
diff --git a/rc1/www/.htaccess b/rc1/www/.htaccess
new file mode 100644
index 0000000..bfd0afc
--- /dev/null
+++ b/rc1/www/.htaccess
@@ -0,0 +1 @@
+AddHandler server-parsed .html 
diff --git a/rc1/www/bugs.html b/rc1/www/bugs.html
new file mode 100644
index 0000000..87254a8
--- /dev/null
+++ b/rc1/www/bugs.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+  "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Polly - Bugs</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Bug Reports</h1>
+
+Polly uses the LLVM bug tracking system.
+
+<h3>File a  Bug</h3>
+
+If a problem appears, please <a
+href="http://llvm.org/bugs/enter_bug.cgi?product=Projects&component=Polly">
+report a bug</a> to the LLVM bugzilla. Polly bugs are tracked under product
+'Projects' and component 'Polly'.
+
+
+<h3>Open Bugs</h3>
+A list of the <a
+href="http://llvm.org/bugs/buglist.cgi?query_format=advanced&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Polly&product=Projects">open
+bugs</a> in Polly is also available.
+
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/content.css b/rc1/www/content.css
new file mode 100644
index 0000000..b7e8f2e
--- /dev/null
+++ b/rc1/www/content.css
@@ -0,0 +1,139 @@
+html { margin: 0px; } body { margin: 8px; }
+
+html, body {
+  padding:0px;
+  font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222;
+}
+
+#box {
+  margin-left: auto;
+  margin-right: auto;
+  max-width: 70em;
+}
+[id=content] {
+	/* *****  EDIT THIS VALUE IF CONTENT OVERLAPS MENU ***** */
+        margin-left: 18em;
+	padding-left: 3em;
+}
+
+a:visited {
+  color: #931e24;
+}
+
+h1, h2, h3, tt { color: #000 }
+
+h1 { padding-top:0px; margin-top:0px;}
+h2 { color:#333333; padding-top:0.5em; }
+h3 { padding-top: 0.5em; margin-bottom: -0.25em; color:#2d58b7}
+li { padding-bottom: 0.5em; }
+ul { padding-left:1.5em; }
+
+TD.done {background-color: #88ff99; text-align: center}
+TD.inprogress{background-color: #ffce00; text-align: center}
+TD.open{background-color: #e6705f; text-align: center}
+TD.nice{background-color: #5555df; text-align: center}
+TD.niceinprogress{background-color: #8888ff; text-align: center}
+
+PRE.code {padding-left: 0.5em; background-color: #eeeeee}
+PRE {padding-left: 0.5em}
+
+/* Slides */
+IMG.img_slide {
+    display: block;
+    margin-left: auto;
+    margin-right: auto
+}
+
+.itemTitle { color:#2d58b7 }
+
+span.error { color:red }
+span.caret { color:green; font-weight:bold }
+
+/* Tables */
+tr { vertical-align:top }
+#news P {padding: 0px; margin: 0px; border: 0px}
+
+#head {
+    min-height: 15em;
+    background-image:url(images/header-background.png);
+    background-repeat:no-repeat;
+    background-position: right;
+    max-width: 70em;
+    margin-bottom: 1em
+
+
+}
+
+#head h1 {
+  padding-bottom: 0em;
+  margin-bottom: 0em;
+  padding-top: 1em;
+  padding-left: 2em;
+  font-size: 3em;
+}
+
+#head h1 span {
+  background: white;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  background: white;
+  box-shadow: 1px 2px 5px 1px rgba(0, 0, 0, 0.7),
+              -1px 2px 20px rgba(255, 255, 255, 0.6) inset; 
+}
+
+#head h1 span a {
+  text-decoration: none;
+  color: #3b4567;
+}
+#head h1 span:before {
+  content: "\00a0 ";
+}
+#head h1 span:after {
+  content: "\00a0 ";
+}
+
+#head h2 {
+  color: #3b4567;
+  text-align: center;
+  padding-top: 0em;
+  margin-top: 0em;
+  padding-left: .5em;
+  padding-bottom: .5em;
+}
+
+#head h2 span {
+  background: white;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  background: white;
+  box-shadow: 1px 2px 5px 1px rgba(0, 0, 0, 0.7),
+              -1px 2px 20px rgba(255, 255, 255, 0.6) inset; 
+  padding-top: 0.2em;
+  padding-bottom: 0.2em;
+}
+
+#head h2 span:before {
+  content: "\00a0\00a0\00a0";
+}
+#head h2 span:after {
+  content: "\00a0\00a0\00a0";
+}
+
+#head p:before {
+  content: "\00a0\00a0\00a0";
+}
+#head p:after {
+  content: "\00a0\00a0\00a0";
+}
+
+#head p {
+  padding:0.1em;
+  background: rgba(0,0,0,0.3);
+  color: white;
+  position: absolute;
+  top: -1em; right: 0.5em;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+}
diff --git a/rc1/www/contributors.html b/rc1/www/contributors.html
new file mode 100644
index 0000000..83c64f5
--- /dev/null
+++ b/rc1/www/contributors.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Polly - Contributors</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Contributors</h1>
+
+Polly is developed by a team of students supported by different universities.
+
+<h2>People</h2>
+<h3>Raghesh Aloor</h3>
+<p>Raghesh works on OpenMP code generation. He is funded as Google Summer of Code
+Student 2011.</p>
+
+<h3>Tobias Grosser</h3>
+<p>Tobias is one of the two Co-founders of Polly. He designed the overall
+architecture and contributed to almost every part of Polly. Polly was started
+during his diploma studies at University of Passau. Furthermore, he spent 6
+months at Ohio State University (funded by the U.S. National Science Foundation
+through awards 0811781 and 0926688). From August 2011 he works on Polly,
+during his PhD with INRIA/UMPC/ENS (funded through a
+<a href="http://research.google.com/university/relations/fellowship_recipients.html">
+Google Europe Fellowship in Efficient Computing</a>).</p>
+
+<p>Website: <a href="http://www.grosser.es">www.grosser.es</a></p>
+
+
+<h3>Andreas Simb&uuml;rger</h3>
+<p>
+Andreas works on the profiling infrastructure during his PhD at University of
+Passau.
+</p>
+<p>Website: <a href="http://www.infosun.fim.uni-passau.de/cl/staff/simbuerger/">
+http://www.infosun.fim.uni-passau.de/cl/staff/simbuerger/</a></p>
+<h3>Hongbin Zheng</h3>
+<p>Hongbin Zheng is one of the two Co-founders of Polly. He was funded as a
+Google Summer of Code Student 2010 and implemented parts of the Polly frontends
+as well as the automake/cmake infrastructure.</p>
+
+<h2> Universities</h2>
+
+<p>Polly is supported by the following Universities.</p>
+<img src="images/iit-madras.png" style="padding:1em" />
+<img src="images/uni-passau.png" style="padding: 1em; padding-bottom:2em;"/>
+<img src="images/osu.png" style="padding:1em"/>
+<img src="images/sys-uni.png" style="padding:1em"/>
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/documentation.html b/rc1/www/documentation.html
new file mode 100644
index 0000000..eddf1cf
--- /dev/null
+++ b/rc1/www/documentation.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Documentation</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>Documentation</h1>
+  <!--*********************************************************************-->
+
+<ul>
+<li><a href="documentation/architecture.html">The Architecture of Polly</a></li>
+<li><a href="example_load_Polly_into_clang.html">Use Polly in clang/clang++</a>
+
+</li>
+<li><a href="example_load_Polly_into_dragonegg.html">Use Polly in dragonegg</a>
+</li>
+
+<li>
+<a href="example_manual_matmul.html">Inside Polly - How to manually use the
+individual pieces of Polly</a>
+
+</li>
+<li><a href="documentation/passes.html">A list of the LLVM passes available
+in Polly</a></li>
+<li><a href="documentation/memaccess.html">Polly - Memory access optimizations
+</a></li>
+</ul>
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/documentation/architecture.html b/rc1/www/documentation/architecture.html
new file mode 100644
index 0000000..aa1c80f
--- /dev/null
+++ b/rc1/www/documentation/architecture.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - The architecture</title>
+  <link type="text/css" rel="stylesheet" href="../menu.css">
+  <link type="text/css" rel="stylesheet" href="../content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="../menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>The Architecture Diagram of Polly</h1>
+  <!--*********************************************************************-->
+  <img src='../images/architecture.png' />
+</div>
+</div>
+</body>
+</html>
+
diff --git a/rc1/www/documentation/gpgpucodegen.html b/rc1/www/documentation/gpgpucodegen.html
new file mode 100644
index 0000000..74af240
--- /dev/null
+++ b/rc1/www/documentation/gpgpucodegen.html
@@ -0,0 +1,229 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - GPGPU Code Generation</title>
+  <link type="text/css" rel="stylesheet" href="../menu.css">
+  <link type="text/css" rel="stylesheet" href="../content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="../menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>Polly - GPGPU Code Generation</h1>
+  <!--*********************************************************************-->
+<p><em>WARNING: This project was part of the Google Summer of Code 2012.
+It is currently not finished, but it is in the design and implementation stage.
+The ideas/plans described here may not yet be implemented in Polly and may
+change later on.</em></p>
+
+This project adds GPGPU code generation feature to Polly.
+
+<h2>Objective</h2>
+<p>The overall objective of this GSoC project is to create a preliminary
+   implementation of GPGPU code generation for Polly. With this addition, users
+   can parallelize some perfectly nested loops with Polly to execute on a
+   heterogeneous platform, composed of CPU and GPU.</p>
+<p>There are several successful projects about automatic source-to-source gpu
+   code transformation. C-to-CUDA[1] uses the standard Pluto algorithms for
+   computing an affine schedule and then applies a wavefront transformation to
+   obtain one sequential and n-1 parallel loops. The parallel loops are then
+   mapped onto the blocks and threads of GPU. PPCG[2] introduces some advanced
+   algorithms which can expose much more parallelism than other methods . And It
+   also introduces affine partition heuristics and code generation algorithms
+   for locality enhancement in the registers and shared memory.</p>
+<p>Since automatic GPGPU code generation is quite a complex problem and what we
+   target is a low-level intermediate representation, LLVM IR, rather than a
+   high-level language source, it is important for us to set a proper objective
+   as a start step to give a complete solution to GPGPU code generation for LLVM
+   IR.</p>
+<p>Firstly, we plan to target two kinds of relatively simple test cases. One is
+   comprised of pure parallel and perfectly nested loops, like the following
+   code.</p>
+<pre>
+parfor(int i=0 to M)
+  parfor(int j=0 to N)
+    LoopBody(i, j);
+</pre>
+<p>Another one is that all the loops in it are parallel except the inner-most
+   one, just like this:</p>
+<pre>
+parfor(int i=0 to M)
+  parfor(int j=0 to N)
+    non-parfor(int k=0 to K)
+      LoopBody(i, j, k);
+</pre>
+<p>The LoopBody part should be limited to instructions or functions calls
+   (intrinsics) which can be handled by LLVM's NVPTX backend.</p>
+<p>On the other hand, we focus on building a preliminary and scalable framework
+   of GPGPU code generation for polly. Thus we plan to employ relatively simple
+   tiling and mapping algorithms and optimize them later.</p>
+<h2>Work Flow</h2>
+<h3>GPGPU Code Generation In General</h3>
+<p>C-to-CUDA[1] and PPCG[2] propose similar steps to solve the automatic GPGPU
+   code generation problem.</p>
+<li>Look for parallel loops.</li>
+<li>Create a polyhedral model from the loops.</li>
+<li>Tile and map the loops to GPU blocks and threads.</li>
+<li>Determine where to place the data.</li>
+<h3>What has been done in Polly</h3>
+<p>Polly has implemented the 1st, 2nd and part of the 3rd of the above steps and
+   many other analysis and transformation passes.</p>
+<h3>What to do in Polly</h3>
+<p>Unlike many source-to-source optimizers such as C-to-CUDA and PPCG, Polly is
+   a low-level optimizer, which means we can't use a source-level compiler
+   (e.g. NVCC) to generate the final assembly for the device. We need manually
+   insert device driver API calls to execute the generated kernel assembly
+   text.</p>
+<p>In this project, we assume that the device driver library has provided an
+   interface to launch kernels in the form of assembly text. Fortunately, most
+   of the mainstream GPU vendors provide such a feature in thier products (see
+   ptxjit of NVIDIA GPUs and CAL of AMD GPUs). Generally speaking, what we
+   are going to do in Polly is:</p>
+<li>Find a way to tile the parallel loops.</li>
+<li>Find a way to extract the loop body and transform it into thread-centric
+    parallel code.</li>
+<li>Find a way to store/load the thread-centric code into/from a device module.
+<li>Find a way to pass the target machine information and generate code of the
+    device module for the target.
+<li>Find a way to map the tiled loop to GPU blocks and threads.</li>
+<li>Find a way to insert CUDA synchronization operations on-demand.
+<li>Find a way to generate the memory copy operations between a host and a
+    device.</li>
+<li>Implement/Wrap a runtime library to serve as the execution engine for the
+    generated device code.</li>
+
+<h3>The Work Flow</h3>
+<p>In this section, we assume that the host cpu is X86 and the device is NVIDIA
+   CUDA-compatible. we will use the following test case to describe our work
+   flow.</p>
+<pre>
+for(i = 0; i &lt; 128; i++)
+      for(j = 0; j &lt; 128; j++)
+              A[i][j] = i*128 + j;
+</pre>
+<p>The work flow of our code generator is as follows.</p>
+<p>1.We first use Polly's jscop file importer to get a wanted 4-level parallel
+   tiled code.</p>
+The "schedule" part of the pre-optimization jscop file is as the following:
+<pre>
+"schedule" : "{ Stmt_for_body3[i0, i1] -&gt; scattering[0, i0, 0, i1, 0] }"
+</pre>
+The jscop file describing the tiling transformation is:
+<pre>
+"schedule" : "{ Stmt_for_body3[i0, i1] -&gt; scattering[0, o0, o1, o2, o3]:
+              o0 &gt;= 0 and o0 &lt;= 7 and o1 &gt;= 0 and o1 &lt;= 15 and
+              o2 &gt;= 0 and o2 &lt;= 7 and o3 &gt;= 0 and o3 &lt;= 15 and
+              i0 = 16o0 + o1 and i1 = 16o2 + o3 }"
+</pre>
+We can test the schedule with the following command line.
+<pre>
+opt -load /path/to/polly/build/LLVMPolly.so -basicaa -polly-import-jscop
+    -polly-cloog -analyze -q ./test.ll
+    -polly-import-jscop-postfix=transformed+gpu
+</pre>
+The output of this schedule is:
+<pre>
+for (c2=0;c2&lt;=7;c2++) {
+  for (c3=0;c3&lt;=15;c3++) {
+    for (c4=0;c4&lt;=7;c4++) {
+      for (c5=0;c5&lt;=15;c5++) {
+        Stmt_for_body3(16*c2+c3,16*c4+c5);
+      }
+    }
+  }
+}
+</pre>
+Now we get a 4-dimensional parallel loops with a single SCoP statement in it.
+<p>2.We then extract the loop body (or the inner-most non-parallel loop) into a
+   LLVM function, tagging it with PTX_Kernel call convention.</p>
+<p>3.We extract the PTX_kernel function into a temporary module, set the target
+   triple (e.g. nvptx64-unknown-linux) for the module, transform the temporary
+   module into a string, store it in the original module and erase the
+   PTX_kernel function.</p>
+<p>4.We replace the loops with their GPGPU counterpart. The GPGPU part of code
+   is composed of a call to the llvm.codegen intrinsic and function calls to our
+   GPU runtime library.</p>
+<p>5.Finally, we generate the executable program with <em>llc</em> or run the
+   optimized LLVM IRs with a JIT compiler like  <em>lli</em>.</p>
+<h2>Usage</h2>
+<p>1. Apply the llvm.codegen intrinsic patch to LLVM code base.</p>
+<pre>cd /path/to/llvm/source
+git am /path/to/polly/source/utils/0001-Add-llvm.codegen-intrinsic.patch</pre>
+<p>2. Build the test case.</p>
+<pre>/path/to/polly/source/test/create_ll.sh test.c</pre>
+<p>3. Get and edit the jscop file (take function "gpu_codegen" as an example).
+</p>
+<pre>opt -load /path/to/polly/build/lib/LLVMPolly.so -basicaa
+    -polly-export-jscop ./test.ll
+cp gpu_codegen___%for.cond---%for.end8.jscop
+   gpu_codegen___%for.cond---%for.end8.jscop.transformed+gpu
+vi gpu_codegen___%for.cond---%for.end8.jscop.transformed+gpu</pre>
+<p><em>(Please refer to section "The Work Flow" on how to edit the "schedule"
+       part of a statement)</em></p>
+<p>4. Optimize the code with GPGPU code generation.</p>
+<pre>opt -load /path/to/polly/build/lib/LLVMPolly.so -basicaa
+    -polly-import-jscop-postfix=transformed+gpu -enable-polly-gpgpu
+    -polly-gpgpu-triple=nvptx64-unknown-unknown -polly-codegen ./test.ll -S
+    -o test.gpued.ll</pre>
+<p>5. Build the final assembly and executable.</p>
+<pre>llc test.gpued.ll -o test.s
+gcc test.s -lGPURuntime -o test</pre>
+<p><em>(Please make sure that LD_LIBRARY_PATH is set properly so that
+        /path/to/polly/build/lib/libGPURuntime.so is visible to gcc.)</em></p>
+<h2>TODO List</h2>
+
+<table class="wikitable" cellpadding="2">
+<tbody>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Tasks</th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left">Tiling the Parallel Loops with An External Jscop File</th>
+<td align="center" class='open'>Open, In Design</td>
+<td>Yabin Hu</td>
+</tr>
+<tr>
+<th align="left">GPU Runtime Library Implementation</th>
+<td align="center" class='inprogress'>Coding Finished, In Reviewing</td>
+<td></td>
+</tr>
+<tr>
+<th align="left">llvm.codegen Intrinsic Implementation</th>
+<td align="center" class='inprogress'>Codeing Finished, To Be Reviewed</td>
+<td></td>
+</tr>
+<tr>
+<th align="left">Code Generation For Host</th>
+<td align="center" class='inprogress'>50% Done</td>
+<td></td>
+</tr>
+
+</tbody></table>
+
+<h2>References</h2>
+<li type="1" value="1">
+<em>Automatic C-to-CUDA Code Generation for Affine Programs. </em><br />
+    Muthu Manikandan Baskaran, J. Ramanujam and P. Sadayappan.<br />
+    International Conference on Compiler Construction (CC) 2010.<br />
+</li>
+<li type="1"><em>PPCG Project</em><br />
+<a href="http://freecode.com/projects/ppcg">http://freecode.com/projects/ppcg
+</a></li>
+<li type="1">
+<em>Where is the Data? Why You Cannot Debate GPU vs. CPU Performance Without the
+    Answer. </em><br />
+  Chris Gregg and Kim Hazelwood<br />
+  International Symposium on Performance Analysis of Systems and Software
+  (ISPASS) 2011.
+</li>
+<p></p>
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/documentation/memaccess.html b/rc1/www/documentation/memaccess.html
new file mode 100644
index 0000000..fa48771
--- /dev/null
+++ b/rc1/www/documentation/memaccess.html
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Memory access optimizations</title>
+  <link type="text/css" rel="stylesheet" href="../menu.css">
+  <link type="text/css" rel="stylesheet" href="../content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="../menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>Memory access optimizations</h1>
+  <!--*********************************************************************-->
+<p><em>WARNING: This project was part of the Google Summer of Code 2011.
+Tt is currently not finished, but it is in the design and implementation stage.
+The Ideas/Plans described here may not yet be implemented in Polly and may be
+changed during the actual implementation.</em></p>
+
+This project adds memory access transformations to Polly. In many cases
+changing the memory access pattern yields to better data locality or removes
+dependences that would otherwise block transformations.
+
+<p>An examples which uses this feature is given below.</p>
+
+Consider the following loop
+<pre>
+for (i = 0; i < 8; i++)
+  sum += A[i];
+</pre>
+Through memory access transformations this loop can be executed in parallel.
+It can be transformed to
+<pre>
+<em>// Create and initialize an array 'tmp' with size 4</em>
+for (i = 0; i < 8; i++)
+  tmp[i % 4] += A[i];
+sum = tmp[0] + tmp[1] + tmp[2] + tmp[3];
+</pre>
+
+Optimizers like PluTo can schedule the code such that an outer, parallel
+loop is created:
+<pre>
+parfor (ii = 0; ii < 4; ii++) {
+  tmp[ii] = 0;
+  for (i = ii * 2; i < (ii+1) * 2; i++)
+    tmp[ii] += A[i];
+  }
+sum = tmp[0] + tmp[1] + tmp[2] + tmp[3];
+</pre>
+
+<h2>TODO</h2>
+<h3>Step 1</h3>
+Polly exports its polyhedral description in a JSCoP file. Define how memory
+layout transformations are expressed in Polly and in the JSCOP file. 
+Example:
+
+<p>Consider the following loop.</p>
+<pre>
+for (i = 0; i < 12; i++)
+  A[i] = 0;
+</pre>
+In the JSCOP file the memory accesses are represented as follows.
+<pre>
+"accesses": [{
+        "kind": "write",
+                "relation": "{ Stmt[i] -> A[i] }"
+}]
+</pre>
+To perform a transformation we generate the following code:
+<pre>
+for (i = 0; i < 12; i++)
+  A[0] = i;
+</pre>
+The representation in the JSCoP file is:
+<pre>
+"accesses": [{
+        "kind": "read",
+                "relation": "{ Stmt[i] -> A[0] }"
+}]
+</pre>
+We need to detect this access function change.
+
+<h3>Step 2</h3>
+Update the code generation module to reflect the access function change made
+in Step 1.
+<h3>Step 2.1 Code generation for a constant</h3>
+In the JSCOP file an access function which has variables is changed to a
+constant. Code is generated to reflect this change. Let the content of original
+JSCOP file be:
+<pre>
+"accesses" : [{
+        "kind" : "read",
+                 "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
+}]
+</pre>
+The transformed JSCOP file is:
+<pre>
+"accesses" : [{
+        "kind" : "read",
+                 "relation" : "{ Stmt_for_body[i0] -> MemRef_A[10] }"
+}]
+</pre>
+Code is generated for this change.
+<h3>Step 2.2 Code generation for coefficients</h3>
+The coefficients of induction variables are changed here. Let the original
+JSCOP file be:
+<pre>
+"accesses" : [{
+      "kind" : "read",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[32i0+i1] }"
+}]
+</pre>
+The transformed JSCOP file is:
+<pre>
+"accesses" : [{
+      "kind" : "read",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[16i0+2i1+5] }"
+}]
+</pre>
+Code is generated for this change.
+</div>
+</div>
+</body>
+</html>
+
diff --git a/rc1/www/documentation/passes.html b/rc1/www/documentation/passes.html
new file mode 100644
index 0000000..f5ceb76
--- /dev/null
+++ b/rc1/www/documentation/passes.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - The available LLVM passes</title>
+  <link type="text/css" rel="stylesheet" href="../menu.css">
+  <link type="text/css" rel="stylesheet" href="../content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="../menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>The available LLVM passes</h1>
+  <!--*********************************************************************-->
+
+  <p>Polly consists of a set of LLVM passes.  </p>
+
+<h2>Front End</h2>
+<ul>
+<li><em>polly-prepare</em> Prepare code for Polly</li>
+<li><em>polly-detect</em> Detect SCoPs in functions</li>
+<li><em>polly-analyze-ir</em> Analyse the LLVM-IR in the detected SCoPs</li>
+<li><em>polly-independent</em> Create independent blocks</li>
+<li><em>polly-scops</em> Create polyhedral description of SCoPs</li>
+</ul>
+<h2>Middle End</h2>
+<ul>
+<li><em>polly-dependences</em> Calculate the dependences in a SCoPs</li>
+<li><em>polly-opt-pocc</em> Optimize the SCoP using PoCC</li>
+<li><em>polly-opt-isl</em> Optimize the SCoP using isl</li>
+<li>Import/Export
+<ul>
+<li><em>polly-export-cloog</em> Export the CLooG input file
+(Writes a .cloog file for each SCoP)</li>
+<li><em>polly-export-scoplib</em> Export SCoPs with ScopLib library
+(Writes a .scoplib file for each SCoP)</li>
+<li><em>polly-import-scoplib</em> Import SCoPs with ScopLib library
+(Reads a .scoplib file for each SCoP)</li>
+<li><em>polly-export-jscop</em> Export SCoPs as JSON
+(Writes a .jscop file for each SCoP)</li>
+<li><em>polly-import-jscop</em> Import SCoPs from JSON
+(Reads a .jscop file for each SCoP)</li>
+</ul>
+</li>
+<li>Graphviz
+<ul>
+<li><em>dot-scops</em> Print SCoPs of function</li>
+<li><em>dot-scops-only</em> Print SCoPs of function (without function bodies)</li>
+<li><em>view-scops</em> View SCoPs of function</li>
+<li><em>view-scops-only</em> View SCoPs of function (without function bodies)</li>
+</ul></li>
+</ul>
+<h2>Back End</h2>
+<ul>
+<li><em>polly-cloog</em> Execute CLooG code generation</li>
+<li><em>polly-codegen</em> Create LLVM-IR from the polyhedral information</li>
+</ul>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/example_load_Polly_into_clang.html b/rc1/www/example_load_Polly_into_clang.html
new file mode 100644
index 0000000..1fa7b71
--- /dev/null
+++ b/rc1/www/example_load_Polly_into_clang.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Load Polly into clang</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+<!--=====================================================================-->
+<h1>Load Polly into clang and automatically run it at -O3</h1>
+<!--=====================================================================-->
+
+<p><b>Warning:</b> Even though this example makes it very easy to use Polly,
+you should be aware that Polly is a young research project. It is expected
+to crash, produce invalid code or to hang in complex calculations even for
+simple examples. In case you see such a problem, please check the <a
+href="bugs.html">Bug database</a> and consider reporting a bug.
+<p>
+<b>Warning II:</b> clang/LLVM/Polly need to be in sync. This means
+            you need to compile them yourself from a recent svn/git checkout</b>
+<h2>Load Polly into clang</h2>
+
+By default Polly is configured as a shared library plugin that is loaded in
+tools like clang, opt, and bugpoint when they start their execution.
+
+By loading Polly into clang (or opt) the Polly options become automatically
+available. You can load Polly either by adding the relevant commands to
+the CPPFLAGS or by creating an alias.
+
+<pre class="code">
+$ export CPPFLAGS="-Xclang -load -Xclang ${POLLY_BUILD_DIR}/lib/LLVMPolly.so"
+</pre>
+
+or
+<pre class="code">
+$ alias pollycc clang -Xclang -load -Xclang ${POLLY_BUILD_DIR}/lib/LLVMPolly.so
+</pre>
+
+To avoid having to load Polly in the tools, Polly can optionally be configured
+with cmake to be statically linked in the tools:
+
+<pre class="code">
+$ cmake -D LINK_POLLY_INTO_TOOLS:Bool=ON
+</pre>
+
+<h2>Optimizing with Polly</h2>
+
+Optimizing with Polly is as easy as adding <b>-O3 -mllvm -polly</b> to your
+compiler flags (Polly is only available at -O3).
+
+<pre class="code">pollycc -O3 -mllvm -polly file.c</pre>
+
+<h2>Automatic OpenMP code generation</h2>
+
+To automatically detect parallel loops and generate OpenMP code for them you
+also need to add <b>-mllvm -enable-polly-openmp -lgomp</b> to your CFLAGS.
+
+<pre class="code">pollycc -O3 -mllvm -polly -mllvm -enable-polly-openmp -lgomp file.c</pre>
+
+<h2>Automatic Vector code generation</h2>
+
+Automatic vector code generation can be enabled by adding <b>-mllvm
+-polly-vectorizer=polly</b> to your CFLAGS.
+
+<pre class="code">pollycc -O3 -mllvm -polly -mllvm -polly-vectorizer=polly file.c</pre>
+
+<h2>Extract a preoptimized LLVM-IR file</h2>
+
+Often it is useful to derive from a C-file the LLVM-IR code that is actually
+optimized by Polly. Normally the LLVM-IR is automatically generated from
+the C code by first lowering C to LLVM-IR (clang) and by subsequently applying a
+set of preparing transformations on the LLVM-IR. To get the LLVM-IR after the
+preparing transformations have been applied run Polly with '-O0'.
+
+<pre class="code">pollycc -O0 -mllvm -polly -S -emit-llvm file.c</pre>
+
+<h2>Further options</h2>
+
+Polly supports further options that are mainly useful for the development or
+the
+analysis of Polly. The relevant options can be added to clang by appending
+<b>-mllvm -option-name</b> to the CFLAGS or the clang
+command line.
+
+<h3>Limit Polly to a single function</h3>
+To limit the execution of Polly to a single function, use the option
+<b>-polly-detect-only=functionname</b>.
+
+<h3>Disable LLVM-IR generation</h3>
+Polly normally regenerates LLVM-IR from the Polyhedral representation. To only
+see the effects of the preparing transformation, but to disable Polly code
+generation add the option <b>polly-no-codegen</b>.
+
+<h3>Graphical view of the SCoPs</h3>
+
+Polly can use graphviz to show the SCoPs it detects in a program. The relevant
+options are <b>-polly-show</b>, <b>-polly-show-only</b>, <b>-polly-dot</b> and
+<b>-polly-dot-only</b>. The 'show' options automatically run dotty or another
+graphviz viewer to show the scops graphically. The 'dot' options store for each
+function a dot file that highlights the detected SCoPs. If 'only' is appended at
+the end of the option, the basic blocks are shown without the statements the
+contain.
+
+<h3>Change/Disable the Optimizer</h3>
+Polly uses by default the isl scheduling optimizer. The isl optimizer optimizes
+for data-locality and parallelism using the <a
+href="http://pluto-compiler.sf.net">Pluto</a> algorithm. For research it is also
+possible to run <a
+href="http://www-rocq.inria.fr/~pouchet/software/pocc/">PoCC</a> as external
+optimizer. PoCC provides access to the original Pluto implementation. To use
+PoCC add <b>-polly-optimizer=pocc</b> to the command line (only available if
+Polly was compiled with scoplib support). To disable the
+optimizer entirely use the option <b>-polly-optimizer=none</b>.
+
+<h3>Disable tiling in the optimizer</h3>
+By default both optimizers perform tiling, if possible. In case this is not
+wanted the option <b>-polly-no-tiling</b> can be used to disable it. (This
+option disables tiling for both optimizers).
+
+<h3>Ignore possible aliasing</h3>
+By default we only detect scops, if we can prove that the different array bases
+can not alias. This is correct do if we optimize automatically.  However,
+without special user annotations like 'restrict' we can often not prove that
+no aliasing is possible. In case the user knows no aliasing can happen in the
+code the <b>-polly-ignore-aliasing</b> can be used to disable the check for
+possible aliasing.
+
+<h3>Import / Export</h3>
+The flags <b>-polly-import</b> and <b>-polly-export</b> allow the export and
+reimport of the polyhedral representation. By exporting, modifying and
+reimporting the polyhedral representation externally calculated transformations
+can be applied. This enables external optimizers or the manual optimization of
+specific SCoPs.
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/example_load_Polly_into_dragonegg.html b/rc1/www/example_load_Polly_into_dragonegg.html
new file mode 100644
index 0000000..ef9f68b
--- /dev/null
+++ b/rc1/www/example_load_Polly_into_dragonegg.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Load Polly into dragonegg</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+<!--=====================================================================-->
+<h1>Load Polly into dragonegg and automatically run it at -O3</h1>
+<!--=====================================================================-->
+
+<p><b>Note:</b>This is a quick note on how to load Polly into
+  dragonegg. The choice of front-end does not affect the passes
+  available with Polly, only the syntax is different.
+  The <a href="example_load_Polly_into_clang.html">examples for use
+  with clang</a> can also be performed with Polly, with suitable
+  corrections in the syntax.
+
+<h2>Compile dragonegg with support for LLVM plugins</h2>
+
+The support for LLVM plugins in dragonegg is still experimental, and
+hence protected by a build option. You must rebuild dragonegg with the
+following options:
+
+<pre class="code">
+$ GCC=${PATH_TO_GCC} LLVM_CONFIG=${PATH_TO_LLVM_CONFIG} ENABLE_LLVM_PLUGINS=1 make
+</pre>
+
+<h2>Load Polly into dragonegg</h2>
+
+By loading Polly into dragonegg, the Polly options become automatically
+available. You can load Polly either by adding the relevant commands to
+the CPPFLAGS or by creating an alias.
+
+<pre class="code">
+$ export CPPFLAGS="-fplugin=/path/to/dragonegg.so -fplugin-arg-dragonegg-llvm-option=-load:${POLLY_BUILD_DIR}/lib/LLVMPolly.so"
+</pre>
+
+or
+
+<pre class="code">
+$ alias pollycc gcc -fplugin=/path/to/dragonegg.so -fplugin-arg-dragonegg-llvm-option=-load:${POLLY_BUILD_DIR}/lib/LLVMPolly.so
+</pre>
+
+<h2>Optimizing with Polly</h2>
+
+Optimizing with Polly is as easy as adding <b>-O3 -fplugin-arg-dragonegg-llvm-option=-polly</b> to your
+compiler flags (Polly is only available at -O3).
+
+<pre class="code">pollycc -O3 -fplugin-arg-dragonegg-llvm-option=-polly file.c</pre>
+
+<h2>Passing various options to Polly</h2>
+
+As must be evident from the examples so far, options to LLVM and its
+plugins are passed via the <b>-fplugin-arg-dragonegg-llvm-option</b>
+commandline argment.
+The <a href="example_load_Polly_into_clang.html">examples for use with
+clang</a> can be executed with dragonegg by replacing
+the <b>-mllvm</b> syntax with the dragonegg syntax.
+
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/example_manual_matmul.html b/rc1/www/example_manual_matmul.html
new file mode 100644
index 0000000..f71e53a
--- /dev/null
+++ b/rc1/www/example_manual_matmul.html
@@ -0,0 +1,454 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Examples</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+<!--=====================================================================-->
+<h1>Execute the individual Polly passes manually</h1>
+<!--=====================================================================-->
+
+<p>
+This example presents the individual passes that are involved when optimizing
+code with Polly. We show how to execute them individually and explain for each
+which analysis is performed or what transformation is applied. In this example
+the polyhedral transformation is user-provided to show how much performance
+improvement can be expected by an optimal automatic optimizer.</p>
+
+The files used and created in this example are available in the Polly checkout
+in the folder <em>www/experiments/matmul</em>. They can be created automatically
+by running the <em>www/experiments/matmul/runall.sh</em> script.
+
+<ol>
+<li><h4>Create LLVM-IR from the C code</h4>
+
+Polly works on LLVM-IR. Hence it is necessary to translate the source files into
+LLVM-IR. If more than on file should be optimized the files can be combined into
+a single file with llvm-link.
+
+<pre class="code">clang -S -emit-llvm matmul.c -o matmul.s</pre>
+</li>
+
+
+<li><h4>Load Polly automatically when calling the 'opt' tool</h4>
+
+Polly is not built into opt or bugpoint, but it is a shared library that needs
+to be loaded into these tools explicitally. The Polly library is called
+LVMPolly.so. For a cmake build it is available in the build/lib/ directory,
+autoconf creates the same file in
+build/tools/polly/{Release+Asserts|Asserts|Debug}/lib. For convenience we create
+an alias that automatically loads Polly if 'opt' is called.
+<pre class="code">
+export PATH_TO_POLLY_LIB="~/polly/build/lib/"
+alias opt="opt -load ${PATH_TO_POLLY_LIB}/LLVMPolly.so"</pre>
+</li>
+
+<li><h4>Prepare the LLVM-IR for Polly</h4>
+
+Polly is only able to work with code that matches a canonical form. To translate
+the LLVM-IR into this form we use a set of canonicalication passes. They are
+scheduled by using '-polly-canonicalize'.
+<pre class="code">opt -S -polly-canonicalize matmul.s &gt; matmul.preopt.ll</pre></li>
+
+<li><h4>Show the SCoPs detected by Polly (optional)</h4>
+
+To understand if Polly was able to detect SCoPs, we print the
+structure of the detected SCoPs. In our example two SCoPs were detected. One in
+'init_array' the other in 'main'.
+
+<pre class="code">opt -basicaa -polly-cloog -analyze -q matmul.preopt.ll</pre>
+
+<pre>
+init_array():
+for (c2=0;c2&lt;=1023;c2++) {
+  for (c4=0;c4&lt;=1023;c4++) {
+    Stmt_5(c2,c4);
+  }
+}
+
+main():
+for (c2=0;c2&lt;=1023;c2++) {
+  for (c4=0;c4&lt;=1023;c4++) {
+    Stmt_4(c2,c4);
+    for (c6=0;c6&lt;=1023;c6++) {
+      Stmt_6(c2,c4,c6);
+    }
+  }
+}
+</pre>
+</li>
+<li><h4>Highlight the detected SCoPs in the CFGs of the program (requires graphviz/dotty)</h4>
+
+Polly can use graphviz to graphically show a CFG in which the detected SCoPs are
+highlighted. It can also create '.dot' files that can be translated by
+the 'dot' utility into various graphic formats.
+
+<pre class="code">opt -basicaa -view-scops -disable-output matmul.preopt.ll
+opt -basicaa -view-scops-only -disable-output matmul.preopt.ll</pre>
+The output for the different functions<br />
+view-scops:
+<a href="experiments/matmul/scops.main.dot.png">main</a>,
+<a href="experiments/matmul/scops.init_array.dot.png">init_array</a>,
+<a href="experiments/matmul/scops.print_array.dot.png">print_array</a><br />
+view-scops-only:
+<a href="experiments/matmul/scopsonly.main.dot.png">main</a>,
+<a href="experiments/matmul/scopsonly.init_array.dot.png">init_array</a>,
+<a href="experiments/matmul/scopsonly.print_array.dot.png">print_array</a>
+</li>
+
+<li><h4>View the polyhedral representation of the SCoPs</h4>
+<pre class="code">opt -basicaa -polly-scops -analyze matmul.preopt.ll</pre>
+<pre>
+[...]
+Printing analysis 'Polly - Create polyhedral description of Scops' for region:
+'for.cond =&gt; for.end19' in function 'init_array':
+   Context:
+   { [] }
+   Statements {
+   	Stmt_5
+           Domain&nbsp;:=
+               { Stmt_5[i0, i1]&nbsp;: i0 &gt;= 0 and i0 &lt;= 1023 and i1 &gt;= 0 and i1 &lt;= 1023 };
+           Scattering&nbsp;:=
+               { Stmt_5[i0, i1] -&gt; scattering[0, i0, 0, i1, 0] };
+           WriteAccess&nbsp;:= 
+               { Stmt_5[i0, i1] -&gt; MemRef_A[1037i0 + i1] };
+           WriteAccess&nbsp;:= 
+               { Stmt_5[i0, i1] -&gt; MemRef_B[1047i0 + i1] };
+   	FinalRead
+           Domain&nbsp;:=
+               { FinalRead[0] };
+           Scattering&nbsp;:=
+               { FinalRead[i0] -&gt; scattering[200000000, o1, o2, o3, o4] };
+           ReadAccess&nbsp;:= 
+               { FinalRead[i0] -&gt; MemRef_A[o0] };
+           ReadAccess&nbsp;:= 
+               { FinalRead[i0] -&gt; MemRef_B[o0] };
+   }
+[...]
+Printing analysis 'Polly - Create polyhedral description of Scops' for region:
+'for.cond =&gt; for.end30' in function 'main':
+   Context:
+   { [] }
+   Statements {
+   	Stmt_4
+           Domain&nbsp;:=
+               { Stmt_4[i0, i1]&nbsp;: i0 &gt;= 0 and i0 &lt;= 1023 and i1 &gt;= 0 and i1 &lt;= 1023 };
+           Scattering&nbsp;:=
+               { Stmt_4[i0, i1] -&gt; scattering[0, i0, 0, i1, 0, 0, 0] };
+           WriteAccess&nbsp;:= 
+               { Stmt_4[i0, i1] -&gt; MemRef_C[1067i0 + i1] };
+   	Stmt_6
+           Domain&nbsp;:=
+               { Stmt_6[i0, i1, i2]&nbsp;: i0 &gt;= 0 and i0 &lt;= 1023 and i1 &gt;= 0 and i1 &lt;= 1023 and i2 &gt;= 0 and i2 &lt;= 1023 };
+           Scattering&nbsp;:=
+               { Stmt_6[i0, i1, i2] -&gt; scattering[0, i0, 0, i1, 1, i2, 0] };
+           ReadAccess&nbsp;:= 
+               { Stmt_6[i0, i1, i2] -&gt; MemRef_C[1067i0 + i1] };
+           ReadAccess&nbsp;:= 
+               { Stmt_6[i0, i1, i2] -&gt; MemRef_A[1037i0 + i2] };
+           ReadAccess&nbsp;:= 
+               { Stmt_6[i0, i1, i2] -&gt; MemRef_B[i1 + 1047i2] };
+           WriteAccess&nbsp;:= 
+               { Stmt_6[i0, i1, i2] -&gt; MemRef_C[1067i0 + i1] };
+   	FinalRead
+           Domain&nbsp;:=
+               { FinalRead[0] };
+           Scattering&nbsp;:=
+               { FinalRead[i0] -&gt; scattering[200000000, o1, o2, o3, o4, o5, o6] };
+           ReadAccess&nbsp;:= 
+               { FinalRead[i0] -&gt; MemRef_C[o0] };
+           ReadAccess&nbsp;:= 
+               { FinalRead[i0] -&gt; MemRef_A[o0] };
+           ReadAccess&nbsp;:= 
+               { FinalRead[i0] -&gt; MemRef_B[o0] };
+   }
+[...]
+</pre>
+</li>
+
+<li><h4>Show the dependences for the SCoPs</h4>
+<pre class="code">opt -basicaa -polly-dependences -analyze matmul.preopt.ll</pre>
+<pre>Printing analysis 'Polly - Calculate dependences for SCoP' for region:
+'for.cond =&gt; for.end19' in function 'init_array':
+   Must dependences:
+       {  }
+   May dependences:
+       {  }
+   Must no source:
+       {  }
+   May no source:
+       {  }
+Printing analysis 'Polly - Calculate dependences for SCoP' for region:
+'for.cond =&gt; for.end30' in function 'main':
+   Must dependences:
+       {  Stmt_4[i0, i1] -&gt; Stmt_6[i0, i1, 0]&nbsp;:
+              i0 &gt;= 0 and i0 &lt;= 1023 and i1 &gt;= 0 and i1 &lt;= 1023;
+          Stmt_6[i0, i1, i2] -&gt; Stmt_6[i0, i1, 1 + i2]&nbsp;:
+              i0 &gt;= 0 and i0 &lt;= 1023 and i1 &gt;= 0 and i1 &lt;= 1023 and i2 &gt;= 0 and i2 &lt;= 1022; 
+          Stmt_6[i0, i1, 1023] -&gt; FinalRead[0]&nbsp;:
+              i1 &lt;= 1091540 - 1067i0 and i1 &gt;= -1067i0 and i1 &gt;= 0 and i1 &lt;= 1023;
+          Stmt_6[1023, i1, 1023] -&gt; FinalRead[0]&nbsp;:
+              i1 &gt;= 0 and i1 &lt;= 1023 
+       }
+   May dependences:
+       {  }
+   Must no source:
+       {  Stmt_6[i0, i1, i2] -&gt; MemRef_A[1037i0 + i2]&nbsp;:
+              i0 &gt;= 0 and i0 &lt;= 1023 and i1 &gt;= 0 and i1 &lt;= 1023 and i2 &gt;= 0 and i2 &lt;= 1023; 
+          Stmt_6[i0, i1, i2] -&gt; MemRef_B[i1 + 1047i2]&nbsp;:
+              i0 &gt;= 0 and i0 &lt;= 1023 and i1 &gt;= 0 and i1 &lt;= 1023 and i2 &gt;= 0 and i2 &lt;= 1023; 
+          FinalRead[0] -&gt; MemRef_A[o0];
+          FinalRead[0] -&gt; MemRef_B[o0]
+          FinalRead[0] -&gt; MemRef_C[o0]&nbsp;:
+              o0 &gt;= 1092565 or (exists (e0 = [(o0)/1067]: o0 &lt;= 1091540 and o0 &gt;= 0
+              and 1067e0 &lt;= -1024 + o0 and 1067e0 &gt;= -1066 + o0)) or o0 &lt;= -1;
+       }
+   May no source:
+       {  }
+</pre></li>
+
+<li><h4>Export jscop files</h4>
+
+Polly can export the polyhedral representation in so called jscop files. Jscop
+files contain the polyhedral representation stored in a JSON file.
+<pre class="code">opt -basicaa -polly-export-jscop matmul.preopt.ll</pre>
+<pre>Writing SCoP 'for.cond =&gt; for.end19' in function 'init_array' to './init_array___%for.cond---%for.end19.jscop'.
+Writing SCoP 'for.cond =&gt; for.end30' in function 'main' to './main___%for.cond---%for.end30.jscop'.
+</pre></li>
+
+<li><h4>Import the changed jscop files and print the updated SCoP structure
+(optional)</h4>
+<p>Polly can reimport jscop files, in which the schedules of the statements are
+changed. These changed schedules are used to descripe transformations.
+It is possible to import different jscop files by providing the postfix
+of the jscop file that is imported.</p>
+<p> We apply three different transformations on the SCoP in the main function.
+The jscop files describing these transformations are hand written (and available
+in <em>www/experiments/matmul</em>).
+
+<h5>No Polly</h5>
+
+<p>As a baseline we do not call any Polly code generation, but only apply the
+normal -O3 optimizations.</p>
+
+<pre class="code">
+opt matmul.preopt.ll -basicaa \
+    -polly-import-jscop \
+    -polly-cloog -analyze
+</pre>
+<pre>
+[...]
+main():
+for (c2=0;c2&ltg;=1535;c2++) {
+  for (c4=0;c4&ltg;=1535;c4++) {
+    Stmt_4(c2,c4);
+    for (c6=0;c6&ltg;=1535;c6++) {
+      Stmt_6(c2,c4,c6);
+    }
+  }
+}
+[...]
+</pre>
+<h5>Interchange (and Fission to allow the interchange)</h5>
+<p>We split the loops and can now apply an interchange of the loop dimensions that
+enumerate Stmt_6.</p>
+<pre class="code">
+opt matmul.preopt.ll -basicaa \
+    -polly-import-jscop -polly-import-jscop-postfix=interchanged \
+    -polly-cloog -analyze
+</pre>
+<pre>
+[...]
+Reading JScop 'for.cond =&gt; for.end30' in function 'main' from './main___%for.cond---%for.end30.jscop.interchanged+tiled'.
+[...]
+main():
+for (c2=0;c2&lt;=1535;c2++) {
+  for (c4=0;c4&lt;=1535;c4++) {
+    Stmt_4(c2,c4);
+  }
+}
+for (c2=0;c2&lt;=1535;c2++) {
+  for (c4=0;c4&lt;=1535;c4++) {
+    for (c6=0;c6&lt;=1535;c6++) {
+      Stmt_6(c2,c6,c4);
+    }
+  }
+}
+[...]
+</pre>
+<h5>Interchange + Tiling</h5>
+<p>In addition to the interchange we tile now the second loop nest.</p>
+
+<pre class="code">
+opt matmul.preopt.ll -basicaa \
+    -polly-import-jscop -polly-import-jscop-postfix=interchanged+tiled \
+    -polly-cloog -analyze
+</pre>
+<pre>
+[...]
+Reading JScop 'for.cond =&gt; for.end30' in function 'main' from './main___%for.cond---%for.end30.jscop.interchanged+tiled'.
+[...]
+main():
+for (c2=0;c2&lt;=1535;c2++) {
+  for (c4=0;c4&lt;=1535;c4++) {
+    Stmt_4(c2,c4);
+  }
+}
+for (c2=0;c2&lt;=1535;c2+=64) {
+  for (c3=0;c3&lt;=1535;c3+=64) {
+    for (c4=0;c4&lt;=1535;c4+=64) {
+      for (c5=c2;c5&lt;=c2+63;c5++) {
+        for (c6=c4;c6&lt;=c4+63;c6++) {
+          for (c7=c3;c7&lt;=c3+63;c7++) {
+            Stmt_6(c5,c7,c6);
+          }
+        }
+      }
+    }
+  }
+}
+[...]
+</pre>
+<h5>Interchange + Tiling + Strip-mining to prepare vectorization</h5>
+To later allow vectorization we create a so called trivially parallelizable
+loop. It is innermost, parallel and has only four iterations. It can be
+replaced by 4-element SIMD instructions.
+<pre class="code">
+opt matmul.preopt.ll -basicaa \
+    -polly-import-jscop -polly-import-jscop-postfix=interchanged+tiled+vector \
+    -polly-cloog -analyze </pre>
+
+<pre>
+[...]
+Reading JScop 'for.cond =&gt; for.end30' in function 'main' from './main___%for.cond---%for.end30.jscop.interchanged+tiled+vector'.
+[...]
+main():
+for (c2=0;c2&lt;=1535;c2++) {
+  for (c4=0;c4&lt;=1535;c4++) {
+    Stmt_4(c2,c4);
+  }
+}
+for (c2=0;c2&lt;=1535;c2+=64) {
+  for (c3=0;c3&lt;=1535;c3+=64) {
+    for (c4=0;c4&lt;=1535;c4+=64) {
+      for (c5=c2;c5&lt;=c2+63;c5++) {
+        for (c6=c4;c6&lt;=c4+63;c6++) {
+          for (c7=c3;c7&lt;=c3+63;c7+=4) {
+            for (c8=c7;c8&lt;=c7+3;c8++) {
+              Stmt_6(c5,c8,c6);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+[...]
+</pre>
+
+</li>
+
+<li><h4>Codegenerate the SCoPs</h4>
+<p>
+This generates new code for the SCoPs detected by polly.
+If -polly-import-jscop is present, transformations specified in the imported
+jscop files will be applied.</p>
+<pre class="code">opt matmul.preopt.ll | opt -O3 &gt; matmul.normalopt.ll</pre>
+<pre class="code">
+opt -basicaa \
+    -polly-import-jscop -polly-import-jscop-postfix=interchanged \
+    -polly-codegen matmul.preopt.ll \
+   | opt -O3 &gt; matmul.polly.interchanged.ll</pre>
+<pre>
+Reading JScop 'for.cond =&gt; for.end19' in function 'init_array' from
+    './init_array___%for.cond---%for.end19.jscop.interchanged'.
+File could not be read: No such file or directory
+Reading JScop 'for.cond =&gt; for.end30' in function 'main' from
+    './main___%for.cond---%for.end30.jscop.interchanged'.
+</pre>
+<pre class="code">
+opt -basicaa \
+    -polly-import-jscop -polly-import-jscop-postfix=interchanged+tiled \
+    -polly-codegen matmul.preopt.ll \
+   | opt -O3 &gt; matmul.polly.interchanged+tiled.ll</pre>
+<pre>
+Reading JScop 'for.cond =&gt; for.end19' in function 'init_array' from
+    './init_array___%for.cond---%for.end19.jscop.interchanged+tiled'.
+File could not be read: No such file or directory
+Reading JScop 'for.cond =&gt; for.end30' in function 'main' from
+    './main___%for.cond---%for.end30.jscop.interchanged+tiled'.
+</pre>
+<pre class="code">
+opt -basicaa \
+    -polly-import-jscop -polly-import-jscop-postfix=interchanged+tiled+vector \
+    -polly-codegen -polly-vectorizer=polly matmul.preopt.ll \
+   | opt -O3 &gt; matmul.polly.interchanged+tiled+vector.ll</pre>
+<pre>
+Reading JScop 'for.cond =&gt; for.end19' in function 'init_array' from
+    './init_array___%for.cond---%for.end19.jscop.interchanged+tiled+vector'.
+File could not be read: No such file or directory
+Reading JScop 'for.cond =&gt; for.end30' in function 'main' from
+    './main___%for.cond---%for.end30.jscop.interchanged+tiled+vector'.
+</pre>
+<pre class="code">
+opt -basicaa \
+    -polly-import-jscop -polly-import-jscop-postfix=interchanged+tiled+vector \
+    -polly-codegen -polly-vectorizer=polly -enable-polly-openmp matmul.preopt.ll \
+  | opt -O3 &gt; matmul.polly.interchanged+tiled+openmp.ll</pre>
+<pre>
+Reading JScop 'for.cond =&gt; for.end19' in function 'init_array' from
+    './init_array___%for.cond---%for.end19.jscop.interchanged+tiled+vector'.
+File could not be read: No such file or directory
+Reading JScop 'for.cond =&gt; for.end30' in function 'main' from
+    './main___%for.cond---%for.end30.jscop.interchanged+tiled+vector'.
+</pre>
+
+<li><h4>Create the executables</h4>
+
+Create one executable optimized with plain -O3 as well as a set of executables
+optimized in different ways with Polly. One changes only the loop structure, the
+other adds tiling, the next adds vectorization and finally we use OpenMP
+parallelism.
+<pre class="code">
+llc matmul.normalopt.ll -o matmul.normalopt.s &amp;&amp; \
+    gcc matmul.normalopt.s -o matmul.normalopt.exe
+llc matmul.polly.interchanged.ll -o matmul.polly.interchanged.s &amp;&amp; \
+    gcc matmul.polly.interchanged.s -o matmul.polly.interchanged.exe
+llc matmul.polly.interchanged+tiled.ll -o matmul.polly.interchanged+tiled.s &amp;&amp; \
+    gcc matmul.polly.interchanged+tiled.s -o matmul.polly.interchanged+tiled.exe
+llc matmul.polly.interchanged+tiled+vector.ll -o matmul.polly.interchanged+tiled+vector.s &amp;&amp; \
+    gcc matmul.polly.interchanged+tiled+vector.s -o matmul.polly.interchanged+tiled+vector.exe
+llc matmul.polly.interchanged+tiled+vector+openmp.ll -o matmul.polly.interchanged+tiled+vector+openmp.s &amp;&amp; \
+    gcc -lgomp matmul.polly.interchanged+tiled+vector+openmp.s -o matmul.polly.interchanged+tiled+vector+openmp.exe </pre>
+
+<li><h4>Compare the runtime of the executables</h4>
+
+By comparing the runtimes of the different code snippets we see that a simple
+loop interchange gives here the largest performance boost. However by adding
+vectorization and by using OpenMP we can further improve the performance
+significantly.
+<pre class="code">time ./matmul.normalopt.exe</pre>
+<pre>42.68 real, 42.55 user, 0.00 sys</pre>
+<pre class="code">time ./matmul.polly.interchanged.exe</pre>
+<pre>04.33 real, 4.30 user, 0.01 sys</pre>
+<pre class="code">time ./matmul.polly.interchanged+tiled.exe</pre>
+<pre>04.11 real, 4.10 user, 0.00 sys</pre>
+<pre class="code">time ./matmul.polly.interchanged+tiled+vector.exe</pre>
+<pre>01.39 real, 1.36 user, 0.01 sys</pre>
+<pre class="code">time ./matmul.polly.interchanged+tiled+vector+openmp.exe</pre>
+<pre>00.66 real, 2.58 user, 0.02 sys</pre>
+</li>
+</ol>
+
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/examples.html b/rc1/www/examples.html
new file mode 100644
index 0000000..c8ceb65
--- /dev/null
+++ b/rc1/www/examples.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Examples</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+  <meta http-equiv="REFRESH"
+  content="0;url=documentation.html"></HEAD>
+</head>
+<body>
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+<!--=====================================================================-->
+<h1>Polly: Examples</h1>
+<!--=====================================================================-->
+
+</div>
+</body>
+</html>
diff --git a/rc1/www/experiments/matmul/init_array___%for.cond---%for.end19.jscop b/rc1/www/experiments/matmul/init_array___%for.cond---%for.end19.jscop
new file mode 100644
index 0000000..dfd1093
--- /dev/null
+++ b/rc1/www/experiments/matmul/init_array___%for.cond---%for.end19.jscop
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end19",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_A[1536i0 + i1] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_B[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 1535 and i1 >= 0 and i1 <= 1535 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0] }"
+      }
+   ]
+}
diff --git a/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop
new file mode 100644
index 0000000..4d6e463
--- /dev/null
+++ b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop
@@ -0,0 +1,40 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end30",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body3[i0, i1] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body3[i0, i1] : i0 >= 0 and i0 <= 1535 and i1 >= 0 and i1 <= 1535 }",
+         "name" : "Stmt_for_body3",
+         "schedule" : "{ Stmt_for_body3[i0, i1] -> scattering[0, i0, 0, i1, 0, 0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body8[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body8[i0, i1, i2] -> MemRef_A[1536i0 + i2] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body8[i0, i1, i2] -> MemRef_B[i1 + 1536i2] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body8[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body8[i0, i1, i2] : i0 >= 0 and i0 <= 1535 and i1 >= 0 and i1 <= 1535 and i2 >= 0 and i2 <= 1535 }",
+         "name" : "Stmt_for_body8",
+         "schedule" : "{ Stmt_for_body8[i0, i1, i2] -> scattering[0, i0, 0, i1, 1, i2, 0] }"
+      }
+   ]
+}
diff --git a/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged
new file mode 100644
index 0000000..1d73c8a
--- /dev/null
+++ b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged
@@ -0,0 +1,40 @@
+{
+   "context" : "{ [] }",
+   "name" : "%1 => %17",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_4[i0, i1] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_4[i0, i1] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_4",
+         "schedule" : "{ Stmt_4[i0, i1] -> scattering[0, i0, 0, i1, 0, 0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_A[1536i0 + i2] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_B[i1 + 1536i2] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_6[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+         "name" : "Stmt_6",
+         "schedule" : "{ Stmt_6[i0, i1, i2] -> scattering[1, i0, 0, i2, 0, i1, 0] }"
+      }
+   ]
+}
diff --git a/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged+tiled b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged+tiled
new file mode 100644
index 0000000..ab68b5e
--- /dev/null
+++ b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged+tiled
@@ -0,0 +1,40 @@
+{
+   "context" : "{ [] }",
+   "name" : "%1 => %17",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_4[i0, i1] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_4[i0, i1] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_4",
+         "schedule" : "{ Stmt_4[i0, i1] -> scattering[0, i0, 0, i1, 0, 0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_A[1536i0 + i2] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_B[i1 + 1536i2] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_6[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+         "name" : "Stmt_6",
+         "schedule" : "{ Stmt_6[i0, i1, i2] -> scattering[1, o0, o1, o2, i0, i2, i1]: o0 <= i0 < o0 + 64 and o1 <= i1 < o1 + 64 and o2 <= i2 < o2 + 64 and o0 % 64 = 0 and o1 % 64 = 0 and o2 % 64 = 0 }"
+      }
+   ]
+}
diff --git a/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged+tiled+vector b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged+tiled+vector
new file mode 100644
index 0000000..67a1cd9
--- /dev/null
+++ b/rc1/www/experiments/matmul/main___%for.cond---%for.end30.jscop.interchanged+tiled+vector
@@ -0,0 +1,40 @@
+{
+   "context" : "{ [] }",
+   "name" : "%1 => %17",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_4[i0, i1] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_4[i0, i1] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 }",
+         "name" : "Stmt_4",
+         "schedule" : "{ Stmt_4[i0, i1] -> scattering[0, i0, 0, i1, 0, 0, 0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_A[1536i0 + i2] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_B[i1 + 1536i2] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_6[i0, i1, i2] -> MemRef_C[1536i0 + i1] }"
+            }
+         ],
+         "domain" : "{ Stmt_6[i0, i1, i2] : i0 >= 0 and i0 <= 1023 and i1 >= 0 and i1 <= 1023 and i2 >= 0 and i2 <= 1023 }",
+         "name" : "Stmt_6",
+         "schedule" : "{ Stmt_6[i0, i1, i2] -> scattering[1, o0, o1, o2, i0, i2, ii1, i1]: o0 <= i0 < o0 + 64 and o1 <= i1 < o1 + 64 and o2 <= i2 < o2 + 64 and o0 % 64 = 0 and o1 % 64 = 0 and o2 % 64 = 0 and ii1 % 4 = 0 and ii1 <= i1 < ii1 + 4}"
+      }
+   ]
+}
diff --git a/rc1/www/experiments/matmul/matmul.c b/rc1/www/experiments/matmul/matmul.c
new file mode 100644
index 0000000..edb2455
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+#define N 1536
+float A[N][N];
+float B[N][N];
+float C[N][N];
+
+void init_array()
+{
+    int i, j;
+
+    for (i=0; i<N; i++) {
+        for (j=0; j<N; j++) {
+            A[i][j] = (1+(i*j)%1024)/2.0;
+            B[i][j] = (1+(i*j)%1024)/2.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");
+    }
+}
+
+int main()
+{
+    int i, j, k;
+    double t_start, t_end;
+
+    init_array();
+
+    for(i=0; i<N; i++)  {
+        for(j=0; j<N; j++)  {
+            C[i][j] = 0;
+            for(k=0; k<N; k++)
+                C[i][j] = C[i][j] + A[i][k] * B[k][j];
+        }
+    }
+
+#ifdef TEST
+    print_array();
+#endif
+    return 0;
+}
diff --git a/rc1/www/experiments/matmul/matmul.normalopt.exe b/rc1/www/experiments/matmul/matmul.normalopt.exe
new file mode 100755
index 0000000..cdb9e67
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.normalopt.exe
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.normalopt.ll b/rc1/www/experiments/matmul/matmul.normalopt.ll
new file mode 100644
index 0000000..ba792c2
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.normalopt.ll
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.normalopt.s b/rc1/www/experiments/matmul/matmul.normalopt.s
new file mode 100644
index 0000000..079af70
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.normalopt.s
@@ -0,0 +1,274 @@
+	.file	"matmul.normalopt.ll"
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI0_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	init_array
+	.align	16, 0x90
+	.type	init_array,@function
+init_array:                             # @init_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp2:
+	.cfi_def_cfa_offset 16
+.Ltmp3:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp4:
+	.cfi_def_cfa_register %rbp
+	xorl	%r8d, %r8d
+	vmovsd	.LCPI0_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB0_1:                                # %for.cond1.preheader
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB0_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB0_2:                                # %for.body3
+                                        #   Parent Loop BB0_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%r8d, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%r8, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB0_2
+# BB#3:                                 # %for.inc17
+                                        #   in Loop: Header=BB0_1 Depth=1
+	incq	%r8
+	cmpq	$1536, %r8              # imm = 0x600
+	jne	.LBB0_1
+# BB#4:                                 # %for.end19
+	popq	%rbp
+	ret
+.Ltmp5:
+	.size	init_array, .Ltmp5-init_array
+	.cfi_endproc
+
+	.globl	print_array
+	.align	16, 0x90
+	.type	print_array,@function
+print_array:                            # @print_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp9:
+	.cfi_def_cfa_offset 16
+.Ltmp10:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp11:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r12
+	pushq	%rbx
+.Ltmp12:
+	.cfi_offset %rbx, -48
+.Ltmp13:
+	.cfi_offset %r12, -40
+.Ltmp14:
+	.cfi_offset %r14, -32
+.Ltmp15:
+	.cfi_offset %r15, -24
+	xorl	%r14d, %r14d
+	movl	$C, %r15d
+	.align	16, 0x90
+.LBB1_1:                                # %for.cond1.preheader
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB1_2 Depth 2
+	movq	stdout(%rip), %rax
+	movq	%r15, %r12
+	xorl	%ebx, %ebx
+	.align	16, 0x90
+.LBB1_2:                                # %for.body3
+                                        #   Parent Loop BB1_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	vmovss	(%r12), %xmm0
+	vcvtss2sd	%xmm0, %xmm0, %xmm0
+	movq	%rax, %rdi
+	movl	$.L.str, %esi
+	movb	$1, %al
+	callq	fprintf
+	movslq	%ebx, %rax
+	imulq	$1717986919, %rax, %rcx # imm = 0x66666667
+	movq	%rcx, %rdx
+	shrq	$63, %rdx
+	sarq	$37, %rcx
+	addl	%edx, %ecx
+	imull	$80, %ecx, %ecx
+	subl	%ecx, %eax
+	cmpl	$79, %eax
+	jne	.LBB1_4
+# BB#3:                                 # %if.then
+                                        #   in Loop: Header=BB1_2 Depth=2
+	movq	stdout(%rip), %rsi
+	movl	$10, %edi
+	callq	fputc
+.LBB1_4:                                # %for.inc
+                                        #   in Loop: Header=BB1_2 Depth=2
+	addq	$4, %r12
+	incq	%rbx
+	movq	stdout(%rip), %rax
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB1_2
+# BB#5:                                 # %for.end
+                                        #   in Loop: Header=BB1_1 Depth=1
+	movl	$10, %edi
+	movq	%rax, %rsi
+	callq	fputc
+	addq	$6144, %r15             # imm = 0x1800
+	incq	%r14
+	cmpq	$1536, %r14             # imm = 0x600
+	jne	.LBB1_1
+# BB#6:                                 # %for.end12
+	popq	%rbx
+	popq	%r12
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp16:
+	.size	print_array, .Ltmp16-print_array
+	.cfi_endproc
+
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI2_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	main
+	.align	16, 0x90
+	.type	main,@function
+main:                                   # @main
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp19:
+	.cfi_def_cfa_offset 16
+.Ltmp20:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp21:
+	.cfi_def_cfa_register %rbp
+	xorl	%r8d, %r8d
+	vmovsd	.LCPI2_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB2_1:                                # %for.cond1.preheader.i
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB2_2:                                # %for.body3.i
+                                        #   Parent Loop BB2_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%r8d, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%r8, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB2_2
+# BB#3:                                 # %for.inc17.i
+                                        #   in Loop: Header=BB2_1 Depth=1
+	incq	%r8
+	cmpq	$1536, %r8              # imm = 0x600
+	jne	.LBB2_1
+# BB#4:
+	xorl	%r8d, %r8d
+	movl	$A, %r9d
+	.align	16, 0x90
+.LBB2_5:                                # %for.cond1.preheader
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_6 Depth 2
+                                        #       Child Loop BB2_7 Depth 3
+	leaq	(%r8,%r8,2), %rdx
+	shlq	$11, %rdx
+	leaq	C(%rdx), %rsi
+	xorl	%edi, %edi
+	.align	16, 0x90
+.LBB2_6:                                # %for.body3
+                                        #   Parent Loop BB2_5 Depth=1
+                                        # =>  This Loop Header: Depth=2
+                                        #       Child Loop BB2_7 Depth 3
+	movl	$0, (%rsi)
+	vxorps	%xmm0, %xmm0, %xmm0
+	movq	$-9437184, %rax         # imm = 0xFFFFFFFFFF700000
+	movq	%r9, %rcx
+	.align	16, 0x90
+.LBB2_7:                                # %for.body8
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_6 Depth=2
+                                        # =>    This Inner Loop Header: Depth=3
+	vmovss	(%rcx), %xmm1
+	vmulss	B+9437184(%rax,%rdi,4), %xmm1, %xmm1
+	vaddss	%xmm1, %xmm0, %xmm0
+	addq	$4, %rcx
+	addq	$6144, %rax             # imm = 0x1800
+	jne	.LBB2_7
+# BB#8:                                 # %for.inc25
+                                        #   in Loop: Header=BB2_6 Depth=2
+	vmovss	%xmm0, (%rsi)
+	leaq	C+4(%rdx,%rdi,4), %rsi
+	incq	%rdi
+	cmpq	$1536, %rdi             # imm = 0x600
+	jne	.LBB2_6
+# BB#9:                                 # %for.inc28
+                                        #   in Loop: Header=BB2_5 Depth=1
+	addq	$6144, %r9              # imm = 0x1800
+	incq	%r8
+	cmpq	$1536, %r8              # imm = 0x600
+	jne	.LBB2_5
+# BB#10:                                # %for.end30
+	xorl	%eax, %eax
+	popq	%rbp
+	ret
+.Ltmp22:
+	.size	main, .Ltmp22-main
+	.cfi_endproc
+
+	.type	A,@object               # @A
+	.comm	A,9437184,16
+	.type	B,@object               # @B
+	.comm	B,9437184,16
+	.type	.L.str,@object          # @.str
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.L.str:
+	.asciz	 "%lf "
+	.size	.L.str, 5
+
+	.type	C,@object               # @C
+	.comm	C,9437184,16
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.exe b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.exe
new file mode 100755
index 0000000..feb2436
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.exe
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.ll b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.ll
new file mode 100644
index 0000000..593794e
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.ll
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.s b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.s
new file mode 100644
index 0000000..ca87de1
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector+openmp.s
@@ -0,0 +1,754 @@
+	.file	"matmul.polly.interchanged+tiled+vector+openmp.ll"
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI0_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	init_array
+	.align	16, 0x90
+	.type	init_array,@function
+init_array:                             # @init_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp3:
+	.cfi_def_cfa_offset 16
+.Ltmp4:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp5:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%rbx
+	subq	$24, %rsp
+.Ltmp6:
+	.cfi_offset %rbx, -40
+.Ltmp7:
+	.cfi_offset %r14, -32
+.Ltmp8:
+	.cfi_offset %r15, -24
+	leaq	-32(%rbp), %rsi
+	movl	$init_array.omp_subfn, %edi
+	xorl	%edx, %edx
+	xorl	%ecx, %ecx
+	movl	$1536, %r8d             # imm = 0x600
+	movl	$1, %r9d
+	callq	GOMP_parallel_loop_runtime_start
+	leaq	-40(%rbp), %rdi
+	leaq	-48(%rbp), %rsi
+	callq	GOMP_loop_runtime_next
+	testb	%al, %al
+	je	.LBB0_4
+# BB#1:
+	leaq	-40(%rbp), %r14
+	leaq	-48(%rbp), %r15
+	vmovsd	.LCPI0_0(%rip), %xmm1
+	.align	16, 0x90
+.LBB0_2:                                # %omp.loadIVBounds.i
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB0_8 Depth 2
+                                        #       Child Loop BB0_5 Depth 3
+	movq	-48(%rbp), %r8
+	leaq	-1(%r8), %rcx
+	movq	-40(%rbp), %rax
+	cmpq	%rcx, %rax
+	jg	.LBB0_3
+# BB#7:                                 # %polly.loop_preheader4.preheader.i
+                                        #   in Loop: Header=BB0_2 Depth=1
+	addq	$-2, %r8
+	.align	16, 0x90
+.LBB0_8:                                # %polly.loop_preheader4.i
+                                        #   Parent Loop BB0_2 Depth=1
+                                        # =>  This Loop Header: Depth=2
+                                        #       Child Loop BB0_5 Depth 3
+	xorl	%edx, %edx
+	.align	16, 0x90
+.LBB0_5:                                # %polly.loop_header3.i
+                                        #   Parent Loop BB0_2 Depth=1
+                                        #     Parent Loop BB0_8 Depth=2
+                                        # =>    This Inner Loop Header: Depth=3
+	movl	%edx, %esi
+	imull	%eax, %esi
+	movl	%esi, %edi
+	sarl	$31, %edi
+	shrl	$22, %edi
+	addl	%esi, %edi
+	andl	$-1024, %edi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%edi
+	movq	%rax, %rcx
+	shlq	$11, %rcx
+	leal	1(%rsi,%rdi), %ebx
+	leaq	(%rcx,%rcx,2), %rdi
+	leaq	1(%rdx), %rsi
+	cmpq	$1536, %rsi             # imm = 0x600
+	vcvtsi2sdl	%ebx, %xmm0, %xmm0
+	vmulsd	%xmm1, %xmm0, %xmm0
+	vcvtsd2ss	%xmm0, %xmm0, %xmm0
+	vmovss	%xmm0, A(%rdi,%rdx,4)
+	vmovss	%xmm0, B(%rdi,%rdx,4)
+	movq	%rsi, %rdx
+	jne	.LBB0_5
+# BB#6:                                 # %polly.loop_exit5.i
+                                        #   in Loop: Header=BB0_8 Depth=2
+	cmpq	%r8, %rax
+	leaq	1(%rax), %rax
+	jle	.LBB0_8
+.LBB0_3:                                # %omp.checkNext.backedge.i
+                                        #   in Loop: Header=BB0_2 Depth=1
+	movq	%r14, %rdi
+	movq	%r15, %rsi
+	callq	GOMP_loop_runtime_next
+	vmovsd	.LCPI0_0(%rip), %xmm1
+	testb	%al, %al
+	jne	.LBB0_2
+.LBB0_4:                                # %init_array.omp_subfn.exit
+	callq	GOMP_loop_end_nowait
+	callq	GOMP_parallel_end
+	addq	$24, %rsp
+	popq	%rbx
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp9:
+	.size	init_array, .Ltmp9-init_array
+	.cfi_endproc
+
+	.globl	print_array
+	.align	16, 0x90
+	.type	print_array,@function
+print_array:                            # @print_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp13:
+	.cfi_def_cfa_offset 16
+.Ltmp14:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp15:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r12
+	pushq	%rbx
+.Ltmp16:
+	.cfi_offset %rbx, -48
+.Ltmp17:
+	.cfi_offset %r12, -40
+.Ltmp18:
+	.cfi_offset %r14, -32
+.Ltmp19:
+	.cfi_offset %r15, -24
+	xorl	%r14d, %r14d
+	movl	$C, %r15d
+	.align	16, 0x90
+.LBB1_1:                                # %for.cond1.preheader
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB1_2 Depth 2
+	movq	stdout(%rip), %rax
+	movq	%r15, %r12
+	xorl	%ebx, %ebx
+	.align	16, 0x90
+.LBB1_2:                                # %for.body3
+                                        #   Parent Loop BB1_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	vmovss	(%r12), %xmm0
+	vcvtss2sd	%xmm0, %xmm0, %xmm0
+	movq	%rax, %rdi
+	movl	$.L.str, %esi
+	movb	$1, %al
+	callq	fprintf
+	movslq	%ebx, %rax
+	imulq	$1717986919, %rax, %rcx # imm = 0x66666667
+	movq	%rcx, %rdx
+	shrq	$63, %rdx
+	sarq	$37, %rcx
+	addl	%edx, %ecx
+	imull	$80, %ecx, %ecx
+	subl	%ecx, %eax
+	cmpl	$79, %eax
+	jne	.LBB1_4
+# BB#3:                                 # %if.then
+                                        #   in Loop: Header=BB1_2 Depth=2
+	movq	stdout(%rip), %rsi
+	movl	$10, %edi
+	callq	fputc
+.LBB1_4:                                # %for.inc
+                                        #   in Loop: Header=BB1_2 Depth=2
+	addq	$4, %r12
+	incq	%rbx
+	movq	stdout(%rip), %rax
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB1_2
+# BB#5:                                 # %for.end
+                                        #   in Loop: Header=BB1_1 Depth=1
+	movl	$10, %edi
+	movq	%rax, %rsi
+	callq	fputc
+	addq	$6144, %r15             # imm = 0x1800
+	incq	%r14
+	cmpq	$1536, %r14             # imm = 0x600
+	jne	.LBB1_1
+# BB#6:                                 # %for.end12
+	popq	%rbx
+	popq	%r12
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp20:
+	.size	print_array, .Ltmp20-print_array
+	.cfi_endproc
+
+	.globl	main
+	.align	16, 0x90
+	.type	main,@function
+main:                                   # @main
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp24:
+	.cfi_def_cfa_offset 16
+.Ltmp25:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp26:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
+	pushq	%rbx
+	subq	$24, %rsp
+.Ltmp27:
+	.cfi_offset %rbx, -56
+.Ltmp28:
+	.cfi_offset %r12, -48
+.Ltmp29:
+	.cfi_offset %r13, -40
+.Ltmp30:
+	.cfi_offset %r14, -32
+.Ltmp31:
+	.cfi_offset %r15, -24
+	callq	init_array
+	leaq	-48(%rbp), %rsi
+	movl	$main.omp_subfn, %edi
+	xorl	%edx, %edx
+	xorl	%ecx, %ecx
+	movl	$1536, %r8d             # imm = 0x600
+	movl	$1, %r9d
+	callq	GOMP_parallel_loop_runtime_start
+	leaq	-56(%rbp), %rdi
+	leaq	-64(%rbp), %rsi
+	callq	GOMP_loop_runtime_next
+	testb	%al, %al
+	je	.LBB2_4
+# BB#1:
+	leaq	-56(%rbp), %r14
+	leaq	-64(%rbp), %r15
+	.align	16, 0x90
+.LBB2_2:                                # %omp.loadIVBounds.i
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_6 Depth 2
+	movq	-64(%rbp), %r12
+	leaq	-1(%r12), %rcx
+	movq	-56(%rbp), %rax
+	cmpq	%rcx, %rax
+	jg	.LBB2_3
+# BB#5:                                 # %polly.loop_preheader4.preheader.i
+                                        #   in Loop: Header=BB2_2 Depth=1
+	addq	$-2, %r12
+	leaq	(%rax,%rax,2), %rcx
+	leaq	-1(%rax), %r13
+	shlq	$11, %rcx
+	leaq	C(%rcx), %rbx
+	.align	16, 0x90
+.LBB2_6:                                # %polly.loop_preheader4.i
+                                        #   Parent Loop BB2_2 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movq	%rbx, %rdi
+	xorl	%esi, %esi
+	movl	$6144, %edx             # imm = 0x1800
+	callq	memset
+	addq	$6144, %rbx             # imm = 0x1800
+	incq	%r13
+	cmpq	%r12, %r13
+	jle	.LBB2_6
+.LBB2_3:                                # %omp.checkNext.backedge.i
+                                        #   in Loop: Header=BB2_2 Depth=1
+	movq	%r14, %rdi
+	movq	%r15, %rsi
+	callq	GOMP_loop_runtime_next
+	testb	%al, %al
+	jne	.LBB2_2
+.LBB2_4:                                # %main.omp_subfn.exit
+	callq	GOMP_loop_end_nowait
+	callq	GOMP_parallel_end
+	leaq	-48(%rbp), %rbx
+	movl	$main.omp_subfn1, %edi
+	movq	%rbx, %rsi
+	xorl	%edx, %edx
+	xorl	%ecx, %ecx
+	movl	$1536, %r8d             # imm = 0x600
+	movl	$64, %r9d
+	callq	GOMP_parallel_loop_runtime_start
+	movq	%rbx, %rdi
+	callq	main.omp_subfn1
+	callq	GOMP_parallel_end
+	xorl	%eax, %eax
+	addq	$24, %rsp
+	popq	%rbx
+	popq	%r12
+	popq	%r13
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp32:
+	.size	main, .Ltmp32-main
+	.cfi_endproc
+
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI3_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.align	16, 0x90
+	.type	init_array.omp_subfn,@function
+init_array.omp_subfn:                   # @init_array.omp_subfn
+	.cfi_startproc
+# BB#0:                                 # %omp.setup
+	pushq	%rbp
+.Ltmp36:
+	.cfi_def_cfa_offset 16
+.Ltmp37:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp38:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%rbx
+	subq	$24, %rsp
+.Ltmp39:
+	.cfi_offset %rbx, -40
+.Ltmp40:
+	.cfi_offset %r14, -32
+.Ltmp41:
+	.cfi_offset %r15, -24
+	leaq	-32(%rbp), %rdi
+	leaq	-40(%rbp), %rsi
+	callq	GOMP_loop_runtime_next
+	testb	%al, %al
+	je	.LBB3_4
+# BB#1:
+	leaq	-32(%rbp), %r14
+	leaq	-40(%rbp), %r15
+	vmovsd	.LCPI3_0(%rip), %xmm1
+	.align	16, 0x90
+.LBB3_2:                                # %omp.loadIVBounds
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB3_8 Depth 2
+                                        #       Child Loop BB3_5 Depth 3
+	movq	-40(%rbp), %r8
+	leaq	-1(%r8), %rcx
+	movq	-32(%rbp), %rax
+	cmpq	%rcx, %rax
+	jg	.LBB3_3
+# BB#7:                                 # %polly.loop_preheader4.preheader
+                                        #   in Loop: Header=BB3_2 Depth=1
+	addq	$-2, %r8
+	.align	16, 0x90
+.LBB3_8:                                # %polly.loop_preheader4
+                                        #   Parent Loop BB3_2 Depth=1
+                                        # =>  This Loop Header: Depth=2
+                                        #       Child Loop BB3_5 Depth 3
+	xorl	%edx, %edx
+	.align	16, 0x90
+.LBB3_5:                                # %polly.loop_header3
+                                        #   Parent Loop BB3_2 Depth=1
+                                        #     Parent Loop BB3_8 Depth=2
+                                        # =>    This Inner Loop Header: Depth=3
+	movl	%edx, %esi
+	imull	%eax, %esi
+	movl	%esi, %edi
+	sarl	$31, %edi
+	shrl	$22, %edi
+	addl	%esi, %edi
+	andl	$-1024, %edi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%edi
+	movq	%rax, %rcx
+	shlq	$11, %rcx
+	leal	1(%rsi,%rdi), %ebx
+	leaq	(%rcx,%rcx,2), %rdi
+	leaq	1(%rdx), %rsi
+	cmpq	$1536, %rsi             # imm = 0x600
+	vcvtsi2sdl	%ebx, %xmm0, %xmm0
+	vmulsd	%xmm1, %xmm0, %xmm0
+	vcvtsd2ss	%xmm0, %xmm0, %xmm0
+	vmovss	%xmm0, A(%rdi,%rdx,4)
+	vmovss	%xmm0, B(%rdi,%rdx,4)
+	movq	%rsi, %rdx
+	jne	.LBB3_5
+# BB#6:                                 # %polly.loop_exit5
+                                        #   in Loop: Header=BB3_8 Depth=2
+	cmpq	%r8, %rax
+	leaq	1(%rax), %rax
+	jle	.LBB3_8
+.LBB3_3:                                # %omp.checkNext.backedge
+                                        #   in Loop: Header=BB3_2 Depth=1
+	movq	%r14, %rdi
+	movq	%r15, %rsi
+	callq	GOMP_loop_runtime_next
+	vmovsd	.LCPI3_0(%rip), %xmm1
+	testb	%al, %al
+	jne	.LBB3_2
+.LBB3_4:                                # %omp.exit
+	callq	GOMP_loop_end_nowait
+	addq	$24, %rsp
+	popq	%rbx
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp42:
+	.size	init_array.omp_subfn, .Ltmp42-init_array.omp_subfn
+	.cfi_endproc
+
+	.align	16, 0x90
+	.type	main.omp_subfn,@function
+main.omp_subfn:                         # @main.omp_subfn
+	.cfi_startproc
+# BB#0:                                 # %omp.setup
+	pushq	%rbp
+.Ltmp46:
+	.cfi_def_cfa_offset 16
+.Ltmp47:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp48:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
+	pushq	%rbx
+	subq	$24, %rsp
+.Ltmp49:
+	.cfi_offset %rbx, -56
+.Ltmp50:
+	.cfi_offset %r12, -48
+.Ltmp51:
+	.cfi_offset %r13, -40
+.Ltmp52:
+	.cfi_offset %r14, -32
+.Ltmp53:
+	.cfi_offset %r15, -24
+	leaq	-48(%rbp), %rdi
+	leaq	-56(%rbp), %rsi
+	callq	GOMP_loop_runtime_next
+	testb	%al, %al
+	je	.LBB4_4
+# BB#1:
+	leaq	-48(%rbp), %r14
+	leaq	-56(%rbp), %r15
+	.align	16, 0x90
+.LBB4_2:                                # %omp.loadIVBounds
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB4_6 Depth 2
+	movq	-56(%rbp), %r12
+	leaq	-1(%r12), %rcx
+	movq	-48(%rbp), %rax
+	cmpq	%rcx, %rax
+	jg	.LBB4_3
+# BB#5:                                 # %polly.loop_preheader4.preheader
+                                        #   in Loop: Header=BB4_2 Depth=1
+	addq	$-2, %r12
+	leaq	(%rax,%rax,2), %rcx
+	leaq	-1(%rax), %r13
+	shlq	$11, %rcx
+	leaq	C(%rcx), %rbx
+	.align	16, 0x90
+.LBB4_6:                                # %polly.loop_preheader4
+                                        #   Parent Loop BB4_2 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movq	%rbx, %rdi
+	xorl	%esi, %esi
+	movl	$6144, %edx             # imm = 0x1800
+	callq	memset
+	addq	$6144, %rbx             # imm = 0x1800
+	incq	%r13
+	cmpq	%r12, %r13
+	jle	.LBB4_6
+.LBB4_3:                                # %omp.checkNext.backedge
+                                        #   in Loop: Header=BB4_2 Depth=1
+	movq	%r14, %rdi
+	movq	%r15, %rsi
+	callq	GOMP_loop_runtime_next
+	testb	%al, %al
+	jne	.LBB4_2
+.LBB4_4:                                # %omp.exit
+	callq	GOMP_loop_end_nowait
+	addq	$24, %rsp
+	popq	%rbx
+	popq	%r12
+	popq	%r13
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp54:
+	.size	main.omp_subfn, .Ltmp54-main.omp_subfn
+	.cfi_endproc
+
+	.align	16, 0x90
+	.type	main.omp_subfn1,@function
+main.omp_subfn1:                        # @main.omp_subfn1
+	.cfi_startproc
+# BB#0:                                 # %omp.setup
+	pushq	%rbp
+.Ltmp58:
+	.cfi_def_cfa_offset 16
+.Ltmp59:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp60:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
+	pushq	%rbx
+	subq	$72, %rsp
+.Ltmp61:
+	.cfi_offset %rbx, -56
+.Ltmp62:
+	.cfi_offset %r12, -48
+.Ltmp63:
+	.cfi_offset %r13, -40
+.Ltmp64:
+	.cfi_offset %r14, -32
+.Ltmp65:
+	.cfi_offset %r15, -24
+	jmp	.LBB5_1
+	.align	16, 0x90
+.LBB5_2:                                # %omp.loadIVBounds
+                                        #   in Loop: Header=BB5_1 Depth=1
+	movq	-56(%rbp), %rax
+	movq	%rax, -112(%rbp)        # 8-byte Spill
+	leaq	-1(%rax), %rax
+	movq	-48(%rbp), %rcx
+	cmpq	%rax, %rcx
+	jg	.LBB5_1
+# BB#3:                                 # %polly.loop_preheader4.preheader
+                                        #   in Loop: Header=BB5_1 Depth=1
+	leaq	-1(%rcx), %rax
+	movq	%rax, -88(%rbp)         # 8-byte Spill
+	addq	$-65, -112(%rbp)        # 8-byte Folded Spill
+	movq	%rcx, %rax
+	shlq	$9, %rax
+	leaq	(%rax,%rax,2), %rax
+	leaq	C+16(,%rax,4), %rax
+	movq	%rax, -104(%rbp)        # 8-byte Spill
+	.align	16, 0x90
+.LBB5_7:                                # %polly.loop_preheader4
+                                        #   Parent Loop BB5_1 Depth=1
+                                        # =>  This Loop Header: Depth=2
+                                        #       Child Loop BB5_8 Depth 3
+                                        #         Child Loop BB5_9 Depth 4
+                                        #           Child Loop BB5_12 Depth 5
+                                        #             Child Loop BB5_17 Depth 6
+                                        #               Child Loop BB5_18 Depth 7
+                                        #           Child Loop BB5_14 Depth 5
+	movq	%rcx, -72(%rbp)         # 8-byte Spill
+	leaq	62(%rcx), %rdi
+	xorl	%edx, %edx
+	.align	16, 0x90
+.LBB5_8:                                # %polly.loop_preheader11
+                                        #   Parent Loop BB5_1 Depth=1
+                                        #     Parent Loop BB5_7 Depth=2
+                                        # =>    This Loop Header: Depth=3
+                                        #         Child Loop BB5_9 Depth 4
+                                        #           Child Loop BB5_12 Depth 5
+                                        #             Child Loop BB5_17 Depth 6
+                                        #               Child Loop BB5_18 Depth 7
+                                        #           Child Loop BB5_14 Depth 5
+	movq	%rdx, -96(%rbp)         # 8-byte Spill
+	leaq	-4(%rdx), %rcx
+	movq	%rdx, %rax
+	decq	%rax
+	cmovsq	%rcx, %rax
+	movq	%rax, %r14
+	sarq	$63, %r14
+	shrq	$62, %r14
+	addq	%rax, %r14
+	andq	$-4, %r14
+	movq	%rdx, %rax
+	orq	$63, %rax
+	leaq	-4(%rax), %rdx
+	movq	-104(%rbp), %rcx        # 8-byte Reload
+	leaq	(%rcx,%r14,4), %rcx
+	movq	%rcx, -80(%rbp)         # 8-byte Spill
+	leaq	B+16(,%r14,4), %rbx
+	leaq	4(%r14), %rcx
+	movq	%rcx, -64(%rbp)         # 8-byte Spill
+	xorl	%r11d, %r11d
+	.align	16, 0x90
+.LBB5_9:                                # %polly.loop_header10
+                                        #   Parent Loop BB5_1 Depth=1
+                                        #     Parent Loop BB5_7 Depth=2
+                                        #       Parent Loop BB5_8 Depth=3
+                                        # =>      This Loop Header: Depth=4
+                                        #           Child Loop BB5_12 Depth 5
+                                        #             Child Loop BB5_17 Depth 6
+                                        #               Child Loop BB5_18 Depth 7
+                                        #           Child Loop BB5_14 Depth 5
+	movabsq	$9223372036854775744, %rcx # imm = 0x7FFFFFFFFFFFFFC0
+	cmpq	%rcx, -72(%rbp)         # 8-byte Folded Reload
+	jg	.LBB5_15
+# BB#10:                                # %polly.loop_header17.preheader
+                                        #   in Loop: Header=BB5_9 Depth=4
+	movq	%r11, %r15
+	orq	$63, %r15
+	cmpq	%r15, %r11
+	movq	-88(%rbp), %rcx         # 8-byte Reload
+	jle	.LBB5_11
+	.align	16, 0x90
+.LBB5_14:                               # %polly.loop_exit28.us
+                                        #   Parent Loop BB5_1 Depth=1
+                                        #     Parent Loop BB5_7 Depth=2
+                                        #       Parent Loop BB5_8 Depth=3
+                                        #         Parent Loop BB5_9 Depth=4
+                                        # =>        This Inner Loop Header: Depth=5
+	incq	%rcx
+	cmpq	%rdi, %rcx
+	jle	.LBB5_14
+	jmp	.LBB5_15
+	.align	16, 0x90
+.LBB5_11:                               #   in Loop: Header=BB5_9 Depth=4
+	decq	%r15
+	movq	-80(%rbp), %r13         # 8-byte Reload
+	movq	-72(%rbp), %rcx         # 8-byte Reload
+	.align	16, 0x90
+.LBB5_12:                               # %polly.loop_header26.preheader
+                                        #   Parent Loop BB5_1 Depth=1
+                                        #     Parent Loop BB5_7 Depth=2
+                                        #       Parent Loop BB5_8 Depth=3
+                                        #         Parent Loop BB5_9 Depth=4
+                                        # =>        This Loop Header: Depth=5
+                                        #             Child Loop BB5_17 Depth 6
+                                        #               Child Loop BB5_18 Depth 7
+	cmpq	%rax, -64(%rbp)         # 8-byte Folded Reload
+	movq	%rbx, %r12
+	movq	%r11, %r8
+	jg	.LBB5_13
+	.align	16, 0x90
+.LBB5_17:                               # %polly.loop_header35.preheader
+                                        #   Parent Loop BB5_1 Depth=1
+                                        #     Parent Loop BB5_7 Depth=2
+                                        #       Parent Loop BB5_8 Depth=3
+                                        #         Parent Loop BB5_9 Depth=4
+                                        #           Parent Loop BB5_12 Depth=5
+                                        # =>          This Loop Header: Depth=6
+                                        #               Child Loop BB5_18 Depth 7
+	leaq	(%rcx,%rcx,2), %rsi
+	shlq	$11, %rsi
+	vbroadcastss	A(%rsi,%r8,4), %xmm0
+	movq	%r13, %r9
+	movq	%r12, %r10
+	movq	%r14, %rsi
+.LBB5_18:                               # %polly.loop_header35
+                                        #   Parent Loop BB5_1 Depth=1
+                                        #     Parent Loop BB5_7 Depth=2
+                                        #       Parent Loop BB5_8 Depth=3
+                                        #         Parent Loop BB5_9 Depth=4
+                                        #           Parent Loop BB5_12 Depth=5
+                                        #             Parent Loop BB5_17 Depth=6
+                                        # =>            This Inner Loop Header: Depth=7
+	vmulps	(%r10), %xmm0, %xmm1
+	vaddps	(%r9), %xmm1, %xmm1
+	vmovaps	%xmm1, (%r9)
+	addq	$16, %r9
+	addq	$16, %r10
+	addq	$4, %rsi
+	cmpq	%rdx, %rsi
+	jle	.LBB5_18
+# BB#16:                                # %polly.loop_exit37
+                                        #   in Loop: Header=BB5_17 Depth=6
+	addq	$6144, %r12             # imm = 0x1800
+	cmpq	%r15, %r8
+	leaq	1(%r8), %r8
+	jle	.LBB5_17
+	.align	16, 0x90
+.LBB5_13:                               # %polly.loop_exit28
+                                        #   in Loop: Header=BB5_12 Depth=5
+	addq	$6144, %r13             # imm = 0x1800
+	cmpq	%rdi, %rcx
+	leaq	1(%rcx), %rcx
+	jle	.LBB5_12
+	.align	16, 0x90
+.LBB5_15:                               # %polly.loop_exit19
+                                        #   in Loop: Header=BB5_9 Depth=4
+	addq	$393216, %rbx           # imm = 0x60000
+	cmpq	$1472, %r11             # imm = 0x5C0
+	leaq	64(%r11), %r11
+	jl	.LBB5_9
+# BB#5:                                 # %polly.loop_exit12
+                                        #   in Loop: Header=BB5_8 Depth=3
+	movq	-96(%rbp), %rdx         # 8-byte Reload
+	cmpq	$1472, %rdx             # imm = 0x5C0
+	leaq	64(%rdx), %rdx
+	jl	.LBB5_8
+# BB#6:                                 # %polly.loop_exit5
+                                        #   in Loop: Header=BB5_7 Depth=2
+	addq	$64, -88(%rbp)          # 8-byte Folded Spill
+	addq	$393216, -104(%rbp)     # 8-byte Folded Spill
+                                        # imm = 0x60000
+	movq	-72(%rbp), %rcx         # 8-byte Reload
+	cmpq	-112(%rbp), %rcx        # 8-byte Folded Reload
+	leaq	64(%rcx), %rcx
+	jle	.LBB5_7
+.LBB5_1:                                # %omp.setup
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB5_7 Depth 2
+                                        #       Child Loop BB5_8 Depth 3
+                                        #         Child Loop BB5_9 Depth 4
+                                        #           Child Loop BB5_12 Depth 5
+                                        #             Child Loop BB5_17 Depth 6
+                                        #               Child Loop BB5_18 Depth 7
+                                        #           Child Loop BB5_14 Depth 5
+	leaq	-48(%rbp), %rdi
+	leaq	-56(%rbp), %rsi
+	callq	GOMP_loop_runtime_next
+	testb	%al, %al
+	jne	.LBB5_2
+# BB#4:                                 # %omp.exit
+	callq	GOMP_loop_end_nowait
+	addq	$72, %rsp
+	popq	%rbx
+	popq	%r12
+	popq	%r13
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp66:
+	.size	main.omp_subfn1, .Ltmp66-main.omp_subfn1
+	.cfi_endproc
+
+	.type	A,@object               # @A
+	.comm	A,9437184,16
+	.type	B,@object               # @B
+	.comm	B,9437184,16
+	.type	.L.str,@object          # @.str
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.L.str:
+	.asciz	 "%lf "
+	.size	.L.str, 5
+
+	.type	C,@object               # @C
+	.comm	C,9437184,16
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.exe b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.exe
new file mode 100755
index 0000000..36b788e
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.exe
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.ll b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.ll
new file mode 100644
index 0000000..9d1f9ad
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.ll
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.s b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.s
new file mode 100644
index 0000000..485d230
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled+vector.s
@@ -0,0 +1,396 @@
+	.file	"matmul.polly.interchanged+tiled+vector.ll"
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI0_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	init_array
+	.align	16, 0x90
+	.type	init_array,@function
+init_array:                             # @init_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp2:
+	.cfi_def_cfa_offset 16
+.Ltmp3:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp4:
+	.cfi_def_cfa_register %rbp
+	xorl	%r8d, %r8d
+	vmovsd	.LCPI0_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB0_1:                                # %polly.loop_preheader3
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB0_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB0_2:                                # %polly.loop_header2
+                                        #   Parent Loop BB0_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%r8d, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%r8, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB0_2
+# BB#3:                                 # %polly.loop_exit4
+                                        #   in Loop: Header=BB0_1 Depth=1
+	incq	%r8
+	cmpq	$1536, %r8              # imm = 0x600
+	jne	.LBB0_1
+# BB#4:                                 # %polly.loop_exit
+	popq	%rbp
+	ret
+.Ltmp5:
+	.size	init_array, .Ltmp5-init_array
+	.cfi_endproc
+
+	.globl	print_array
+	.align	16, 0x90
+	.type	print_array,@function
+print_array:                            # @print_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp9:
+	.cfi_def_cfa_offset 16
+.Ltmp10:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp11:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r12
+	pushq	%rbx
+.Ltmp12:
+	.cfi_offset %rbx, -48
+.Ltmp13:
+	.cfi_offset %r12, -40
+.Ltmp14:
+	.cfi_offset %r14, -32
+.Ltmp15:
+	.cfi_offset %r15, -24
+	xorl	%r14d, %r14d
+	movl	$C, %r15d
+	.align	16, 0x90
+.LBB1_1:                                # %for.cond1.preheader
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB1_2 Depth 2
+	movq	stdout(%rip), %rax
+	movq	%r15, %r12
+	xorl	%ebx, %ebx
+	.align	16, 0x90
+.LBB1_2:                                # %for.body3
+                                        #   Parent Loop BB1_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	vmovss	(%r12), %xmm0
+	vcvtss2sd	%xmm0, %xmm0, %xmm0
+	movq	%rax, %rdi
+	movl	$.L.str, %esi
+	movb	$1, %al
+	callq	fprintf
+	movslq	%ebx, %rax
+	imulq	$1717986919, %rax, %rcx # imm = 0x66666667
+	movq	%rcx, %rdx
+	shrq	$63, %rdx
+	sarq	$37, %rcx
+	addl	%edx, %ecx
+	imull	$80, %ecx, %ecx
+	subl	%ecx, %eax
+	cmpl	$79, %eax
+	jne	.LBB1_4
+# BB#3:                                 # %if.then
+                                        #   in Loop: Header=BB1_2 Depth=2
+	movq	stdout(%rip), %rsi
+	movl	$10, %edi
+	callq	fputc
+.LBB1_4:                                # %for.inc
+                                        #   in Loop: Header=BB1_2 Depth=2
+	addq	$4, %r12
+	incq	%rbx
+	movq	stdout(%rip), %rax
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB1_2
+# BB#5:                                 # %for.end
+                                        #   in Loop: Header=BB1_1 Depth=1
+	movl	$10, %edi
+	movq	%rax, %rsi
+	callq	fputc
+	addq	$6144, %r15             # imm = 0x1800
+	incq	%r14
+	cmpq	$1536, %r14             # imm = 0x600
+	jne	.LBB1_1
+# BB#6:                                 # %for.end12
+	popq	%rbx
+	popq	%r12
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp16:
+	.size	print_array, .Ltmp16-print_array
+	.cfi_endproc
+
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI2_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	main
+	.align	16, 0x90
+	.type	main,@function
+main:                                   # @main
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp20:
+	.cfi_def_cfa_offset 16
+.Ltmp21:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp22:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
+	pushq	%rbx
+	subq	$56, %rsp
+.Ltmp23:
+	.cfi_offset %rbx, -56
+.Ltmp24:
+	.cfi_offset %r12, -48
+.Ltmp25:
+	.cfi_offset %r13, -40
+.Ltmp26:
+	.cfi_offset %r14, -32
+.Ltmp27:
+	.cfi_offset %r15, -24
+	xorl	%ebx, %ebx
+	vmovsd	.LCPI2_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB2_1:                                # %polly.loop_preheader3.i
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB2_2:                                # %polly.loop_header2.i
+                                        #   Parent Loop BB2_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%ebx, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%rbx, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB2_2
+# BB#3:                                 # %polly.loop_exit4.i
+                                        #   in Loop: Header=BB2_1 Depth=1
+	incq	%rbx
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB2_1
+# BB#4:                                 # %polly.loop_preheader3.preheader
+	movl	$C, %edi
+	xorl	%esi, %esi
+	movl	$9437184, %edx          # imm = 0x900000
+	callq	memset
+	xorl	%esi, %esi
+	movl	$C+16, %eax
+	movq	%rax, -88(%rbp)         # 8-byte Spill
+	.align	16, 0x90
+.LBB2_5:                                # %polly.loop_preheader17
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_15 Depth 2
+                                        #       Child Loop BB2_8 Depth 3
+                                        #         Child Loop BB2_11 Depth 4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	movq	%rsi, -56(%rbp)         # 8-byte Spill
+	movq	%rsi, %rax
+	orq	$63, %rax
+	movq	%rax, -72(%rbp)         # 8-byte Spill
+	leaq	-1(%rax), %rax
+	movq	%rax, -48(%rbp)         # 8-byte Spill
+	xorl	%edx, %edx
+	.align	16, 0x90
+.LBB2_15:                               # %polly.loop_preheader24
+                                        #   Parent Loop BB2_5 Depth=1
+                                        # =>  This Loop Header: Depth=2
+                                        #       Child Loop BB2_8 Depth 3
+                                        #         Child Loop BB2_11 Depth 4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	movq	%rdx, -80(%rbp)         # 8-byte Spill
+	leaq	-4(%rdx), %rcx
+	movq	%rdx, %rax
+	decq	%rax
+	cmovsq	%rcx, %rax
+	movq	%rax, %r15
+	sarq	$63, %r15
+	shrq	$62, %r15
+	addq	%rax, %r15
+	andq	$-4, %r15
+	movq	%rdx, %r13
+	orq	$63, %r13
+	leaq	-4(%r13), %rdx
+	xorl	%r10d, %r10d
+	movq	-88(%rbp), %rax         # 8-byte Reload
+	leaq	(%rax,%r15,4), %rax
+	movq	%rax, -64(%rbp)         # 8-byte Spill
+	leaq	B+16(,%r15,4), %rbx
+	leaq	4(%r15), %r12
+	.align	16, 0x90
+.LBB2_8:                                # %polly.loop_header23
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        # =>    This Loop Header: Depth=3
+                                        #         Child Loop BB2_11 Depth 4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	cmpq	-72(%rbp), %rsi         # 8-byte Folded Reload
+	jg	.LBB2_13
+# BB#9:                                 # %polly.loop_header30.preheader
+                                        #   in Loop: Header=BB2_8 Depth=3
+	movq	%r10, %rax
+	orq	$63, %rax
+	cmpq	%rax, %r10
+	jg	.LBB2_13
+# BB#10:                                #   in Loop: Header=BB2_8 Depth=3
+	decq	%rax
+	movq	-64(%rbp), %r14         # 8-byte Reload
+	movq	-56(%rbp), %r11         # 8-byte Reload
+	.align	16, 0x90
+.LBB2_11:                               # %polly.loop_header37.preheader
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        #       Parent Loop BB2_8 Depth=3
+                                        # =>      This Loop Header: Depth=4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	cmpq	%r13, %r12
+	movq	%rbx, %r8
+	movq	%r10, %rsi
+	jg	.LBB2_12
+	.align	16, 0x90
+.LBB2_17:                               # %polly.loop_header46.preheader
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        #       Parent Loop BB2_8 Depth=3
+                                        #         Parent Loop BB2_11 Depth=4
+                                        # =>        This Loop Header: Depth=5
+                                        #             Child Loop BB2_18 Depth 6
+	leaq	(%r11,%r11,2), %rcx
+	shlq	$11, %rcx
+	vbroadcastss	A(%rcx,%rsi,4), %xmm0
+	movq	%r14, %rdi
+	movq	%r8, %r9
+	movq	%r15, %rcx
+.LBB2_18:                               # %polly.loop_header46
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        #       Parent Loop BB2_8 Depth=3
+                                        #         Parent Loop BB2_11 Depth=4
+                                        #           Parent Loop BB2_17 Depth=5
+                                        # =>          This Inner Loop Header: Depth=6
+	vmulps	(%r9), %xmm0, %xmm1
+	vaddps	(%rdi), %xmm1, %xmm1
+	vmovaps	%xmm1, (%rdi)
+	addq	$16, %rdi
+	addq	$16, %r9
+	addq	$4, %rcx
+	cmpq	%rdx, %rcx
+	jle	.LBB2_18
+# BB#16:                                # %polly.loop_exit48
+                                        #   in Loop: Header=BB2_17 Depth=5
+	addq	$6144, %r8              # imm = 0x1800
+	cmpq	%rax, %rsi
+	leaq	1(%rsi), %rsi
+	jle	.LBB2_17
+	.align	16, 0x90
+.LBB2_12:                               # %polly.loop_exit39
+                                        #   in Loop: Header=BB2_11 Depth=4
+	addq	$6144, %r14             # imm = 0x1800
+	cmpq	-48(%rbp), %r11         # 8-byte Folded Reload
+	leaq	1(%r11), %r11
+	jle	.LBB2_11
+	.align	16, 0x90
+.LBB2_13:                               # %polly.loop_exit32
+                                        #   in Loop: Header=BB2_8 Depth=3
+	addq	$393216, %rbx           # imm = 0x60000
+	cmpq	$1472, %r10             # imm = 0x5C0
+	leaq	64(%r10), %r10
+	movq	-56(%rbp), %rsi         # 8-byte Reload
+	jl	.LBB2_8
+# BB#14:                                # %polly.loop_exit25
+                                        #   in Loop: Header=BB2_15 Depth=2
+	movq	-80(%rbp), %rdx         # 8-byte Reload
+	cmpq	$1472, %rdx             # imm = 0x5C0
+	leaq	64(%rdx), %rdx
+	jl	.LBB2_15
+# BB#6:                                 # %polly.loop_exit18
+                                        #   in Loop: Header=BB2_5 Depth=1
+	addq	$393216, -88(%rbp)      # 8-byte Folded Spill
+                                        # imm = 0x60000
+	cmpq	$1472, %rsi             # imm = 0x5C0
+	leaq	64(%rsi), %rsi
+	jl	.LBB2_5
+# BB#7:                                 # %polly.loop_exit11
+	xorl	%eax, %eax
+	addq	$56, %rsp
+	popq	%rbx
+	popq	%r12
+	popq	%r13
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp28:
+	.size	main, .Ltmp28-main
+	.cfi_endproc
+
+	.type	A,@object               # @A
+	.comm	A,9437184,16
+	.type	B,@object               # @B
+	.comm	B,9437184,16
+	.type	.L.str,@object          # @.str
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.L.str:
+	.asciz	 "%lf "
+	.size	.L.str, 5
+
+	.type	C,@object               # @C
+	.comm	C,9437184,16
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.exe b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.exe
new file mode 100755
index 0000000..fbd8b12
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.exe
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.ll b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.ll
new file mode 100644
index 0000000..acdd95f
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.ll
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.s b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.s
new file mode 100644
index 0000000..f7ab7fd
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged+tiled.s
@@ -0,0 +1,390 @@
+	.file	"matmul.polly.interchanged+tiled.ll"
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI0_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	init_array
+	.align	16, 0x90
+	.type	init_array,@function
+init_array:                             # @init_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp2:
+	.cfi_def_cfa_offset 16
+.Ltmp3:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp4:
+	.cfi_def_cfa_register %rbp
+	xorl	%r8d, %r8d
+	vmovsd	.LCPI0_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB0_1:                                # %polly.loop_preheader3
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB0_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB0_2:                                # %polly.loop_header2
+                                        #   Parent Loop BB0_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%r8d, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%r8, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB0_2
+# BB#3:                                 # %polly.loop_exit4
+                                        #   in Loop: Header=BB0_1 Depth=1
+	incq	%r8
+	cmpq	$1536, %r8              # imm = 0x600
+	jne	.LBB0_1
+# BB#4:                                 # %polly.loop_exit
+	popq	%rbp
+	ret
+.Ltmp5:
+	.size	init_array, .Ltmp5-init_array
+	.cfi_endproc
+
+	.globl	print_array
+	.align	16, 0x90
+	.type	print_array,@function
+print_array:                            # @print_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp9:
+	.cfi_def_cfa_offset 16
+.Ltmp10:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp11:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r12
+	pushq	%rbx
+.Ltmp12:
+	.cfi_offset %rbx, -48
+.Ltmp13:
+	.cfi_offset %r12, -40
+.Ltmp14:
+	.cfi_offset %r14, -32
+.Ltmp15:
+	.cfi_offset %r15, -24
+	xorl	%r14d, %r14d
+	movl	$C, %r15d
+	.align	16, 0x90
+.LBB1_1:                                # %for.cond1.preheader
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB1_2 Depth 2
+	movq	stdout(%rip), %rax
+	movq	%r15, %r12
+	xorl	%ebx, %ebx
+	.align	16, 0x90
+.LBB1_2:                                # %for.body3
+                                        #   Parent Loop BB1_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	vmovss	(%r12), %xmm0
+	vcvtss2sd	%xmm0, %xmm0, %xmm0
+	movq	%rax, %rdi
+	movl	$.L.str, %esi
+	movb	$1, %al
+	callq	fprintf
+	movslq	%ebx, %rax
+	imulq	$1717986919, %rax, %rcx # imm = 0x66666667
+	movq	%rcx, %rdx
+	shrq	$63, %rdx
+	sarq	$37, %rcx
+	addl	%edx, %ecx
+	imull	$80, %ecx, %ecx
+	subl	%ecx, %eax
+	cmpl	$79, %eax
+	jne	.LBB1_4
+# BB#3:                                 # %if.then
+                                        #   in Loop: Header=BB1_2 Depth=2
+	movq	stdout(%rip), %rsi
+	movl	$10, %edi
+	callq	fputc
+.LBB1_4:                                # %for.inc
+                                        #   in Loop: Header=BB1_2 Depth=2
+	addq	$4, %r12
+	incq	%rbx
+	movq	stdout(%rip), %rax
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB1_2
+# BB#5:                                 # %for.end
+                                        #   in Loop: Header=BB1_1 Depth=1
+	movl	$10, %edi
+	movq	%rax, %rsi
+	callq	fputc
+	addq	$6144, %r15             # imm = 0x1800
+	incq	%r14
+	cmpq	$1536, %r14             # imm = 0x600
+	jne	.LBB1_1
+# BB#6:                                 # %for.end12
+	popq	%rbx
+	popq	%r12
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp16:
+	.size	print_array, .Ltmp16-print_array
+	.cfi_endproc
+
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI2_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	main
+	.align	16, 0x90
+	.type	main,@function
+main:                                   # @main
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp20:
+	.cfi_def_cfa_offset 16
+.Ltmp21:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp22:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r13
+	pushq	%r12
+	pushq	%rbx
+	subq	$56, %rsp
+.Ltmp23:
+	.cfi_offset %rbx, -56
+.Ltmp24:
+	.cfi_offset %r12, -48
+.Ltmp25:
+	.cfi_offset %r13, -40
+.Ltmp26:
+	.cfi_offset %r14, -32
+.Ltmp27:
+	.cfi_offset %r15, -24
+	xorl	%ebx, %ebx
+	vmovsd	.LCPI2_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB2_1:                                # %polly.loop_preheader3.i
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB2_2:                                # %polly.loop_header2.i
+                                        #   Parent Loop BB2_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%ebx, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%rbx, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB2_2
+# BB#3:                                 # %polly.loop_exit4.i
+                                        #   in Loop: Header=BB2_1 Depth=1
+	incq	%rbx
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB2_1
+# BB#4:                                 # %polly.loop_preheader3.preheader
+	movl	$C, %ebx
+	movl	$C, %edi
+	xorl	%esi, %esi
+	movl	$9437184, %edx          # imm = 0x900000
+	callq	memset
+	xorl	%eax, %eax
+	.align	16, 0x90
+.LBB2_5:                                # %polly.loop_preheader17
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_15 Depth 2
+                                        #       Child Loop BB2_8 Depth 3
+                                        #         Child Loop BB2_11 Depth 4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	movq	%rax, -56(%rbp)         # 8-byte Spill
+	movq	%rbx, -88(%rbp)         # 8-byte Spill
+	movq	%rax, %rcx
+	orq	$63, %rcx
+	movq	%rcx, -72(%rbp)         # 8-byte Spill
+	leaq	-1(%rcx), %rcx
+	movq	%rcx, -48(%rbp)         # 8-byte Spill
+	movq	$-1, %r15
+	movl	$B, %ecx
+	movq	%rbx, -64(%rbp)         # 8-byte Spill
+	xorl	%r12d, %r12d
+	.align	16, 0x90
+.LBB2_15:                               # %polly.loop_preheader24
+                                        #   Parent Loop BB2_5 Depth=1
+                                        # =>  This Loop Header: Depth=2
+                                        #       Child Loop BB2_8 Depth 3
+                                        #         Child Loop BB2_11 Depth 4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	movq	%rcx, -80(%rbp)         # 8-byte Spill
+	movq	%r12, %r13
+	orq	$63, %r13
+	leaq	-1(%r13), %rbx
+	xorl	%r9d, %r9d
+	movq	%rcx, %rdx
+	.align	16, 0x90
+.LBB2_8:                                # %polly.loop_header23
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        # =>    This Loop Header: Depth=3
+                                        #         Child Loop BB2_11 Depth 4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	cmpq	-72(%rbp), %rax         # 8-byte Folded Reload
+	jg	.LBB2_13
+# BB#9:                                 # %polly.loop_header30.preheader
+                                        #   in Loop: Header=BB2_8 Depth=3
+	movq	%r9, %rax
+	orq	$63, %rax
+	cmpq	%rax, %r9
+	jg	.LBB2_13
+# BB#10:                                #   in Loop: Header=BB2_8 Depth=3
+	decq	%rax
+	movq	-64(%rbp), %r10         # 8-byte Reload
+	movq	-56(%rbp), %r11         # 8-byte Reload
+	.align	16, 0x90
+.LBB2_11:                               # %polly.loop_header37.preheader
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        #       Parent Loop BB2_8 Depth=3
+                                        # =>      This Loop Header: Depth=4
+                                        #           Child Loop BB2_17 Depth 5
+                                        #             Child Loop BB2_18 Depth 6
+	cmpq	%r13, %r12
+	movq	%rdx, %r14
+	movq	%r9, %rcx
+	jg	.LBB2_12
+	.align	16, 0x90
+.LBB2_17:                               # %polly.loop_header46.preheader
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        #       Parent Loop BB2_8 Depth=3
+                                        #         Parent Loop BB2_11 Depth=4
+                                        # =>        This Loop Header: Depth=5
+                                        #             Child Loop BB2_18 Depth 6
+	leaq	(%r11,%r11,2), %rsi
+	shlq	$11, %rsi
+	vmovss	A(%rsi,%rcx,4), %xmm0
+	movq	%r10, %rdi
+	movq	%r14, %r8
+	movq	%r15, %rsi
+.LBB2_18:                               # %polly.loop_header46
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_15 Depth=2
+                                        #       Parent Loop BB2_8 Depth=3
+                                        #         Parent Loop BB2_11 Depth=4
+                                        #           Parent Loop BB2_17 Depth=5
+                                        # =>          This Inner Loop Header: Depth=6
+	vmulss	(%r8), %xmm0, %xmm1
+	vaddss	(%rdi), %xmm1, %xmm1
+	vmovss	%xmm1, (%rdi)
+	addq	$4, %rdi
+	addq	$4, %r8
+	incq	%rsi
+	cmpq	%rbx, %rsi
+	jle	.LBB2_18
+# BB#16:                                # %polly.loop_exit48
+                                        #   in Loop: Header=BB2_17 Depth=5
+	addq	$6144, %r14             # imm = 0x1800
+	cmpq	%rax, %rcx
+	leaq	1(%rcx), %rcx
+	jle	.LBB2_17
+	.align	16, 0x90
+.LBB2_12:                               # %polly.loop_exit39
+                                        #   in Loop: Header=BB2_11 Depth=4
+	addq	$6144, %r10             # imm = 0x1800
+	cmpq	-48(%rbp), %r11         # 8-byte Folded Reload
+	leaq	1(%r11), %r11
+	jle	.LBB2_11
+	.align	16, 0x90
+.LBB2_13:                               # %polly.loop_exit32
+                                        #   in Loop: Header=BB2_8 Depth=3
+	addq	$393216, %rdx           # imm = 0x60000
+	cmpq	$1472, %r9              # imm = 0x5C0
+	leaq	64(%r9), %r9
+	movq	-56(%rbp), %rax         # 8-byte Reload
+	jl	.LBB2_8
+# BB#14:                                # %polly.loop_exit25
+                                        #   in Loop: Header=BB2_15 Depth=2
+	addq	$256, -64(%rbp)         # 8-byte Folded Spill
+                                        # imm = 0x100
+	movq	-80(%rbp), %rcx         # 8-byte Reload
+	addq	$256, %rcx              # imm = 0x100
+	addq	$64, %r15
+	cmpq	$1472, %r12             # imm = 0x5C0
+	leaq	64(%r12), %r12
+	jl	.LBB2_15
+# BB#6:                                 # %polly.loop_exit18
+                                        #   in Loop: Header=BB2_5 Depth=1
+	movq	-88(%rbp), %rbx         # 8-byte Reload
+	addq	$393216, %rbx           # imm = 0x60000
+	cmpq	$1472, %rax             # imm = 0x5C0
+	leaq	64(%rax), %rax
+	jl	.LBB2_5
+# BB#7:                                 # %polly.loop_exit11
+	xorl	%eax, %eax
+	addq	$56, %rsp
+	popq	%rbx
+	popq	%r12
+	popq	%r13
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp28:
+	.size	main, .Ltmp28-main
+	.cfi_endproc
+
+	.type	A,@object               # @A
+	.comm	A,9437184,16
+	.type	B,@object               # @B
+	.comm	B,9437184,16
+	.type	.L.str,@object          # @.str
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.L.str:
+	.asciz	 "%lf "
+	.size	.L.str, 5
+
+	.type	C,@object               # @C
+	.comm	C,9437184,16
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged.exe b/rc1/www/experiments/matmul/matmul.polly.interchanged.exe
new file mode 100755
index 0000000..240c95a
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged.exe
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged.ll b/rc1/www/experiments/matmul/matmul.polly.interchanged.ll
new file mode 100644
index 0000000..52fbccc
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged.ll
Binary files differ
diff --git a/rc1/www/experiments/matmul/matmul.polly.interchanged.s b/rc1/www/experiments/matmul/matmul.polly.interchanged.s
new file mode 100644
index 0000000..a764da0
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.polly.interchanged.s
@@ -0,0 +1,286 @@
+	.file	"matmul.polly.interchanged.ll"
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI0_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	init_array
+	.align	16, 0x90
+	.type	init_array,@function
+init_array:                             # @init_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp2:
+	.cfi_def_cfa_offset 16
+.Ltmp3:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp4:
+	.cfi_def_cfa_register %rbp
+	xorl	%r8d, %r8d
+	vmovsd	.LCPI0_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB0_1:                                # %polly.loop_preheader3
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB0_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB0_2:                                # %polly.loop_header2
+                                        #   Parent Loop BB0_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%r8d, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%r8, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB0_2
+# BB#3:                                 # %polly.loop_exit4
+                                        #   in Loop: Header=BB0_1 Depth=1
+	incq	%r8
+	cmpq	$1536, %r8              # imm = 0x600
+	jne	.LBB0_1
+# BB#4:                                 # %polly.loop_exit
+	popq	%rbp
+	ret
+.Ltmp5:
+	.size	init_array, .Ltmp5-init_array
+	.cfi_endproc
+
+	.globl	print_array
+	.align	16, 0x90
+	.type	print_array,@function
+print_array:                            # @print_array
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp9:
+	.cfi_def_cfa_offset 16
+.Ltmp10:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp11:
+	.cfi_def_cfa_register %rbp
+	pushq	%r15
+	pushq	%r14
+	pushq	%r12
+	pushq	%rbx
+.Ltmp12:
+	.cfi_offset %rbx, -48
+.Ltmp13:
+	.cfi_offset %r12, -40
+.Ltmp14:
+	.cfi_offset %r14, -32
+.Ltmp15:
+	.cfi_offset %r15, -24
+	xorl	%r14d, %r14d
+	movl	$C, %r15d
+	.align	16, 0x90
+.LBB1_1:                                # %for.cond1.preheader
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB1_2 Depth 2
+	movq	stdout(%rip), %rax
+	movq	%r15, %r12
+	xorl	%ebx, %ebx
+	.align	16, 0x90
+.LBB1_2:                                # %for.body3
+                                        #   Parent Loop BB1_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	vmovss	(%r12), %xmm0
+	vcvtss2sd	%xmm0, %xmm0, %xmm0
+	movq	%rax, %rdi
+	movl	$.L.str, %esi
+	movb	$1, %al
+	callq	fprintf
+	movslq	%ebx, %rax
+	imulq	$1717986919, %rax, %rcx # imm = 0x66666667
+	movq	%rcx, %rdx
+	shrq	$63, %rdx
+	sarq	$37, %rcx
+	addl	%edx, %ecx
+	imull	$80, %ecx, %ecx
+	subl	%ecx, %eax
+	cmpl	$79, %eax
+	jne	.LBB1_4
+# BB#3:                                 # %if.then
+                                        #   in Loop: Header=BB1_2 Depth=2
+	movq	stdout(%rip), %rsi
+	movl	$10, %edi
+	callq	fputc
+.LBB1_4:                                # %for.inc
+                                        #   in Loop: Header=BB1_2 Depth=2
+	addq	$4, %r12
+	incq	%rbx
+	movq	stdout(%rip), %rax
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB1_2
+# BB#5:                                 # %for.end
+                                        #   in Loop: Header=BB1_1 Depth=1
+	movl	$10, %edi
+	movq	%rax, %rsi
+	callq	fputc
+	addq	$6144, %r15             # imm = 0x1800
+	incq	%r14
+	cmpq	$1536, %r14             # imm = 0x600
+	jne	.LBB1_1
+# BB#6:                                 # %for.end12
+	popq	%rbx
+	popq	%r12
+	popq	%r14
+	popq	%r15
+	popq	%rbp
+	ret
+.Ltmp16:
+	.size	print_array, .Ltmp16-print_array
+	.cfi_endproc
+
+	.section	.rodata.cst8,"aM",@progbits,8
+	.align	8
+.LCPI2_0:
+	.quad	4602678819172646912     # double 0.5
+	.text
+	.globl	main
+	.align	16, 0x90
+	.type	main,@function
+main:                                   # @main
+	.cfi_startproc
+# BB#0:                                 # %entry
+	pushq	%rbp
+.Ltmp20:
+	.cfi_def_cfa_offset 16
+.Ltmp21:
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+.Ltmp22:
+	.cfi_def_cfa_register %rbp
+	pushq	%r14
+	pushq	%rbx
+.Ltmp23:
+	.cfi_offset %rbx, -32
+.Ltmp24:
+	.cfi_offset %r14, -24
+	xorl	%ebx, %ebx
+	vmovsd	.LCPI2_0(%rip), %xmm0
+	.align	16, 0x90
+.LBB2_1:                                # %polly.loop_preheader3.i
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_2 Depth 2
+	xorl	%ecx, %ecx
+	.align	16, 0x90
+.LBB2_2:                                # %polly.loop_header2.i
+                                        #   Parent Loop BB2_1 Depth=1
+                                        # =>  This Inner Loop Header: Depth=2
+	movl	%ecx, %edx
+	imull	%ebx, %edx
+	movl	%edx, %esi
+	sarl	$31, %esi
+	shrl	$22, %esi
+	addl	%edx, %esi
+	andl	$-1024, %esi            # imm = 0xFFFFFFFFFFFFFC00
+	negl	%esi
+	movq	%rbx, %rax
+	shlq	$11, %rax
+	leal	1(%rdx,%rsi), %edi
+	leaq	(%rax,%rax,2), %rsi
+	leaq	1(%rcx), %rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	vcvtsi2sdl	%edi, %xmm0, %xmm1
+	vmulsd	%xmm0, %xmm1, %xmm1
+	vcvtsd2ss	%xmm1, %xmm1, %xmm1
+	vmovss	%xmm1, A(%rsi,%rcx,4)
+	vmovss	%xmm1, B(%rsi,%rcx,4)
+	movq	%rdx, %rcx
+	jne	.LBB2_2
+# BB#3:                                 # %polly.loop_exit4.i
+                                        #   in Loop: Header=BB2_1 Depth=1
+	incq	%rbx
+	cmpq	$1536, %rbx             # imm = 0x600
+	jne	.LBB2_1
+# BB#4:                                 # %polly.loop_preheader3.preheader
+	movl	$C, %r14d
+	movl	$C, %edi
+	xorl	%esi, %esi
+	movl	$9437184, %edx          # imm = 0x900000
+	callq	memset
+	xorl	%eax, %eax
+	.align	16, 0x90
+.LBB2_5:                                # %polly.loop_preheader17
+                                        # =>This Loop Header: Depth=1
+                                        #     Child Loop BB2_10 Depth 2
+                                        #       Child Loop BB2_8 Depth 3
+	movl	$B, %ebx
+	xorl	%edx, %edx
+	.align	16, 0x90
+.LBB2_10:                               # %polly.loop_preheader24
+                                        #   Parent Loop BB2_5 Depth=1
+                                        # =>  This Loop Header: Depth=2
+                                        #       Child Loop BB2_8 Depth 3
+	leaq	(%rax,%rax,2), %rcx
+	shlq	$11, %rcx
+	vmovss	A(%rcx,%rdx,4), %xmm0
+	movl	$1536, %esi             # imm = 0x600
+	movq	%r14, %rdi
+	movq	%rbx, %rcx
+	.align	16, 0x90
+.LBB2_8:                                # %polly.loop_header23
+                                        #   Parent Loop BB2_5 Depth=1
+                                        #     Parent Loop BB2_10 Depth=2
+                                        # =>    This Inner Loop Header: Depth=3
+	vmulss	(%rcx), %xmm0, %xmm1
+	vaddss	(%rdi), %xmm1, %xmm1
+	vmovss	%xmm1, (%rdi)
+	addq	$4, %rdi
+	addq	$4, %rcx
+	decq	%rsi
+	jne	.LBB2_8
+# BB#9:                                 # %polly.loop_exit25
+                                        #   in Loop: Header=BB2_10 Depth=2
+	addq	$6144, %rbx             # imm = 0x1800
+	incq	%rdx
+	cmpq	$1536, %rdx             # imm = 0x600
+	jne	.LBB2_10
+# BB#6:                                 # %polly.loop_exit18
+                                        #   in Loop: Header=BB2_5 Depth=1
+	addq	$6144, %r14             # imm = 0x1800
+	incq	%rax
+	cmpq	$1536, %rax             # imm = 0x600
+	jne	.LBB2_5
+# BB#7:                                 # %polly.loop_exit11
+	xorl	%eax, %eax
+	popq	%rbx
+	popq	%r14
+	popq	%rbp
+	ret
+.Ltmp25:
+	.size	main, .Ltmp25-main
+	.cfi_endproc
+
+	.type	A,@object               # @A
+	.comm	A,9437184,16
+	.type	B,@object               # @B
+	.comm	B,9437184,16
+	.type	.L.str,@object          # @.str
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.L.str:
+	.asciz	 "%lf "
+	.size	.L.str, 5
+
+	.type	C,@object               # @C
+	.comm	C,9437184,16
+
+	.section	".note.GNU-stack","",@progbits
diff --git a/rc1/www/experiments/matmul/matmul.preopt.ll b/rc1/www/experiments/matmul/matmul.preopt.ll
new file mode 100644
index 0000000..3931716
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.preopt.ll
@@ -0,0 +1,186 @@
+; ModuleID = '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-S128"
+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 [1536 x [1536 x float]] zeroinitializer, align 16
+@B = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@stdout = external global %struct._IO_FILE*
+@.str = private unnamed_addr constant [5 x i8] c"%lf \00", align 1
+@C = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@.str1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
+
+; Function Attrs: nounwind uwtable
+define void @init_array() #0 {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc17, %entry
+  %0 = phi i64 [ %indvar.next2, %for.inc17 ], [ 0, %entry ]
+  %exitcond3 = icmp ne i64 %0, 1536
+  br i1 %exitcond3, label %for.body, label %for.end19
+
+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 ]
+  %arrayidx6 = getelementptr [1536 x [1536 x float]]* @A, i64 0, i64 %0, i64 %indvar
+  %arrayidx16 = getelementptr [1536 x [1536 x float]]* @B, i64 0, i64 %0, i64 %indvar
+  %1 = mul i64 %0, %indvar
+  %mul = trunc i64 %1 to i32
+  %exitcond = icmp ne i64 %indvar, 1536
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %rem = srem i32 %mul, 1024
+  %add = add nsw i32 1, %rem
+  %conv = sitofp i32 %add to double
+  %div = fdiv double %conv, 2.000000e+00
+  %conv4 = fptrunc double %div to float
+  store float %conv4, float* %arrayidx6, align 4
+  %rem8 = srem i32 %mul, 1024
+  %add9 = add nsw i32 1, %rem8
+  %conv10 = sitofp i32 %add9 to double
+  %div11 = fdiv double %conv10, 2.000000e+00
+  %conv12 = fptrunc double %div11 to float
+  store float %conv12, float* %arrayidx16, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc17
+
+for.inc17:                                        ; preds = %for.end
+  %indvar.next2 = add i64 %0, 1
+  br label %for.cond
+
+for.end19:                                        ; preds = %for.cond
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define void @print_array() #0 {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %indvar1 = phi i64 [ %indvar.next2, %for.inc10 ], [ 0, %entry ]
+  %exitcond3 = icmp ne i64 %indvar1, 1536
+  br i1 %exitcond3, label %for.body, label %for.end12
+
+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 ]
+  %arrayidx5 = getelementptr [1536 x [1536 x float]]* @C, i64 0, i64 %indvar1, i64 %indvar
+  %j.0 = trunc i64 %indvar to i32
+  %exitcond = icmp ne i64 %indvar, 1536
+  br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %0 = load %struct._IO_FILE** @stdout, align 8
+  %1 = load float* %arrayidx5, align 4
+  %conv = fpext float %1 to double
+  %call = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %0, i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), double %conv)
+  %rem = srem i32 %j.0, 80
+  %cmp6 = icmp eq i32 %rem, 79
+  br i1 %cmp6, label %if.then, label %if.end
+
+if.then:                                          ; preds = %for.body3
+  %2 = load %struct._IO_FILE** @stdout, align 8
+  %call8 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %2, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %for.body3
+  br label %for.inc
+
+for.inc:                                          ; preds = %if.end
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  %3 = load %struct._IO_FILE** @stdout, align 8
+  %call9 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %3, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end
+  %indvar.next2 = add i64 %indvar1, 1
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
+
+declare i32 @fprintf(%struct._IO_FILE*, i8*, ...) #1
+
+; Function Attrs: nounwind uwtable
+define i32 @main() #0 {
+entry:
+  call void @init_array()
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc28, %entry
+  %indvar3 = phi i64 [ %indvar.next4, %for.inc28 ], [ 0, %entry ]
+  %exitcond6 = icmp ne i64 %indvar3, 1536
+  br i1 %exitcond6, label %for.body, label %for.end30
+
+for.body:                                         ; preds = %for.cond
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc25, %for.body
+  %indvar1 = phi i64 [ %indvar.next2, %for.inc25 ], [ 0, %for.body ]
+  %arrayidx5 = getelementptr [1536 x [1536 x float]]* @C, i64 0, i64 %indvar3, i64 %indvar1
+  %exitcond5 = icmp ne i64 %indvar1, 1536
+  br i1 %exitcond5, label %for.body3, label %for.end27
+
+for.body3:                                        ; preds = %for.cond1
+  store float 0.000000e+00, float* %arrayidx5, align 4
+  br label %for.cond6
+
+for.cond6:                                        ; preds = %for.inc, %for.body3
+  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body3 ]
+  %arrayidx16 = getelementptr [1536 x [1536 x float]]* @A, i64 0, i64 %indvar3, i64 %indvar
+  %arrayidx20 = getelementptr [1536 x [1536 x float]]* @B, i64 0, i64 %indvar, i64 %indvar1
+  %exitcond = icmp ne i64 %indvar, 1536
+  br i1 %exitcond, label %for.body8, label %for.end
+
+for.body8:                                        ; preds = %for.cond6
+  %0 = load float* %arrayidx5, align 4
+  %1 = load float* %arrayidx16, align 4
+  %2 = load float* %arrayidx20, align 4
+  %mul = fmul float %1, %2
+  %add = fadd float %0, %mul
+  store float %add, float* %arrayidx5, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body8
+  %indvar.next = add i64 %indvar, 1
+  br label %for.cond6
+
+for.end:                                          ; preds = %for.cond6
+  br label %for.inc25
+
+for.inc25:                                        ; preds = %for.end
+  %indvar.next2 = add i64 %indvar1, 1
+  br label %for.cond1
+
+for.end27:                                        ; preds = %for.cond1
+  br label %for.inc28
+
+for.inc28:                                        ; preds = %for.end27
+  %indvar.next4 = add i64 %indvar3, 1
+  br label %for.cond
+
+for.end30:                                        ; preds = %for.cond
+  ret i32 0
+}
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
diff --git a/rc1/www/experiments/matmul/matmul.s b/rc1/www/experiments/matmul/matmul.s
new file mode 100644
index 0000000..22ea57b
--- /dev/null
+++ b/rc1/www/experiments/matmul/matmul.s
@@ -0,0 +1,264 @@
+; ModuleID = 'matmul.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-S128"
+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 [1536 x [1536 x float]] zeroinitializer, align 16
+@B = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@stdout = external global %struct._IO_FILE*
+@.str = private unnamed_addr constant [5 x i8] c"%lf \00", align 1
+@C = common global [1536 x [1536 x float]] zeroinitializer, align 16
+@.str1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
+
+; Function Attrs: nounwind uwtable
+define void @init_array() #0 {
+entry:
+  %i = alloca i32, align 4
+  %j = alloca i32, align 4
+  store i32 0, i32* %i, align 4
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc17, %entry
+  %0 = load i32* %i, align 4
+  %cmp = icmp slt i32 %0, 1536
+  br i1 %cmp, label %for.body, label %for.end19
+
+for.body:                                         ; preds = %for.cond
+  store i32 0, i32* %j, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %1 = load i32* %j, align 4
+  %cmp2 = icmp slt i32 %1, 1536
+  br i1 %cmp2, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %2 = load i32* %i, align 4
+  %3 = load i32* %j, align 4
+  %mul = mul nsw i32 %2, %3
+  %rem = srem i32 %mul, 1024
+  %add = add nsw i32 1, %rem
+  %conv = sitofp i32 %add to double
+  %div = fdiv double %conv, 2.000000e+00
+  %conv4 = fptrunc double %div to float
+  %4 = load i32* %j, align 4
+  %idxprom = sext i32 %4 to i64
+  %5 = load i32* %i, align 4
+  %idxprom5 = sext i32 %5 to i64
+  %arrayidx = getelementptr inbounds [1536 x [1536 x float]]* @A, i32 0, i64 %idxprom5
+  %arrayidx6 = getelementptr inbounds [1536 x float]* %arrayidx, i32 0, i64 %idxprom
+  store float %conv4, float* %arrayidx6, align 4
+  %6 = load i32* %i, align 4
+  %7 = load i32* %j, align 4
+  %mul7 = mul nsw i32 %6, %7
+  %rem8 = srem i32 %mul7, 1024
+  %add9 = add nsw i32 1, %rem8
+  %conv10 = sitofp i32 %add9 to double
+  %div11 = fdiv double %conv10, 2.000000e+00
+  %conv12 = fptrunc double %div11 to float
+  %8 = load i32* %j, align 4
+  %idxprom13 = sext i32 %8 to i64
+  %9 = load i32* %i, align 4
+  %idxprom14 = sext i32 %9 to i64
+  %arrayidx15 = getelementptr inbounds [1536 x [1536 x float]]* @B, i32 0, i64 %idxprom14
+  %arrayidx16 = getelementptr inbounds [1536 x float]* %arrayidx15, i32 0, i64 %idxprom13
+  store float %conv12, float* %arrayidx16, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body3
+  %10 = load i32* %j, align 4
+  %inc = add nsw i32 %10, 1
+  store i32 %inc, i32* %j, align 4
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  br label %for.inc17
+
+for.inc17:                                        ; preds = %for.end
+  %11 = load i32* %i, align 4
+  %inc18 = add nsw i32 %11, 1
+  store i32 %inc18, i32* %i, align 4
+  br label %for.cond
+
+for.end19:                                        ; preds = %for.cond
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define void @print_array() #0 {
+entry:
+  %i = alloca i32, align 4
+  %j = alloca i32, align 4
+  store i32 0, i32* %i, align 4
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc10, %entry
+  %0 = load i32* %i, align 4
+  %cmp = icmp slt i32 %0, 1536
+  br i1 %cmp, label %for.body, label %for.end12
+
+for.body:                                         ; preds = %for.cond
+  store i32 0, i32* %j, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc, %for.body
+  %1 = load i32* %j, align 4
+  %cmp2 = icmp slt i32 %1, 1536
+  br i1 %cmp2, label %for.body3, label %for.end
+
+for.body3:                                        ; preds = %for.cond1
+  %2 = load %struct._IO_FILE** @stdout, align 8
+  %3 = load i32* %j, align 4
+  %idxprom = sext i32 %3 to i64
+  %4 = load i32* %i, align 4
+  %idxprom4 = sext i32 %4 to i64
+  %arrayidx = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom4
+  %arrayidx5 = getelementptr inbounds [1536 x float]* %arrayidx, i32 0, i64 %idxprom
+  %5 = load float* %arrayidx5, align 4
+  %conv = fpext float %5 to double
+  %call = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %2, i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), double %conv)
+  %6 = load i32* %j, align 4
+  %rem = srem i32 %6, 80
+  %cmp6 = icmp eq i32 %rem, 79
+  br i1 %cmp6, label %if.then, label %if.end
+
+if.then:                                          ; preds = %for.body3
+  %7 = load %struct._IO_FILE** @stdout, align 8
+  %call8 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %7, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %for.body3
+  br label %for.inc
+
+for.inc:                                          ; preds = %if.end
+  %8 = load i32* %j, align 4
+  %inc = add nsw i32 %8, 1
+  store i32 %inc, i32* %j, align 4
+  br label %for.cond1
+
+for.end:                                          ; preds = %for.cond1
+  %9 = load %struct._IO_FILE** @stdout, align 8
+  %call9 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %9, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))
+  br label %for.inc10
+
+for.inc10:                                        ; preds = %for.end
+  %10 = load i32* %i, align 4
+  %inc11 = add nsw i32 %10, 1
+  store i32 %inc11, i32* %i, align 4
+  br label %for.cond
+
+for.end12:                                        ; preds = %for.cond
+  ret void
+}
+
+declare i32 @fprintf(%struct._IO_FILE*, i8*, ...) #1
+
+; Function Attrs: nounwind uwtable
+define i32 @main() #0 {
+entry:
+  %retval = alloca i32, align 4
+  %i = alloca i32, align 4
+  %j = alloca i32, align 4
+  %k = alloca i32, align 4
+  %t_start = alloca double, align 8
+  %t_end = alloca double, align 8
+  store i32 0, i32* %retval
+  call void @init_array()
+  store i32 0, i32* %i, align 4
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc28, %entry
+  %0 = load i32* %i, align 4
+  %cmp = icmp slt i32 %0, 1536
+  br i1 %cmp, label %for.body, label %for.end30
+
+for.body:                                         ; preds = %for.cond
+  store i32 0, i32* %j, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc25, %for.body
+  %1 = load i32* %j, align 4
+  %cmp2 = icmp slt i32 %1, 1536
+  br i1 %cmp2, label %for.body3, label %for.end27
+
+for.body3:                                        ; preds = %for.cond1
+  %2 = load i32* %j, align 4
+  %idxprom = sext i32 %2 to i64
+  %3 = load i32* %i, align 4
+  %idxprom4 = sext i32 %3 to i64
+  %arrayidx = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom4
+  %arrayidx5 = getelementptr inbounds [1536 x float]* %arrayidx, i32 0, i64 %idxprom
+  store float 0.000000e+00, float* %arrayidx5, align 4
+  store i32 0, i32* %k, align 4
+  br label %for.cond6
+
+for.cond6:                                        ; preds = %for.inc, %for.body3
+  %4 = load i32* %k, align 4
+  %cmp7 = icmp slt i32 %4, 1536
+  br i1 %cmp7, label %for.body8, label %for.end
+
+for.body8:                                        ; preds = %for.cond6
+  %5 = load i32* %j, align 4
+  %idxprom9 = sext i32 %5 to i64
+  %6 = load i32* %i, align 4
+  %idxprom10 = sext i32 %6 to i64
+  %arrayidx11 = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom10
+  %arrayidx12 = getelementptr inbounds [1536 x float]* %arrayidx11, i32 0, i64 %idxprom9
+  %7 = load float* %arrayidx12, align 4
+  %8 = load i32* %k, align 4
+  %idxprom13 = sext i32 %8 to i64
+  %9 = load i32* %i, align 4
+  %idxprom14 = sext i32 %9 to i64
+  %arrayidx15 = getelementptr inbounds [1536 x [1536 x float]]* @A, i32 0, i64 %idxprom14
+  %arrayidx16 = getelementptr inbounds [1536 x float]* %arrayidx15, i32 0, i64 %idxprom13
+  %10 = load float* %arrayidx16, align 4
+  %11 = load i32* %j, align 4
+  %idxprom17 = sext i32 %11 to i64
+  %12 = load i32* %k, align 4
+  %idxprom18 = sext i32 %12 to i64
+  %arrayidx19 = getelementptr inbounds [1536 x [1536 x float]]* @B, i32 0, i64 %idxprom18
+  %arrayidx20 = getelementptr inbounds [1536 x float]* %arrayidx19, i32 0, i64 %idxprom17
+  %13 = load float* %arrayidx20, align 4
+  %mul = fmul float %10, %13
+  %add = fadd float %7, %mul
+  %14 = load i32* %j, align 4
+  %idxprom21 = sext i32 %14 to i64
+  %15 = load i32* %i, align 4
+  %idxprom22 = sext i32 %15 to i64
+  %arrayidx23 = getelementptr inbounds [1536 x [1536 x float]]* @C, i32 0, i64 %idxprom22
+  %arrayidx24 = getelementptr inbounds [1536 x float]* %arrayidx23, i32 0, i64 %idxprom21
+  store float %add, float* %arrayidx24, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body8
+  %16 = load i32* %k, align 4
+  %inc = add nsw i32 %16, 1
+  store i32 %inc, i32* %k, align 4
+  br label %for.cond6
+
+for.end:                                          ; preds = %for.cond6
+  br label %for.inc25
+
+for.inc25:                                        ; preds = %for.end
+  %17 = load i32* %j, align 4
+  %inc26 = add nsw i32 %17, 1
+  store i32 %inc26, i32* %j, align 4
+  br label %for.cond1
+
+for.end27:                                        ; preds = %for.cond1
+  br label %for.inc28
+
+for.inc28:                                        ; preds = %for.end27
+  %18 = load i32* %i, align 4
+  %inc29 = add nsw i32 %18, 1
+  store i32 %inc29, i32* %i, align 4
+  br label %for.cond
+
+for.end30:                                        ; preds = %for.cond
+  ret i32 0
+}
+
+attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
diff --git a/rc1/www/experiments/matmul/runall.sh b/rc1/www/experiments/matmul/runall.sh
new file mode 100755
index 0000000..a8db82e
--- /dev/null
+++ b/rc1/www/experiments/matmul/runall.sh
@@ -0,0 +1,94 @@
+#!/bin/sh -a
+
+echo "--> 1. Create LLVM-IR from C"
+clang -S -emit-llvm matmul.c -o matmul.s
+
+echo "--> 2. Load Polly automatically when calling the 'opt' tool"
+export PATH_TO_POLLY_LIB="~/polly/build/lib/"
+alias opt="opt -load ${PATH_TO_POLLY_LIB}/LLVMPolly.so"
+
+echo "--> 3. Prepare the LLVM-IR for Polly"
+opt -S -polly-canonicalize matmul.s > matmul.preopt.ll
+
+echo "--> 4. Show the SCoPs detected by Polly"
+opt -basicaa -polly-cloog -analyze -q matmul.preopt.ll
+
+echo "--> 5.1 Highlight the detected SCoPs in the CFGs of the program"
+# We only create .dot files, as directly -view-scops directly calls graphviz
+# which would require user interaction to continue the script.
+# opt -basicaa -view-scops -disable-output matmul.preopt.ll
+opt -basicaa -dot-scops -disable-output matmul.preopt.ll
+
+echo "--> 5.2 Highlight the detected SCoPs in the CFGs of the program (print \
+no instructions)"
+# We only create .dot files, as directly -view-scops-only directly calls
+# graphviz which would require user interaction to continue the script.
+# opt -basicaa -view-scops-only -disable-output matmul.preopt.ll
+opt -basicaa -dot-scops-only -disable-output matmul.preopt.ll
+
+echo "--> 5.3 Create .png files from the .dot files"
+for i in `ls *.dot`; do dot -Tpng $i > $i.png; done
+
+echo "--> 6. View the polyhedral representation of the SCoPs"
+opt -basicaa -polly-scops -analyze matmul.preopt.ll
+
+echo "--> 7. Show the dependences for the SCoPs"
+opt -basicaa -polly-dependences -analyze matmul.preopt.ll
+
+echo "--> 8. Export jscop files"
+opt -basicaa -polly-export-jscop matmul.preopt.ll
+
+echo "--> 9. Import the updated jscop files and print the new SCoPs. (optional)"
+opt -basicaa -polly-import-jscop -polly-cloog -analyze matmul.preopt.ll
+opt -basicaa -polly-import-jscop -polly-cloog -analyze matmul.preopt.ll \
+    -polly-import-jscop-postfix=interchanged
+opt -basicaa -polly-import-jscop -polly-cloog -analyze matmul.preopt.ll \
+    -polly-import-jscop-postfix=interchanged+tiled
+opt -basicaa -polly-import-jscop -polly-cloog -analyze matmul.preopt.ll \
+    -polly-import-jscop-postfix=interchanged+tiled+vector
+
+echo "--> 10. Codegenerate the SCoPs"
+opt -basicaa -polly-import-jscop -polly-import-jscop-postfix=interchanged \
+    -polly-codegen \
+    matmul.preopt.ll | opt -O3 > matmul.polly.interchanged.ll
+opt -basicaa -polly-import-jscop \
+    -polly-import-jscop-postfix=interchanged+tiled -polly-codegen \
+    matmul.preopt.ll | opt -O3 > matmul.polly.interchanged+tiled.ll
+opt -basicaa -polly-import-jscop \
+    -polly-import-jscop-postfix=interchanged+tiled+vector -polly-codegen \
+    matmul.preopt.ll -polly-vectorizer=polly\
+    | opt -O3 > matmul.polly.interchanged+tiled+vector.ll
+opt -basicaa -polly-import-jscop \
+    -polly-import-jscop-postfix=interchanged+tiled+vector -polly-codegen \
+    matmul.preopt.ll -polly-vectorizer=polly -enable-polly-openmp\
+    | opt -O3 > matmul.polly.interchanged+tiled+vector+openmp.ll
+opt matmul.preopt.ll | opt -O3 > matmul.normalopt.ll
+
+echo "--> 11. Create the executables"
+llc matmul.polly.interchanged.ll -o matmul.polly.interchanged.s && gcc matmul.polly.interchanged.s \
+    -o matmul.polly.interchanged.exe
+llc matmul.polly.interchanged+tiled.ll -o matmul.polly.interchanged+tiled.s && gcc matmul.polly.interchanged+tiled.s \
+    -o matmul.polly.interchanged+tiled.exe
+llc matmul.polly.interchanged+tiled+vector.ll \
+    -o matmul.polly.interchanged+tiled+vector.s \
+    && gcc matmul.polly.interchanged+tiled+vector.s \
+    -o matmul.polly.interchanged+tiled+vector.exe
+llc matmul.polly.interchanged+tiled+vector+openmp.ll \
+    -o matmul.polly.interchanged+tiled+vector+openmp.s \
+    && gcc -lgomp matmul.polly.interchanged+tiled+vector+openmp.s \
+    -o matmul.polly.interchanged+tiled+vector+openmp.exe
+llc matmul.normalopt.ll -o matmul.normalopt.s && gcc matmul.normalopt.s \
+    -o matmul.normalopt.exe
+
+echo "--> 12. Compare the runtime of the executables"
+
+echo "time ./matmul.normalopt.exe"
+time -f "%E real, %U user, %S sys" ./matmul.normalopt.exe
+echo "time ./matmul.polly.interchanged.exe"
+time -f "%E real, %U user, %S sys" ./matmul.polly.interchanged.exe
+echo "time ./matmul.polly.interchanged+tiled.exe"
+time -f "%E real, %U user, %S sys" ./matmul.polly.interchanged+tiled.exe
+echo "time ./matmul.polly.interchanged+tiled+vector.exe"
+time -f "%E real, %U user, %S sys" ./matmul.polly.interchanged+tiled+vector.exe
+echo "time ./matmul.polly.interchanged+tiled+vector+openmp.exe"
+time -f "%E real, %U user, %S sys" ./matmul.polly.interchanged+tiled+vector+openmp.exe
diff --git a/rc1/www/experiments/matmul/scops.init_array.dot b/rc1/www/experiments/matmul/scops.init_array.dot
new file mode 100644
index 0000000..10a0add
--- /dev/null
+++ b/rc1/www/experiments/matmul/scops.init_array.dot
@@ -0,0 +1,47 @@
+digraph "Scop Graph for 'init_array' function" {
+	label="Scop Graph for 'init_array' function";
+
+	Node0x17d4370 [shape=record,label="{entry:\l  br label %for.cond\l}"];
+	Node0x17d4370 -> Node0x17da5d0;
+	Node0x17da5d0 [shape=record,label="{for.cond:                                         \l  %0 = phi i64 [ %indvar.next2, %for.inc17 ], [ 0, %entry ]\l  %exitcond3 = icmp ne i64 %0, 1536\l  br i1 %exitcond3, label %for.body, label %for.end19\l}"];
+	Node0x17da5d0 -> Node0x17da5f0;
+	Node0x17da5d0 -> Node0x17da650;
+	Node0x17da5f0 [shape=record,label="{for.body:                                         \l  br label %for.cond1\l}"];
+	Node0x17da5f0 -> Node0x17da900;
+	Node0x17da900 [shape=record,label="{for.cond1:                                        \l  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body ]\l  %arrayidx6 = getelementptr [1536 x [1536 x float]]* @A, i64 0, i64 %0, i64 %indvar\l  %arrayidx16 = getelementptr [1536 x [1536 x float]]* @B, i64 0, i64 %0, i64 %indvar\l  %1 = mul i64 %0, %indvar\l  %mul = trunc i64 %1 to i32\l  %exitcond = icmp ne i64 %indvar, 1536\l  br i1 %exitcond, label %for.body3, label %for.end\l}"];
+	Node0x17da900 -> Node0x17da670;
+	Node0x17da900 -> Node0x17da9a0;
+	Node0x17da670 [shape=record,label="{for.body3:                                        \l  %rem = srem i32 %mul, 1024\l  %add = add nsw i32 1, %rem\l  %conv = sitofp i32 %add to double\l  %div = fdiv double %conv, 2.000000e+00\l  %conv4 = fptrunc double %div to float\l  store float %conv4, float* %arrayidx6, align 4\l  %rem8 = srem i32 %mul, 1024\l  %add9 = add nsw i32 1, %rem8\l  %conv10 = sitofp i32 %add9 to double\l  %div11 = fdiv double %conv10, 2.000000e+00\l  %conv12 = fptrunc double %div11 to float\l  store float %conv12, float* %arrayidx16, align 4\l  br label %for.inc\l}"];
+	Node0x17da670 -> Node0x17da8e0;
+	Node0x17da8e0 [shape=record,label="{for.inc:                                          \l  %indvar.next = add i64 %indvar, 1\l  br label %for.cond1\l}"];
+	Node0x17da8e0 -> Node0x17da900[constraint=false];
+	Node0x17da9a0 [shape=record,label="{for.end:                                          \l  br label %for.inc17\l}"];
+	Node0x17da9a0 -> Node0x17d9e70;
+	Node0x17d9e70 [shape=record,label="{for.inc17:                                        \l  %indvar.next2 = add i64 %0, 1\l  br label %for.cond\l}"];
+	Node0x17d9e70 -> Node0x17da5d0[constraint=false];
+	Node0x17da650 [shape=record,label="{for.end19:                                        \l  ret void\l}"];
+	colorscheme = "paired12"
+        subgraph cluster_0x17d3a30 {
+          label = "";
+          style = solid;
+          color = 1
+          subgraph cluster_0x17d4ec0 {
+            label = "";
+            style = filled;
+            color = 3            subgraph cluster_0x17d4180 {
+              label = "";
+              style = solid;
+              color = 5
+              Node0x17da900;
+              Node0x17da670;
+              Node0x17da8e0;
+            }
+            Node0x17da5d0;
+            Node0x17da5f0;
+            Node0x17da9a0;
+            Node0x17d9e70;
+          }
+          Node0x17d4370;
+          Node0x17da650;
+        }
+}
diff --git a/rc1/www/experiments/matmul/scops.init_array.dot.png b/rc1/www/experiments/matmul/scops.init_array.dot.png
new file mode 100644
index 0000000..48a9f38
--- /dev/null
+++ b/rc1/www/experiments/matmul/scops.init_array.dot.png
Binary files differ
diff --git a/rc1/www/experiments/matmul/scops.main.dot b/rc1/www/experiments/matmul/scops.main.dot
new file mode 100644
index 0000000..2a1fc50
--- /dev/null
+++ b/rc1/www/experiments/matmul/scops.main.dot
@@ -0,0 +1,65 @@
+digraph "Scop Graph for 'main' function" {
+	label="Scop Graph for 'main' function";
+
+	Node0x17d21a0 [shape=record,label="{entry:\l  call void @init_array()\l  br label %for.cond\l}"];
+	Node0x17d21a0 -> Node0x17d2020;
+	Node0x17d2020 [shape=record,label="{for.cond:                                         \l  %indvar3 = phi i64 [ %indvar.next4, %for.inc28 ], [ 0, %entry ]\l  %exitcond6 = icmp ne i64 %indvar3, 1536\l  br i1 %exitcond6, label %for.body, label %for.end30\l}"];
+	Node0x17d2020 -> Node0x17d3950;
+	Node0x17d2020 -> Node0x17da500;
+	Node0x17d3950 [shape=record,label="{for.body:                                         \l  br label %for.cond1\l}"];
+	Node0x17d3950 -> Node0x17da760;
+	Node0x17da760 [shape=record,label="{for.cond1:                                        \l  %indvar1 = phi i64 [ %indvar.next2, %for.inc25 ], [ 0, %for.body ]\l  %arrayidx5 = getelementptr [1536 x [1536 x float]]* @C, i64 0, i64 %indvar3, i64 %indvar1\l  %exitcond5 = icmp ne i64 %indvar1, 1536\l  br i1 %exitcond5, label %for.body3, label %for.end27\l}"];
+	Node0x17da760 -> Node0x17db1e0;
+	Node0x17da760 -> Node0x17db250;
+	Node0x17db1e0 [shape=record,label="{for.body3:                                        \l  store float 0.000000e+00, float* %arrayidx5, align 4\l  br label %for.cond6\l}"];
+	Node0x17db1e0 -> Node0x17da740;
+	Node0x17da740 [shape=record,label="{for.cond6:                                        \l  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body3 ]\l  %arrayidx16 = getelementptr [1536 x [1536 x float]]* @A, i64 0, i64 %indvar3, i64 %indvar\l  %arrayidx20 = getelementptr [1536 x [1536 x float]]* @B, i64 0, i64 %indvar, i64 %indvar1\l  %exitcond = icmp ne i64 %indvar, 1536\l  br i1 %exitcond, label %for.body8, label %for.end\l}"];
+	Node0x17da740 -> Node0x17da5a0;
+	Node0x17da740 -> Node0x17da800;
+	Node0x17da5a0 [shape=record,label="{for.body8:                                        \l  %0 = load float* %arrayidx5, align 4\l  %1 = load float* %arrayidx16, align 4\l  %2 = load float* %arrayidx20, align 4\l  %mul = fmul float %1, %2\l  %add = fadd float %0, %mul\l  store float %add, float* %arrayidx5, align 4\l  br label %for.inc\l}"];
+	Node0x17da5a0 -> Node0x17da5c0;
+	Node0x17da5c0 [shape=record,label="{for.inc:                                          \l  %indvar.next = add i64 %indvar, 1\l  br label %for.cond6\l}"];
+	Node0x17da5c0 -> Node0x17da740[constraint=false];
+	Node0x17da800 [shape=record,label="{for.end:                                          \l  br label %for.inc25\l}"];
+	Node0x17da800 -> Node0x17dae20;
+	Node0x17dae20 [shape=record,label="{for.inc25:                                        \l  %indvar.next2 = add i64 %indvar1, 1\l  br label %for.cond1\l}"];
+	Node0x17dae20 -> Node0x17da760[constraint=false];
+	Node0x17db250 [shape=record,label="{for.end27:                                        \l  br label %for.inc28\l}"];
+	Node0x17db250 -> Node0x17dae80;
+	Node0x17dae80 [shape=record,label="{for.inc28:                                        \l  %indvar.next4 = add i64 %indvar3, 1\l  br label %for.cond\l}"];
+	Node0x17dae80 -> Node0x17d2020[constraint=false];
+	Node0x17da500 [shape=record,label="{for.end30:                                        \l  ret i32 0\l}"];
+	colorscheme = "paired12"
+        subgraph cluster_0x17d3f30 {
+          label = "";
+          style = solid;
+          color = 1
+          subgraph cluster_0x17d38d0 {
+            label = "";
+            style = filled;
+            color = 3            subgraph cluster_0x17d3850 {
+              label = "";
+              style = solid;
+              color = 5
+              subgraph cluster_0x17d37d0 {
+                label = "";
+                style = solid;
+                color = 7
+                Node0x17da740;
+                Node0x17da5a0;
+                Node0x17da5c0;
+              }
+              Node0x17da760;
+              Node0x17db1e0;
+              Node0x17da800;
+              Node0x17dae20;
+            }
+            Node0x17d2020;
+            Node0x17d3950;
+            Node0x17db250;
+            Node0x17dae80;
+          }
+          Node0x17d21a0;
+          Node0x17da500;
+        }
+}
diff --git a/rc1/www/experiments/matmul/scops.main.dot.png b/rc1/www/experiments/matmul/scops.main.dot.png
new file mode 100644
index 0000000..4e73701
--- /dev/null
+++ b/rc1/www/experiments/matmul/scops.main.dot.png
Binary files differ
diff --git a/rc1/www/experiments/matmul/scops.print_array.dot b/rc1/www/experiments/matmul/scops.print_array.dot
new file mode 100644
index 0000000..59f02e7
--- /dev/null
+++ b/rc1/www/experiments/matmul/scops.print_array.dot
@@ -0,0 +1,60 @@
+digraph "Scop Graph for 'print_array' function" {
+	label="Scop Graph for 'print_array' function";
+
+	Node0x17d2200 [shape=record,label="{entry:\l  br label %for.cond\l}"];
+	Node0x17d2200 -> Node0x17d4f20;
+	Node0x17d4f20 [shape=record,label="{for.cond:                                         \l  %indvar1 = phi i64 [ %indvar.next2, %for.inc10 ], [ 0, %entry ]\l  %exitcond3 = icmp ne i64 %indvar1, 1536\l  br i1 %exitcond3, label %for.body, label %for.end12\l}"];
+	Node0x17d4f20 -> Node0x17d3680;
+	Node0x17d4f20 -> Node0x17d9fc0;
+	Node0x17d3680 [shape=record,label="{for.body:                                         \l  br label %for.cond1\l}"];
+	Node0x17d3680 -> Node0x17da220;
+	Node0x17da220 [shape=record,label="{for.cond1:                                        \l  %indvar = phi i64 [ %indvar.next, %for.inc ], [ 0, %for.body ]\l  %arrayidx5 = getelementptr [1536 x [1536 x float]]* @C, i64 0, i64 %indvar1, i64 %indvar\l  %j.0 = trunc i64 %indvar to i32\l  %exitcond = icmp ne i64 %indvar, 1536\l  br i1 %exitcond, label %for.body3, label %for.end\l}"];
+	Node0x17da220 -> Node0x17d9ea0;
+	Node0x17da220 -> Node0x17da0f0;
+	Node0x17d9ea0 [shape=record,label="{for.body3:                                        \l  %0 = load %struct._IO_FILE** @stdout, align 8\l  %1 = load float* %arrayidx5, align 4\l  %conv = fpext float %1 to double\l  %call = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %0, i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), double %conv)\l  %rem = srem i32 %j.0, 80\l  %cmp6 = icmp eq i32 %rem, 79\l  br i1 %cmp6, label %if.then, label %if.end\l}"];
+	Node0x17d9ea0 -> Node0x17d9ec0;
+	Node0x17d9ea0 -> Node0x17da060;
+	Node0x17d9ec0 [shape=record,label="{if.then:                                          \l  %2 = load %struct._IO_FILE** @stdout, align 8\l  %call8 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %2, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))\l  br label %if.end\l}"];
+	Node0x17d9ec0 -> Node0x17da060;
+	Node0x17da060 [shape=record,label="{if.end:                                           \l  br label %for.inc\l}"];
+	Node0x17da060 -> Node0x17da200;
+	Node0x17da200 [shape=record,label="{for.inc:                                          \l  %indvar.next = add i64 %indvar, 1\l  br label %for.cond1\l}"];
+	Node0x17da200 -> Node0x17da220[constraint=false];
+	Node0x17da0f0 [shape=record,label="{for.end:                                          \l  %3 = load %struct._IO_FILE** @stdout, align 8\l  %call9 = call i32 (%struct._IO_FILE*, i8*, ...)* @fprintf(%struct._IO_FILE* %3, i8* getelementptr inbounds ([2 x i8]* @.str1, i32 0, i32 0))\l  br label %for.inc10\l}"];
+	Node0x17da0f0 -> Node0x17da080;
+	Node0x17da080 [shape=record,label="{for.inc10:                                        \l  %indvar.next2 = add i64 %indvar1, 1\l  br label %for.cond\l}"];
+	Node0x17da080 -> Node0x17d4f20[constraint=false];
+	Node0x17d9fc0 [shape=record,label="{for.end12:                                        \l  ret void\l}"];
+	colorscheme = "paired12"
+        subgraph cluster_0x17d38f0 {
+          label = "";
+          style = solid;
+          color = 1
+          subgraph cluster_0x17d4030 {
+            label = "Non affine branch in BB 'for.body3' with LHS: %rem and RHS: 79";
+            style = solid;
+            color = 6
+            subgraph cluster_0x17d3fb0 {
+              label = "Non affine branch in BB 'for.body3' with LHS: %rem and RHS: 79";
+              style = solid;
+              color = 5
+              subgraph cluster_0x17d3f30 {
+                label = "Non affine branch in BB 'for.body3' with LHS: %rem and RHS: 79";
+                style = solid;
+                color = 7
+                Node0x17d9ea0;
+                Node0x17d9ec0;
+              }
+              Node0x17da220;
+              Node0x17da060;
+              Node0x17da200;
+            }
+            Node0x17d4f20;
+            Node0x17d3680;
+            Node0x17da0f0;
+            Node0x17da080;
+          }
+          Node0x17d2200;
+          Node0x17d9fc0;
+        }
+}
diff --git a/rc1/www/experiments/matmul/scops.print_array.dot.png b/rc1/www/experiments/matmul/scops.print_array.dot.png
new file mode 100644
index 0000000..e3b973b
--- /dev/null
+++ b/rc1/www/experiments/matmul/scops.print_array.dot.png
Binary files differ
diff --git a/rc1/www/experiments/matmul/scopsonly.init_array.dot b/rc1/www/experiments/matmul/scopsonly.init_array.dot
new file mode 100644
index 0000000..4685c5b
--- /dev/null
+++ b/rc1/www/experiments/matmul/scopsonly.init_array.dot
@@ -0,0 +1,47 @@
+digraph "Scop Graph for 'init_array' function" {
+	label="Scop Graph for 'init_array' function";
+
+	Node0x17d4370 [shape=record,label="{entry}"];
+	Node0x17d4370 -> Node0x17d9de0;
+	Node0x17d9de0 [shape=record,label="{for.cond}"];
+	Node0x17d9de0 -> Node0x17d9e40;
+	Node0x17d9de0 -> Node0x17d9ea0;
+	Node0x17d9e40 [shape=record,label="{for.body}"];
+	Node0x17d9e40 -> Node0x17d9f90;
+	Node0x17d9f90 [shape=record,label="{for.cond1}"];
+	Node0x17d9f90 -> Node0x17d9ff0;
+	Node0x17d9f90 -> Node0x17da050;
+	Node0x17d9ff0 [shape=record,label="{for.body3}"];
+	Node0x17d9ff0 -> Node0x17d9f00;
+	Node0x17d9f00 [shape=record,label="{for.inc}"];
+	Node0x17d9f00 -> Node0x17d9f90[constraint=false];
+	Node0x17da050 [shape=record,label="{for.end}"];
+	Node0x17da050 -> Node0x17da200;
+	Node0x17da200 [shape=record,label="{for.inc17}"];
+	Node0x17da200 -> Node0x17d9de0[constraint=false];
+	Node0x17d9ea0 [shape=record,label="{for.end19}"];
+	colorscheme = "paired12"
+        subgraph cluster_0x17d3a30 {
+          label = "";
+          style = solid;
+          color = 1
+          subgraph cluster_0x17d4ec0 {
+            label = "";
+            style = filled;
+            color = 3            subgraph cluster_0x17d4180 {
+              label = "";
+              style = solid;
+              color = 5
+              Node0x17d9f90;
+              Node0x17d9ff0;
+              Node0x17d9f00;
+            }
+            Node0x17d9de0;
+            Node0x17d9e40;
+            Node0x17da050;
+            Node0x17da200;
+          }
+          Node0x17d4370;
+          Node0x17d9ea0;
+        }
+}
diff --git a/rc1/www/experiments/matmul/scopsonly.init_array.dot.png b/rc1/www/experiments/matmul/scopsonly.init_array.dot.png
new file mode 100644
index 0000000..f101d4d
--- /dev/null
+++ b/rc1/www/experiments/matmul/scopsonly.init_array.dot.png
Binary files differ
diff --git a/rc1/www/experiments/matmul/scopsonly.main.dot b/rc1/www/experiments/matmul/scopsonly.main.dot
new file mode 100644
index 0000000..3b3f328
--- /dev/null
+++ b/rc1/www/experiments/matmul/scopsonly.main.dot
@@ -0,0 +1,65 @@
+digraph "Scop Graph for 'main' function" {
+	label="Scop Graph for 'main' function";
+
+	Node0x17d3950 [shape=record,label="{entry}"];
+	Node0x17d3950 -> Node0x17d21a0;
+	Node0x17d21a0 [shape=record,label="{for.cond}"];
+	Node0x17d21a0 -> Node0x17db9a0;
+	Node0x17d21a0 -> Node0x17da4f0;
+	Node0x17db9a0 [shape=record,label="{for.body}"];
+	Node0x17db9a0 -> Node0x17da5e0;
+	Node0x17da5e0 [shape=record,label="{for.cond1}"];
+	Node0x17da5e0 -> Node0x17da640;
+	Node0x17da5e0 -> Node0x17da6a0;
+	Node0x17da640 [shape=record,label="{for.body3}"];
+	Node0x17da640 -> Node0x17da550;
+	Node0x17da550 [shape=record,label="{for.cond6}"];
+	Node0x17da550 -> Node0x17da5b0;
+	Node0x17da550 -> Node0x17da850;
+	Node0x17da5b0 [shape=record,label="{for.body8}"];
+	Node0x17da5b0 -> Node0x17da8b0;
+	Node0x17da8b0 [shape=record,label="{for.inc}"];
+	Node0x17da8b0 -> Node0x17da550[constraint=false];
+	Node0x17da850 [shape=record,label="{for.end}"];
+	Node0x17da850 -> Node0x17db930;
+	Node0x17db930 [shape=record,label="{for.inc25}"];
+	Node0x17db930 -> Node0x17da5e0[constraint=false];
+	Node0x17da6a0 [shape=record,label="{for.end27}"];
+	Node0x17da6a0 -> Node0x17dada0;
+	Node0x17dada0 [shape=record,label="{for.inc28}"];
+	Node0x17dada0 -> Node0x17d21a0[constraint=false];
+	Node0x17da4f0 [shape=record,label="{for.end30}"];
+	colorscheme = "paired12"
+        subgraph cluster_0x17d3f30 {
+          label = "";
+          style = solid;
+          color = 1
+          subgraph cluster_0x17d38d0 {
+            label = "";
+            style = filled;
+            color = 3            subgraph cluster_0x17d3850 {
+              label = "";
+              style = solid;
+              color = 5
+              subgraph cluster_0x17d37d0 {
+                label = "";
+                style = solid;
+                color = 7
+                Node0x17da550;
+                Node0x17da5b0;
+                Node0x17da8b0;
+              }
+              Node0x17da5e0;
+              Node0x17da640;
+              Node0x17da850;
+              Node0x17db930;
+            }
+            Node0x17d21a0;
+            Node0x17db9a0;
+            Node0x17da6a0;
+            Node0x17dada0;
+          }
+          Node0x17d3950;
+          Node0x17da4f0;
+        }
+}
diff --git a/rc1/www/experiments/matmul/scopsonly.main.dot.png b/rc1/www/experiments/matmul/scopsonly.main.dot.png
new file mode 100644
index 0000000..3263424
--- /dev/null
+++ b/rc1/www/experiments/matmul/scopsonly.main.dot.png
Binary files differ
diff --git a/rc1/www/experiments/matmul/scopsonly.print_array.dot b/rc1/www/experiments/matmul/scopsonly.print_array.dot
new file mode 100644
index 0000000..c900d0f
--- /dev/null
+++ b/rc1/www/experiments/matmul/scopsonly.print_array.dot
@@ -0,0 +1,60 @@
+digraph "Scop Graph for 'print_array' function" {
+	label="Scop Graph for 'print_array' function";
+
+	Node0x17d2200 [shape=record,label="{entry}"];
+	Node0x17d2200 -> Node0x17d4f20;
+	Node0x17d4f20 [shape=record,label="{for.cond}"];
+	Node0x17d4f20 -> Node0x17d9fd0;
+	Node0x17d4f20 -> Node0x17da030;
+	Node0x17d9fd0 [shape=record,label="{for.body}"];
+	Node0x17d9fd0 -> Node0x17da120;
+	Node0x17da120 [shape=record,label="{for.cond1}"];
+	Node0x17da120 -> Node0x17da180;
+	Node0x17da120 -> Node0x17da1e0;
+	Node0x17da180 [shape=record,label="{for.body3}"];
+	Node0x17da180 -> Node0x17da090;
+	Node0x17da180 -> Node0x17da0f0;
+	Node0x17da090 [shape=record,label="{if.then}"];
+	Node0x17da090 -> Node0x17da0f0;
+	Node0x17da0f0 [shape=record,label="{if.end}"];
+	Node0x17da0f0 -> Node0x17da390;
+	Node0x17da390 [shape=record,label="{for.inc}"];
+	Node0x17da390 -> Node0x17da120[constraint=false];
+	Node0x17da1e0 [shape=record,label="{for.end}"];
+	Node0x17da1e0 -> Node0x17d9e40;
+	Node0x17d9e40 [shape=record,label="{for.inc10}"];
+	Node0x17d9e40 -> Node0x17d4f20[constraint=false];
+	Node0x17da030 [shape=record,label="{for.end12}"];
+	colorscheme = "paired12"
+        subgraph cluster_0x17d38f0 {
+          label = "";
+          style = solid;
+          color = 1
+          subgraph cluster_0x17d4030 {
+            label = "Non affine branch in BB 'for.body3' with LHS: %rem and RHS: 79";
+            style = solid;
+            color = 6
+            subgraph cluster_0x17d3fb0 {
+              label = "Non affine branch in BB 'for.body3' with LHS: %rem and RHS: 79";
+              style = solid;
+              color = 5
+              subgraph cluster_0x17d3f30 {
+                label = "Non affine branch in BB 'for.body3' with LHS: %rem and RHS: 79";
+                style = solid;
+                color = 7
+                Node0x17da180;
+                Node0x17da090;
+              }
+              Node0x17da120;
+              Node0x17da0f0;
+              Node0x17da390;
+            }
+            Node0x17d4f20;
+            Node0x17d9fd0;
+            Node0x17da1e0;
+            Node0x17d9e40;
+          }
+          Node0x17d2200;
+          Node0x17da030;
+        }
+}
diff --git a/rc1/www/experiments/matmul/scopsonly.print_array.dot.png b/rc1/www/experiments/matmul/scopsonly.print_array.dot.png
new file mode 100644
index 0000000..b0d4b45
--- /dev/null
+++ b/rc1/www/experiments/matmul/scopsonly.print_array.dot.png
Binary files differ
diff --git a/rc1/www/favicon.ico b/rc1/www/favicon.ico
new file mode 100644
index 0000000..0638d5b
--- /dev/null
+++ b/rc1/www/favicon.ico
Binary files differ
diff --git a/rc1/www/get_started.html b/rc1/www/get_started.html
new file mode 100644
index 0000000..c025f8d
--- /dev/null
+++ b/rc1/www/get_started.html
@@ -0,0 +1,201 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+  <title>Polly - Getting Started</title>
+  <link type="text/css" rel="stylesheet" href="menu.css" />
+  <link type="text/css" rel="stylesheet" href="content.css" />
+</head>
+<body>
+
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+
+<h1>Getting Started: Building and Installing Polly</h1>
+
+<h2> Automatic </h2>
+
+There is a <a href="polly.sh">script</a> available to automatically checkout,
+update, build, and test Polly. This script contains all the commands that are
+subsequently described on this webpage. The automatic installation consists
+of four simple steps:
+
+<pre>
+mkdir polly &amp;&amp; cd polly
+wget http://polly.llvm.org/polly.sh
+chmod +x polly.sh
+./polly.sh
+</pre>
+
+<h2> Manual </h2>
+<h3 id="source"> Get the code </h3>
+
+The Polly source code is available in the LLVM SVN repository as well as through
+an official git mirror. It is added to the <em>tools</em>
+directory of the llvm sources.
+<b>Polly and LLVM need to be checked out at the same time. Checkouts
+   from different dates may not work!</b>
+<h4>Set the directory layout:</h4>
+<pre>
+export BASE=`pwd`
+export LLVM_SRC=${BASE}/llvm
+export POLLY_SRC=${LLVM_SRC}/tools/polly
+
+# Also build the matching clang-version (optional)
+export CLANG_SRC=${LLVM_SRC}/tools/clang
+</pre>
+
+<h4>SVN</h4>
+<pre>
+svn checkout http://llvm.org/svn/llvm-project/llvm/trunk ${LLVM_SRC}
+svn checkout http://llvm.org/svn/llvm-project/polly/trunk ${POLLY_SRC}
+
+# Also build the matching clang-version (optional)
+svn checkout http://llvm.org/svn/llvm-project/cfe/trunk ${CLANG_SRC}
+</pre>
+<h4>GIT</h4>
+<pre>
+git clone http://llvm.org/git/llvm.git ${LLVM_SRC}
+git clone http://llvm.org/git/polly.git ${POLLY_SRC}
+
+# Also build the matching clang-version (optional)
+git clone http://llvm.org/git/clang.git ${CLANG_SRC}
+</pre>
+<h3 id="prerequisites"> Prerequisites </h3>
+<ul>
+<li>libgmp</li>
+<li>CLooG/isl</li>
+</ul>
+
+<h4> libgmp </h4>
+Install libgmp (library + developer package) through the package management
+system of your operating system.
+
+<h4> CLooG/isl</h4>
+
+Polly is tested with a fixed version of <a href="http://www.cloog.org">CLooG</a>
+and isl. To obtain the source code of CLooG (including isl) use
+checkout_cloog.sh as available in ${POLLY_SRC}/utils/checkout_cloog.sh.
+
+<h4>Set the directory layout:</h4>
+<pre>
+export CLOOG_SRC=${BASE}/cloog_src
+export CLOOG_INSTALL=${BASE}/cloog_install
+</pre>
+
+<h4> First installation</h4>
+<pre>
+${POLLY_SRC}/utils/checkout_cloog.sh ${CLOOG_SRC}
+cd ${CLOOG_SRC}
+./configure --prefix=${CLOOG_INSTALL}
+make
+make install
+cd ${BASE}
+</pre>
+
+<h4> Update the installation</h4>
+
+Updating CLooG may become necessary, if Polly uses a feature
+only available in a recent version of CLooG.
+<pre>
+${POLLY_SRC}/utils/checkout_cloog.sh ${CLOOG_SRC}
+cd ${CLOOG_SRC}
+make
+make install
+cd ${BASE}
+</pre>
+
+<h3 id="build">Build Polly</h3>
+
+To build Polly you can either use the autoconf or the cmake build system. At the
+moment only the autoconf build system allows to run the llvm test-suite and only
+the cmake build system allows to run 'make check-polly'.
+
+<h4>Set the directory layout:</h4>
+<pre>
+export LLVM_BUILD=${BASE}/llvm_build
+mkdir ${LLVM_BUILD}
+cd ${LLVM_BUILD}
+</pre>
+
+<h4>CMake</h4>
+
+<pre>
+cmake -DCMAKE_PREFIX_PATH=${CLOOG_INSTALL} ${LLVM_SRC}
+make
+</pre>
+
+<h4> Autoconf </h4>
+
+<pre>
+${LLVM_SRC}/configure --with-cloog=${CLOOG_INSTALL} --with-isl=${CLOOG_INSTALL}
+make
+</pre>
+
+<h3> Test Polly</h3>
+
+<p>To check if Polly works correctly you can run <em>make check-polly</em> for the
+cmake build or <em>make check-polly -C tools/polly/test/</em> for the autoconf
+build.
+
+<p>If you get something like <em>"... libisl.so.9: cannot open shared object file .."</em>,
+it is because you installed cloog to a non-standard path, and libisl/libcloog
+could not be found. To solve this issue, you need to append the path of parent
+directory of libisl/libcloog, i.e. ${CLOOG_INSTALL}/lib, to LD_LIBRARY_PATH by:
+
+<pre>export LD_LIBRARY_PATH=${CLOOG_INSTALL}/lib:$LD_LIBRARY_PATH</pre>
+
+<p>Also try the above command if you get errors such as:
+<code>undefined symbol: isl_ctx_get_max_operations</code>
+
+<p>If you get an error in one of the python files, your system probably uses python3
+as default python interpreter. This is the case, for instance, under Arch Linux.
+To solve this issue, run <code>cmake</code> again, but with the added argument:
+<code>-DPYTHON_EXECUTABLE=/usr/bin/python2</code> (replace <code>/usr/bin/python2</code>
+with the location of the python2 interpreter under your system).
+
+<pre>cmake -DCMAKE_PREFIX_PATH=${CLOOG_INSTALL} -DPYTHON_EXECUTABLE=/usr/bin/python2 ${LLVM_SRC}</pre>
+
+<h2> Optional Features </h2>
+
+<h3> Pocc </h3>
+
+<p>Polly can use <a href="http://www.cse.ohio-state.edu/~pouchet/software/pocc">
+PoCC</a> as an external optimizer. PoCC is a research project that provides
+an integrated version of <a href="http://pluto-compiler.sf.net">Pluto</a>, an
+advanced data-locality and tileability optimizer. Polly includes internally
+already a similar optimizer, such that in general PoCC is not needed. It is
+only recommended for people who want to compare against a different
+optimizer.</a>
+<br/>
+To use it install PoCC 1.0-rc3.1 (the one with Polly support) and add it to your PATH. 
+
+<pre>
+wget <a
+href="http://www.cse.ohio-state.edu/~pouchet/software/pocc/download/pocc-1.0-rc3.1-full.tar.gz">http://www.cse.ohio-state.edu/~pouchet/software/pocc/download/pocc-1.0-rc3.1-full.tar.gz</a>
+tar xzf pocc-1.0-rc3.1-full.tar.gz
+cd pocc-1.0-rc3.1
+./install.sh
+export PATH=$PATH:`pwd`/bin
+</pre>
+
+You also need to install scoplib-0.2.0 and provide its location to
+Polly's cmake or configure call.
+
+<pre>
+wget <a
+href="http://www.cse.ohio-state.edu/~pouchet/software/pocc/download/modules/scoplib-0.2.0.tar.gz"
+>http://www.cse.ohio-state.edu/~pouchet/software/pocc/download/modules/scoplib-0.2.0.tar.gz</a>
+tar xzf  scoplib-0.2.0.tar.gz
+cd scoplib-0.2.0
+./configure --enable-mp-version --prefix=/path/to/scoplib/installation
+make && make install
+</pre>
+</div>
+</div>
+
+</body>
+</html>
diff --git a/rc1/www/images/architecture.png b/rc1/www/images/architecture.png
new file mode 100644
index 0000000..fdd26a0
--- /dev/null
+++ b/rc1/www/images/architecture.png
Binary files differ
diff --git a/rc1/www/images/header-background.png b/rc1/www/images/header-background.png
new file mode 100644
index 0000000..d736b99
--- /dev/null
+++ b/rc1/www/images/header-background.png
Binary files differ
diff --git a/rc1/www/images/iit-madras.png b/rc1/www/images/iit-madras.png
new file mode 100644
index 0000000..caf90ab
--- /dev/null
+++ b/rc1/www/images/iit-madras.png
Binary files differ
diff --git a/rc1/www/images/osu.png b/rc1/www/images/osu.png
new file mode 100644
index 0000000..154a04b
--- /dev/null
+++ b/rc1/www/images/osu.png
Binary files differ
diff --git a/rc1/www/images/performance/parallel-large.png b/rc1/www/images/performance/parallel-large.png
new file mode 100644
index 0000000..76261bb
--- /dev/null
+++ b/rc1/www/images/performance/parallel-large.png
Binary files differ
diff --git a/rc1/www/images/performance/parallel-small.png b/rc1/www/images/performance/parallel-small.png
new file mode 100644
index 0000000..3c9f6ba
--- /dev/null
+++ b/rc1/www/images/performance/parallel-small.png
Binary files differ
diff --git a/rc1/www/images/performance/sequential-large.png b/rc1/www/images/performance/sequential-large.png
new file mode 100644
index 0000000..5c88354
--- /dev/null
+++ b/rc1/www/images/performance/sequential-large.png
Binary files differ
diff --git a/rc1/www/images/performance/sequential-small.png b/rc1/www/images/performance/sequential-small.png
new file mode 100644
index 0000000..94b248d
--- /dev/null
+++ b/rc1/www/images/performance/sequential-small.png
Binary files differ
diff --git a/rc1/www/images/sys-uni.png b/rc1/www/images/sys-uni.png
new file mode 100644
index 0000000..e6b84e1
--- /dev/null
+++ b/rc1/www/images/sys-uni.png
Binary files differ
diff --git a/rc1/www/images/uni-passau.png b/rc1/www/images/uni-passau.png
new file mode 100644
index 0000000..4bbfa21
--- /dev/null
+++ b/rc1/www/images/uni-passau.png
Binary files differ
diff --git a/rc1/www/images/video-summit-2011.png b/rc1/www/images/video-summit-2011.png
new file mode 100644
index 0000000..dc72e7c
--- /dev/null
+++ b/rc1/www/images/video-summit-2011.png
Binary files differ
diff --git a/rc1/www/index.html b/rc1/www/index.html
new file mode 100644
index 0000000..67367ef
--- /dev/null
+++ b/rc1/www/index.html
@@ -0,0 +1,374 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Polyhedral optimizations for LLVM</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+  <script src="video-js/video.js" type="text/javascript" charset="utf-8"></script>
+  <script type="text/javascript">
+    VideoJS.setupAllWhenReady();
+  </script>
+
+  <!-- Include the VideoJS Stylesheet -->
+  <link rel="stylesheet" href="video-js/video-js.css" type="text/css" media="screen" title="Video JS">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>About Polly</h1>
+  <!--*********************************************************************-->
+
+  <p> Polly is a high-level loop and data-locality optimizer and optimization
+  infrastructure for LLVM. It uses an abstract mathematical representation based
+  on integer polyhedra to analyze and optimize the memory access pattern of a
+  program. We currently perform classical loop transformations, especially
+  tiling and loop fusion to improve data-locality. Polly can also exploit
+  OpenMP level parallelism, expose SIMDization opportunities. Work has also be
+  done in the area of automatic GPU code generation.</p>
+
+  For many users, however, it's not the existing optimizations in Polly that are
+  of most interest, but the new analyses and optimizations enabled by the Polly
+  infrastructure. At
+  <a href="http://polyhedral.info">polyhedral.info</a> you can get an idea of
+  what has already been done and what is possible in the context of polyhedral
+  compilation.
+
+  <p>
+  <div class="video-js-box" style="margin:auto; margin-top: 1em; margin-bottom: 1em">
+    <video id="example_video_2" class="video-js" width="640" height="360"
+           controls="controls" preload="auto"
+           poster="images/video-summit-2011.png">
+      <source
+           src="http://www.grosser.es/publications/grosser-2011--Polly-First-successful-optimizations--LLVM-Developer-Meeting.mp4"
+           type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
+      <source
+           src="http://www.grosser.es/publications/grosser-2011--Polly-First-successful-optimizations--LLVM-Developer-Meeting.webm"
+           type='video/webm; codecs="vp8, vorbis"'>
+      <object id="flash_fallback_2" class="vjs-flash-fallback" width="640"
+      height="360" type="application/x-shockwave-flash"
+        data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
+        <param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
+        <param name="allowfullscreen" value="true" />
+        <param name="flashvars"
+        value='config={"playlist":["publications/images/video-summit-2011.png",
+        {"url":
+        "http://www.grosser.es/publications/grosser-2011--Polly-First-successful-optimizations--LLVM-Developer-Meeting.mp4","autoPlay":false,"autoBuffering":true}]}'
+        />
+        <img src="images/video-summit-2011.png" width="640" height="360" alt="Poster Image"
+          title="No video playback capabilities." />
+      </object>
+    </video>
+  </div>
+
+  <!--=====================================================================-->
+  <h2>News</h2>
+  <!--=====================================================================-->
+
+  <table id="news">
+  <tr><td><b>2014</b></td></tr>
+  <tr><td width="120"><p>June</p></td>
+  <td>
+  <h4>Polly can be built without GPL licensed software</h4> After Sebastian
+  Pop's
+  and David Peixotto's (both Qualcomm) recent <a
+  href="http://repo.or.cz/w/isl.git/commit/60703e3ee89b9d5d4d1afb6a3f611292c0884574">commit</a>
+  to isl, isl's latest development version can be built with imath instead of
+  GMP. With both CLooG and gmp having become optional, the last obilgatory
+  dependency to GPL licensed software has been removed. Now Polly only depends
+  on isl (and the included imath), which are both MIT licensed.
+  </td>
+  </tr>
+  <tr><td width="120"><p>April</p></td>
+  <td>
+  <h4>Polly Phone Call - 23April</h4>
+  We had a polly phone call about delinearizing array accesses (II)<a
+  href="https://docs.google.com/document/d/1IZewI8Up0iEkCNIPr6gVtwJxF7RV6KmXkdwOBM_Q5Cs/edit?usp=sharing ">Meeting notes</a> are available online.
+  <h4>Polly Phone Call - 17th April</h4>
+  We had a polly phone call about delinearizing array accesses <a
+  href="https://docs.google.com/document/d/14d3ehkH2MsvBdqsEOSYjysH0Ztyzb75Lp843hnxh2IA/edit?usp=sharing">Meeting notes</a> are available online.
+  <h4>Polly Phone Call - 10th April</h4>
+  We had a polly phone call. <a
+  href="https://docs.google.com/document/d/12W-qZjiZGEQ_lVrob4OzvKJI3EooonC-ap1b9f9KCUE/edit?usp=sharing">Meeting notes</a> are available online.
+  <h4>Polly Phone Call - 4th April</h4>
+  We had a polly phone call. <a
+  href="https://drive.google.com/folderview?id=0B7OMOXTgCYIUWkpJbWVJcW04ams&usp=sharing">Meeting notes</a> are available online.
+  </td>
+  </tr>
+  <tr><td width="120"><p>March</p></td>
+  <td>
+  <h4>Static link Polly into tools</h4> Polly can now be configured with 'cmake
+  -D LINK_POLLY_INTO_TOOLS:Bool=ON' to be statically linked in the tools (opt,
+  bugpoint, and clang.) This makes it easier to use polly without having to load
+  a shared library, and it also reduces the complexity of compiling Polly on
+  Windows.
+  </td>
+  </tr>
+  <tr><td width="120"><p>February</p></td>
+  <td>
+  <h4>Polly presentation at FOSDEM 2014</h4> Polly was <a
+  href="https://fosdem.org/2014/schedule/event/polly/">presented</a> at the
+  FOSDEM LLVM developer's meeting.
+  <h4>New LLVM test-suite buildbots</h4>
+  The set of <a href="http://lab.llvm.org:8011/console?category=polly">Polly
+  buildbots</a> has been extended. We now have 16 new blades that track
+  correctness and performance when compiling the LLVM test-suite. For now five
+  of them are used to provide <a
+  href="http://llvm.org/perf/db_default/v4/nts/22463">fine granularity
+  reports</a> (almost per-commit)
+  for 'clang -O3' (no polly). We also have six machines that track different
+  configurations of polly.
+  </td>
+  </tr>
+  <tr><td width="120"><p>January</p></td>
+  <td>
+  <h4>islplot released</h4>
+  <a href="https://github.com/tobig/islplot">islplot</a> is a library that
+  generates illustrations of integer sets and maps. It relies on <a
+  href="http://repo.or.cz/w/isl.git">isl</a> to model the integer sets and uses the <a
+  href="https://pypi.python.org/pypi/islpy">islpy</a> Python bindings to access
+  them. Plotting is performed with <a
+  href="http://matplotlib.org">matplotlib</a>. The following <a
+  href="http://nbviewer.ipython.org/github/tobig/islplot/blob/master/notebooks/islplot-examples.ipynb">
+  Examples</a> show its use.
+  </td>
+  </tr>
+  <tr><td><b>2013</b></td></tr>
+  <tr><td width="120"><p>November</p></td>
+  <td>
+  <h4>Loop optimization BoF at upcoming LLVM conference</h4>
+  At the upcoming <a href="http://llvm.org/devmtg/2013-11/#bof5">LLVM conference
+  </a> there will be a loop optimization BoF discussing Polly and other high
+  level loop optimizers.
+  </td>
+  </tr>
+  <tr><td width="120"><p>October</p></td>
+  <td>
+  <h4>Automatic code coverage and static analysis tests</h4>
+  Sylvestre Ledru set up automatic tests for <a
+  href="http://buildd-clang.debian.net/coverage/">code coverage</a> and
+  <a href="http://buildd-clang.debian.net/scan-build/">static analysis</a>
+  which run at least once a day and which include results for Polly.
+  <h4>Move to CLooG 0.18.1 and isl 0.12.1</h4>
+  With the move to an isl 0.12 version Polly can be compiled without the
+  need to link directly to GMP (if isl is used for code generation). Currently
+  isl is still internally using GMP, but private patches exist to also remove
+  this dependency. Without the use of GMP, a <b>GPL free</b> version of Polly
+  is possible.
+  </td></tr>
+
+  <tr><td><b>2012</b></td></tr>
+  <tr><td width="120"><p>December</p></td>
+  <td>
+  <h4> New publication in the PPL Journal
+     </h4>
+
+      We published a journal version of the Polly paper named
+      <em>
+      Polly - Performing polyhedral optimizations on a low-level intermediate
+      representation</em> in the Parallel Processing Letters 2012.
+  </td></tr>
+  <tr><td width="120"><p>September</p></td>
+  <td>
+  <h4>Experimental support for the <b>new isl code generator</b></h4>
+     The code generator can be parameterized on a fine-grained
+     level. It gives direct control for example over unrolling, the amount of
+     control overhead and the code size. It can also be used to
+     create loops to handle border conditions or to perform full-partial tile
+     separation.<br />
+     We also relicensed isl under the <b>MIT license</b>. This means, with the
+     exception of GMP (LGPL), there is no other (L)GPL licensed software used in
+     Polly. The
+     use of GMP is limited to a well defined interface. Replacing it with
+     a BSD licensed replacement is a tractable engineering project we would
+     be very interested in. For more information about isl see the <a
+     href="http://www.kotnet.org/~skimo/isl/manual.pdf">isl manual</a>.
+     </p>
+  </td></tr>
+  <tr><td width="120"><p>July</p></td>
+  <td>
+  <p> Polly can now be directly linked to the <a
+href="http://pluto-compiler.sourceforge.net/">Pluto optimizer</a>. We were
+already able to perform Pluto-like optimizations with Polly, as a similar
+algorithm was added to isl half a year ago. However, being able to directly
+compare with the original implementation will not only bring in competition in
+the optimizer field. It will also allow new experiments with a cutting edge
+research tool.<br \>
+  This support was on of the outcomes of the 1-day Polly workshop and the
+  following week of joint work at IISC Bangalore and in cooperation with
+  AMD India.
+  </td></tr>
+  <td>
+  </td></tr>
+  <tr><td width="120"><p>February</p></td>
+  <td>
+  <p>Polly is an official LLVM project, reachable at <a
+  href="http://polly.llvm.org">http://polly.llvm.org</a></p>
+  </td></tr>
+  <tr><td width="120"><p>January</p></td>
+  <td>
+  <p>Improved support for the isl scheduling optimizer</p>
+  Polly can now automatically optimize all <a
+  href="http://www.cse.ohio-state.edu/~pouchet/software/polybench/">polybench
+  2.0</a> kernels without the help of
+  an external optimizer. The compile time is reasonable and we can show
+  notable speedups for various kernels.
+  </td></tr>
+
+  <tr>
+  <tr><td><b><br/>2011</b></td></tr>
+  <tr><td width="120"><p>November</p></td>
+  <td>
+  <p>
+  Talk at the <a href="http://llvm.org/devmtg/2011-11/">
+      LLVM Developer Meeting 2011</a></p>
+  New SCEV parser<br>
+  (Allows parameters in array subscript and max/signextend)
+  </td></tr>
+
+  <tr>
+  <td><p>October</p></td>
+  <td>
+  <p>Polly can use the isl schedule optimizer<br>
+    (The optimizer is similar to the one in Pluto, but it is part of isl)
+  </p>
+  </td></tr>
+
+  <tr>
+  <td><p>August</p></td>
+  <td>
+  <p>
+  <a href="example_load_Polly_into_clang.html">Use Polly as
+  clang plugin</a></p>
+  </td>
+  </tr>
+
+  <tr>
+  <td><p>July</p></td>
+  <td>
+  <p> Polly builder as part of the <a
+  href="http://lab.llvm.org:8011/console">LLVM Buildbots</a>
+  </p>
+  </td>
+  </tr>
+
+  <tr>
+  <td><p>June</p></td>
+  <td>
+  <p><a href="http://www.grosser.es">Tobias</a> is founded for
+  three years by a <a
+  href="http://research.google.com/university/relations/fellowship_recipients.html">
+  Google Europe Fellowship in Efficient Computing</a>.
+  </p>
+  </td>
+  </tr>
+
+  <tr>
+  <td><p>May </p></td>
+  <td><p><a href="http://www.grosser.es">Tobias</a>' diploma thesis and
+  Raghesh's master thesis. See our <a 
+  href="publications.html">list of publications</a>.</p></td>
+  </tr>
+
+  <tr>
+  <td><p>April</p></td>
+  <td><p>Polly moves to the LLVM infrastructure (svn, bugtracker)</p></td>
+  </tr>
+
+  <tr>
+  <td><p>March</p></td>
+  <td><p>Presentation at <a
+  href="http://impact2011.inrialpes.fr/">CGO/IMPACT</a></p>
+  <p>Polly can compile
+  polybench 2.0 with vectorization and OpenMP code generation</p>
+  </td>
+  </tr>
+  <tr>
+  <td><p>Februar</p></td>
+  <td><p>pollycc - a script to automatically compile with
+  polyhedral optimizations </p></td>
+  </tr>
+
+  <tr>
+  <td><p> Januar</p></td>
+  <td><p> Basic OpenMP support, Alias analysis integration,
+  Pluto/POCC support </p></td>
+  </tr>
+
+  <tr><td><b><br>2010</b></td></tr>
+  <tr>
+  <td><p> Dezember </p></td>
+  <td><p>Basic vectorization support </p></td>
+  </tr>
+
+  <tr>
+  <td><p> November </p></td>
+  <td><p>Talk at the <a
+  href="http://llvm.org/devmtg/2010-11/">LLVM Developer Meeting</a> </p></td>
+  </tr>
+
+  <tr>
+  <td><p>October</p></td>
+  <td><p>Dependency analysis </p>
+  <p>Finished Phase 1 - Get something working </p>
+  <p>Support scalar dependences and sequential SCoPs </p>
+  </td>
+  </tr>
+
+  <tr>
+  <td><p>August</p></td>
+  <td><p>RegionInfo pass committed to LLVM</p>
+  <p>llvm-test suite compiles </p>
+  </td>
+  </tr>
+
+  <tr>
+  <td><p>July</p></td>
+  <td><p>Code generation works for normal SCoPs.  </p></td>
+  </tr>
+
+  <tr>
+  <td><p>May</p></td>
+  <td><p>The CLooG AST can be parsed.</p>
+  </td>
+  </tr>
+
+  <tr>
+  <td><p>April</p></td>
+  <td><p>SCoPs can automatically be detected. </p></td>
+  </tr>
+
+  <tr>
+  <td><p>March</p></td>
+  <td><p>The RegionInfo framework is almost completed.  </p></td>
+  </tr>
+
+  <tr>
+  <td><p>February</p></td>
+  <td><p>Translate a simple loop to Polly-IR and regenerate a loop structure
+         with CLooG works.  </p>
+  <p>ISL and CLooG are integrated.  </p></td>
+  </tr>
+
+  </tr>
+
+  <tr>
+  <td><p>January</p></td>
+  <td><p>The RegionInfo pass is finished.  </p></td>
+  </tr>
+
+  <tr><td><b><br>2009</b></td></tr>
+  <tr>
+  <td><p>End of the year</p></td>
+  <td><p>Work on the infrastructure started.  </p></td>
+  </tr>
+  </table>
+  </ul>
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/menu.css b/rc1/www/menu.css
new file mode 100644
index 0000000..d74c607
--- /dev/null
+++ b/rc1/www/menu.css
@@ -0,0 +1,86 @@
+/***************/
+/* page layout */
+/***************/
+
+#menu {
+        line-height:1.3;
+	width: 18em;
+        float: left;
+        margin-right: 3em;
+        padding: 1em;
+        background-color: #edf7ff;
+}
+/**************/
+/* menu style */
+/**************/
+
+#menu .submenu {
+	display:block;
+        padding-top: 0.2em;
+        font-bottom: 1.2em;
+}
+
+/*
+ * Color scheme
+ * blue: #556293
+ * red:  #931e24
+ * brown: #937155
+ * green: #24931e
+ */
+
+#menu label {
+	display:block;
+        color: white;
+        margin-bottom: 0.4em;
+        margin-top: 0.4em;
+	font-weight: bold;
+        font-size: 1.1em;
+	text-align: center;
+	background-color: #3b4567;
+        -webkit-border-radius: 5px;
+        -moz-border-radius: 5px;
+        border-radius: 5px;
+}
+
+#menu a {
+	padding:0 .2em;
+        -webkit-border-radius: 5px;
+        -moz-border-radius: 5px;
+        border-radius: 5px;
+	display:block;
+        font-weight: bold;
+	text-decoration: none;
+        color: #3b4567;
+}
+
+
+#menu a:hover {
+        background: #f35555;
+        color: #3b4567;
+}
+#menu a:visited {
+}
+
+#menu .submenu2 {
+        margin-top: 2em;
+}
+
+#menu .submenu2 label {
+	background-color: #f35555;
+}
+
+#menu a.rss_item:hover {
+  background-color: transparent;
+  color: none;
+}
+
+.rss_item {
+  line-height: 0.5em;
+  padding-top: 1em;
+}
+
+.rss_date {
+  font-size: 0.8em;
+  color: #f35555;
+  padding-left: 0.4em;
+}
diff --git a/rc1/www/menu.html.incl b/rc1/www/menu.html.incl
new file mode 100644
index 0000000..b4e162b
--- /dev/null
+++ b/rc1/www/menu.html.incl
@@ -0,0 +1,66 @@
+<div id="head" style="position: relative">
+<h1><span><a href="/">Polly</a></span></h1>
+<h2><span>LLVM Framework for High-Level Loop and Data-Locality
+Optimizations</span></h2>
+
+
+<p> Hexagonal tiling in 3D</p>
+
+</div>
+<div id="menu">
+  <div class="submenu">
+    <label>Information</label>
+    <a href="/index.html">About Polly</a>
+    <a href="/documentation.html">Documentation</a>
+    <a href="/performance.html">Performance</a>
+    <a href="/publications.html">Publications</a>
+    <a href="/contributors.html">Contributors</a>
+    <a href="/todo.html">TODO</a>
+  </div>
+
+  <div class="submenu">
+    <label>Development </label>
+    <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">
+      Mailing List (patches)
+    </a>
+    <a href="http://groups.google.com/group/polly-dev">Mailing List (discussion)</a>
+    <a href="/bugs.html">Bug Reports</a>
+    <a href="http://lab.llvm.org:8011/console?category=polly">Buildbot</a>
+    <a href="http://buildd-clang.debian.net/coverage/">Code Coverage</a>
+    <a href="http://buildd-clang.debian.net/scan-build/">Static analysis</a>
+  </div>
+
+  <div class="submenu">
+    <label>The Code</label>
+    <a href="/get_started.html">Get and Install</a>
+    <a href="http://llvm.org/viewvc/llvm-project/polly/trunk/">
+      Browse (ViewVC)
+    </a>
+    <a href="http://repo.or.cz/w/polly-mirror.git">Browse (GitWeb)</a>
+  </div>
+
+  <div class="submenu2">
+  <label>polyhedral.info news</label>
+  <script language="JavaScript"
+  src="http://itde.vccs.edu/rss2js/feed2js.php?src=http%3A%2F%2Fpolyhedral.info%2Frss.xml&chan=n&num=5&desc=0&date=y&targ=n"
+  type="text/javascript"></script>
+  </div>
+</div>
+
+<script type="text/javascript">
+  var _paq = _paq || [];
+  _paq.push(["trackPageView"]);
+  _paq.push(["enableLinkTracking"]);
+
+  (function() {
+    var u=(("https:" == document.location.protocol) ? "https" : "http") + "://www.grosser.es/piwik/piwik/";
+    _paq.push(["setTrackerUrl", u+"piwik.php"]);
+    _paq.push(["setSiteId", "3"]);
+    var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
+    g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
+  })();
+</script>
+<noscript>
+<img src="http://www.grosser.es/piwik/piwik/piwik.php?idsite=3&amp;rec=1" style="border:0" alt="" />
+</noscript>
+
diff --git a/rc1/www/performance.html b/rc1/www/performance.html
new file mode 100644
index 0000000..300a188
--- /dev/null
+++ b/rc1/www/performance.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head> <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Performance</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+<h1>Performance</h1>
+
+<p>To evaluate the performance benefits Polly currently provides we compiled the
+<a href="http://www.cse.ohio-state.edu/~pouchet/software/polybench/">Polybench
+2.0</a> benchmark suite.  Each benchmark was run with double precision floating
+point values on an Intel Core Xeon X5670 CPU @ 2.93GHz (12 cores, 24 thread)
+system. We used <a href="http://pocc.sf.net">PoCC</a> and the included <a
+href="http://pluto-compiler.sf.net">Pluto</a> transformations to optimize the
+code. The source code of Polly and LLVM/clang was checked out on 
+25/03/2011.</p>
+
+<p>The results shown were created fully automatically without manual
+interaction. We did not yet spend any time to tune the results. Hence
+further improvments may be achieved by tuning the code generated by Polly, the
+heuristics used by Pluto or by investigating if more code could be optimized.
+As Pluto was never used at such a low level, its heuristics are probably
+far from perfect. Another area where we expect larger performance improvements
+is the SIMD vector code generation. At the moment, it rarely yields to
+performance improvements, as we did not yet include vectorization in our
+heuristics. By changing this we should be able to significantly increase the
+number of test cases that show improvements.</p>
+
+<p>The polybench test suite contains computation kernels from linear algebra
+routines, stencil computations, image processing and data mining. Polly
+recognices the majority of them and is able to show good speedup. However,
+to show similar speedup on larger examples like the SPEC CPU benchmarks Polly
+still misses support for integer casts, variable-sized multi-dimensional arrays
+and probably several other construts. This support is necessary as such
+constructs appear in larger programs, but not in our limited test suite.
+
+<h2> Sequential runs</h2>
+
+For the sequential runs we used Polly to create a program structure that is
+optimized for data-locality. One of the major optimizations performed is tiling.
+The speedups shown are without the use of any multi-core parallelism. No
+additional hardware is used, but the single available core is used more
+efficiently.
+<h3> Small data size</h3>
+<img src="images/performance/sequential-small.png" /><br />
+<h3> Large data size</h3>
+<img src="images/performance/sequential-large.png" />
+<h2> Parallel runs</h2>
+For the parallel runs we used Polly to expose parallelism and to add calls to an
+OpenMP runtime library. With OpenMP we can use all 12 hardware cores
+instead of the single core that was used before. We can see that in several
+cases we obtain more than linear speedup. This additional speedup is due to
+improved data-locality.
+<h3> Small data size</h3>
+<img src="images/performance/parallel-small.png" /><br />
+<h3> Large data size</h3>
+<img src="images/performance/parallel-large.png" />
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/phonecall.html b/rc1/www/phonecall.html
new file mode 100644
index 0000000..53f1a92
--- /dev/null
+++ b/rc1/www/phonecall.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Polyhedral Phone Call</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>Polly: Polyhedral Phone Call</h1>
+  <!--*********************************************************************-->
+
+  <p>There are irregular phone calls to discuss polyhedral topics and
+     related projects. For this we use a conference service that can be
+     reached both through SIP clients and international dial in numbers.</p>
+
+ <ul>
+ <li><b>VoIP/SIP:</b> sip:000777polyhedral@iptel.org<br />
+    <a href="http://ekiga.org">Ekiga</a> is a SIP client that works well for
+    most of us.</li>
+ <li><b>Traditional Dailin Numbers:</b><br />
+    To use your normal land line phone to connect to the conference dial
+    one of the many available <a
+    href="http://www.sipbroker.com/sipbroker/action/pstnNumbers">dial in
+    numbers</a>. When asked for the number to connect type: <em>*011497659</em>.
+    <br />
+    Attention: Some of the dial in numbers do not work reliable. If you are not
+    asked for the number you want to connect to after a couple of seconds, just
+    try another one. <br/>
+    Some selected dial in numbers:
+    <ul>
+    <li><b>USA:</b> +1-443-524-7370, +1-702-553-2797 </li>
+    <li><b>UK:</b> +44-151-601-8747, +44-115-871-8347</li>
+    <li><b>Belgium:</b> +32-4-2680133, +32-9-2980106</li>
+    </ul>
+
+    </ul> 
+  
+</div>
+</body>
+</html>
diff --git a/rc1/www/polly.sh b/rc1/www/polly.sh
new file mode 100644
index 0000000..dbba662
--- /dev/null
+++ b/rc1/www/polly.sh
@@ -0,0 +1,50 @@
+#!/bin/bash -xe
+
+export BASE=`pwd`
+export LLVM_SRC=${BASE}/llvm
+export POLLY_SRC=${LLVM_SRC}/tools/polly
+export CLANG_SRC=${LLVM_SRC}/tools/clang
+export CLOOG_SRC=${BASE}/cloog_src
+export CLOOG_INSTALL=${BASE}/cloog_install
+export LLVM_BUILD=${BASE}/llvm_build
+
+if [ -e /proc/cpuinfo ]; then
+    procs=`cat /proc/cpuinfo | grep processor | wc -l`
+else
+    procs=1
+fi
+
+if ! test -d ${LLVM_SRC}; then
+    git clone http://llvm.org/git/llvm.git ${LLVM_SRC}
+fi
+
+if ! test -d ${POLLY_SRC}; then
+    git clone http://llvm.org/git/polly.git ${POLLY_SRC}
+fi
+
+if ! test -d ${CLANG_SRC}; then
+    git clone http://llvm.org/git/clang.git ${CLANG_SRC}
+fi
+
+${POLLY_SRC}/utils/checkout_cloog.sh ${CLOOG_SRC}
+cd ${CLOOG_SRC}
+
+if ! test -e ${CLOOG_SRC}/config.log; then
+    ./configure --prefix=${CLOOG_INSTALL}
+fi
+make
+make install
+cd ${BASE}
+
+mkdir -p ${LLVM_BUILD}
+cd ${LLVM_BUILD}
+
+if which cmake ; then
+    cmake -DCMAKE_PREFIX_PATH=${CLOOG_INSTALL} ${LLVM_SRC}
+    make -j$procs -l$procs
+    make check-polly
+else
+    ${LLVM_SRC}/configure --with-cloog=${CLOOG_INSTALL} --with-isl=${CLOOG_INSTALL}
+    make -j$procs -l$procs
+    make check-polly -C tools/polly/test/
+fi
diff --git a/rc1/www/publications.html b/rc1/www/publications.html
new file mode 100644
index 0000000..90d34a2
--- /dev/null
+++ b/rc1/www/publications.html
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head>
+  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Publications</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+  <!--*********************************************************************-->
+  <h1>Publications</h1>
+  <!--*********************************************************************-->
+
+  <h2> Publications about polyhedral compilation </h2>
+  <a href="http://polyhedral.info/publications.html">polyhedral.info</a> has a
+  large list of publications related to polyhedral compilation. They are very
+  useful to get an idea of the latest developments in this area of compilation
+  as well as to understand what kind of optimizations can be built on top of
+  Polly.
+
+  <h2> Citing Polly</h2>
+
+  The canonical publication to cite Polly is:
+
+<p>
+  <em>Polly - Performing polyhedral optimizations on a low-level intermediate
+      representation </em><br />
+Tobias Grosser, Armin Groesslinger, Christian Lengauer<br />
+Parallel Processing Letters 2012 22:04<br />
+  <a
+href="http://www.worldscientific.com/doi/abs/10.1142/S0129626412500107?af=R">
+Online Issue</a>
+</p>
+
+  <h2> Publications involving Polly </h2>
+  <h3> 2012 </h3>
+  <ul>
+  <li><em>KernelGen - a prototype of auto-parallelizing Fortran/C compiler for NVIDIA GPUs</em><br />
+  Dmitry Mikushin, Nikolay Likhogrud, Hou Yunqing, Sergey Kovylov<br />
+  Multi-core Workshop 2012, NCAR, Boulder, CO<br /><a
+  href="publications/kernelgen-ncar-2012-slides.pdf">Slides</a>
+  </li>
+  <li><em>KernelGen - a toolchain for automatic GPU-centric applications porting</em><br />
+  Nikolay Likhogrud, Dmitry Mikushin, Andrew Adinets<br />
+  Parallel Computational Technologies (PCT) 2012, Novosibirsk<br /><a
+  href="publications/kernelgen-pavt-2012-slides.pdf">Slides</a>
+  </li>
+  </ul>
+  <h3> 2011 </h3>
+  <ul>
+  <li><em>Polly - First Successful Optimizations - How to proceed?</em><br />
+  Tobias Grosser, Ragesh A<br />
+  LLVM Developer Meeting 2011<br /><a
+  href="http://llvm.org/devmtg/2011-11/Grosser_PollyOptimizations.pdf">Slides</a>, <a
+  href="http://llvm.org/devmtg/2011-11/videos/Grosser_PollyOptimizations-desktop.mov">Video
+  (Computer)</a>, <a
+  href="http://llvm.org/devmtg/2011-11/videos/Grosser_PollyOptimizations-mobile.mp4">Video
+  (Mobile)</a></li>
+  <li><em>A Framework for Automatic OpenMP Code Generation</em><br />
+  Raghesh A<br />
+  Masters Thesis (May 2011)<br />
+  <a
+  href="publications/raghesh-a-masters-thesis.pdf">Thesis</a>
+  </li>
+  <li><em>Enabling Polyhedral Optimizations in LLVM</em><br />
+  Tobias Grosser<br />
+  Diploma Thesis (April 2011)<br />
+  <a
+  href="publications/grosser-diploma-thesis.pdf">Thesis</a>
+  </li>
+  <li><em>Polly - Polyhedral Optimization in LLVM</em><br />
+  Tobias Grosser, Hongbin Zheng, Ragesh Aloor, Andreas Simb&uuml;rger, Armin
+  Gr&ouml;&szlig;linger, Louis-No&euml;l Pouchet<br />
+  IMPACT at CGO 2011 <br />
+  <a
+  href="publications/grosser-impact-2011.pdf">Paper</a>, <a
+  href="publications/grosser-impact-2011-slides.pdf">Slides </a>
+  </li>
+  </ul>
+  <h3> 2010 </h3>
+  <ul>
+  <li><em>Polly - Polyhedral Transformations for LLVM</em><br />
+  Tobias Grosser, Hongbin Zheng<br />
+  LLVM Developer Meeting 2010<br /><a
+  href="http://llvm.org/devmtg/2010-11/Grosser-Polly.pdf">Slides</a>, <a
+  href="http://llvm.org/devmtg/2010-11/videos/Grosser_Polly-desktop.mp4">Video
+  (Computer)</a>, <a
+  href="http://llvm.org/devmtg/2010-11/videos/Grosser_Polly-mobile.mp4">Video
+  (Mobile)</a></li>
+  </ul>
+
+  <h2>Publications used within Polly</h2>
+  <h3>Polyhedral library</h3>
+  <ul>
+  <li><em>isl: An Integer Set Library for the Polyhedral Model </em><br />
+  Sven Verdoolaege<br />
+  ICMS 2010
+  </li>
+  </ul>
+  <h3>Optimization</h3>
+  <ul>
+  <li><em>A Practical Automatic Polyhedral Parallelizer and Locality Optimizer
+          </em><br />
+  Uday Bondhugula, Alberto Hartono, J. Ramanujam, P. Sadayappan<br />
+  PLDI 2008
+  </li>
+  <li><em>Effective Automatic Parallelization and Locality Optimization using
+          the Polyhedral Model
+          </em><br />
+  Uday Bondhugula<br />
+  PhD thesis 2008
+  </li>
+  </ul>
+  <h3>Code Generation</h3>
+  <ul>
+  <li><em>Code Generation in the Polyhedral Model Is Easier Than You Think</em>
+  <br />
+  C&eacute;dric Bastoul<br />
+  PACT 2004
+  </li>
+  </ul>
+  <h2>Interesting Publications</h2>
+
+  Publications that are not yet used or implemented in Polly, but that are
+  interesting to look at either to understand general concepts or to implement
+  the corresponding ideas. This list is incomplete and papers are added as
+  we hear about them.<br />
+  <h3>GPGPU</h3>
+  <ul>
+  <li><em>Automatic C-to-CUDA Code Generation for Affine Programs</em>
+  <br />
+  Muthu Manikandan Baskaran, J. Ramanujam and P. Sadayappan<br />
+  CC 2010
+  </li>
+  <li><em>Putting Automatic Polyhedral Compilation for GPGPU to Work<em>
+  Soufiane Baghdadi, Armin Gr&ouml;&szlig;linger, and Albert Cohen. <br />
+  In Proc. of Compilers for Parallel Computers (CPC), 2010.
+  </li>
+  </ul>
+  <h3>Vectorization</h3>
+  <ul>
+  <li><em>Joint Scheduling and Layout Optimization to Enable Multi-Level
+  Vectorization</em>
+  <br />
+  Nicolas Vasilache, Benoit Meister, Muthu Baskaran, Richard Lethin<br />
+  IMPACT 2012 (upcoming)
+  </li>
+  </ul>
+  <h3>Iterative Compilation</h3>
+  <ul>
+  <li><em>Iterative optimization in the polyhedral model: Part I,
+  one-dimensional time.  </em>
+  <br />
+  Louis-No&euml;l Pouchet, C&eacute;dric Bastoul, Albert Cohen and Nicolas Vasilache<br />
+  CGO 2007
+  </li>
+  <li><em>Iterative optimization in the polyhedral model: Part II,
+  multidimensional time.  </em>
+  <br />
+  Louis-No&euml;l Pouchet, C&eacute;dric Bastoul, Albert Cohen and John Cavazos<br />
+  PLDI 2008
+  </li>
+  </ul>
+  <h3>Non-static Control</h3>
+  <ul>
+  <li><em>The Polyhedral Model Is More Widely Applicable Than You Think</em>
+  <br />
+  Mohamed-Walid Benabderrahmane, Louis-No&euml;l Pouchet, Albert Cohen,
+  C&eacute;dric
+  Bastoul.<br />
+  CC 2010
+  </li>
+  </ul>
+  <h3>Source to Source Tools</h3>
+  <ul>
+  <li><em> Polyhedral Extraction Tool</em>
+  <br />
+  Sven Verdoolaege, Tobias Grosser<br />
+  IMPACT 2012
+  </li>
+  </ul>
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/publications/grosser-diploma-thesis.pdf b/rc1/www/publications/grosser-diploma-thesis.pdf
new file mode 100644
index 0000000..f7e8dd3
--- /dev/null
+++ b/rc1/www/publications/grosser-diploma-thesis.pdf
Binary files differ
diff --git a/rc1/www/publications/grosser-impact-2011-slides.pdf b/rc1/www/publications/grosser-impact-2011-slides.pdf
new file mode 100644
index 0000000..3e60410
--- /dev/null
+++ b/rc1/www/publications/grosser-impact-2011-slides.pdf
Binary files differ
diff --git a/rc1/www/publications/grosser-impact-2011.pdf b/rc1/www/publications/grosser-impact-2011.pdf
new file mode 100644
index 0000000..9b79bd2
--- /dev/null
+++ b/rc1/www/publications/grosser-impact-2011.pdf
Binary files differ
diff --git a/rc1/www/publications/kernelgen-ncar-2012-slides.pdf b/rc1/www/publications/kernelgen-ncar-2012-slides.pdf
new file mode 100644
index 0000000..8a91611
--- /dev/null
+++ b/rc1/www/publications/kernelgen-ncar-2012-slides.pdf
Binary files differ
diff --git a/rc1/www/publications/kernelgen-pavt-2012-slides.pdf b/rc1/www/publications/kernelgen-pavt-2012-slides.pdf
new file mode 100644
index 0000000..ce4b832
--- /dev/null
+++ b/rc1/www/publications/kernelgen-pavt-2012-slides.pdf
Binary files differ
diff --git a/rc1/www/publications/raghesh-a-masters-thesis.pdf b/rc1/www/publications/raghesh-a-masters-thesis.pdf
new file mode 100644
index 0000000..2eeb193
--- /dev/null
+++ b/rc1/www/publications/raghesh-a-masters-thesis.pdf
Binary files differ
diff --git a/rc1/www/todo.html b/rc1/www/todo.html
new file mode 100644
index 0000000..0c812fe
--- /dev/null
+++ b/rc1/www/todo.html
@@ -0,0 +1,457 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
+          "http://www.w3.org/TR/html4/strict.dtd">
+<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
+<html>
+<head> <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+  <title>Polly - Todo</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+</head>
+<body>
+<div id="box">
+<!--#include virtual="menu.html.incl"-->
+<div id="content">
+<h1> TODO </h1>
+
+<h2> Overview</h2>
+<ul>
+<li><a href="#phase3">Phase 3 - Improve Robustness, Interoperability and
+Optimizations (ongoing)</a></li>
+<li><a href="#llvm">Polly as a LLVM Project (Finished February 2012)</a></li>
+<li><a href="#phase2">Phase 2 - First Optimizations and Enhanced User Experience (Finished
+February 2012)</a></li>
+<li><a href="#phase1">Phase 1 - Get Something Working (Finished October 2010)</a>
+</li>
+</ul>
+<h2> Individual Phases</h3>
+
+<h3 id="phase3"> Phase 3 - Improve Robustness, Interoperability and
+Optimizations (ongoing)</h3>
+<table class="wikitable" cellpadding="2">
+<p> </p>
+
+<tbody>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Frontend </th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> Non-affine access functions
+</th><td align="center" class='done'> Done, needs testing
+</td><td>Marcello
+</td>
+</tr>
+
+
+<tr>
+<th align="left"> <a href="http://llvm.org/bugs/show_bug.cgi?id=12397">Model
+integer wrapping</a>
+</th><td align="center" class='open'> Open
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> <a
+href="http://llvm.org/bugs/show_bug.cgi?id=12403">Variable-size
+multi-dimensional arrays</a>
+</th><td align="center" class='open'> Open
+</td><td>Sebastian
+</td></tr>
+<tr>
+<th align="left"> <a
+href="http://llvm.org/bugs/show_bug.cgi?id=12407">Derive information for
+the SCoP context
+</a>
+</th>
+<td align="center" class='nice'> Open
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> <a href="http://llvm.org/bugs/show_bug.cgi?id=12402">Finer
+grained statements</a>
+</th><td align="center" class='nice'> Open
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> Detect reductions
+</th><td align="center" class='nice'>Open
+</td><td>Johannes
+</td></tr>
+<tr>
+<th align="left"> Assume static sized arrays are only accessed in-bounds
+</th><td align="center" class='nice'>Open
+</td><td>Zino
+</td></tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Optimizer </th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> <a href="http://llvm.org/bugs/show_bug.cgi?id=12405">Polyhedral
+dead code elimination</a>
+</th><td class="done">Done
+</td><td>
+</td></tr>
+<th align="left"> <a
+href="http://llvm.org/bugs/show_bug.cgi?id=10229">OpenSCoP Import/Export</a>
+</th><td class="nice">Open
+</td><td>
+</td></tr>
+
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Back End</th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> Make OpenMP independent of Polly code generation
+(requirement to enable scev codegen)
+</th><td class="open"> Open
+</td><td> Zino
+</td></tr>
+<tr>
+<th align="left"> Support for scalars/PHIs directly in the code generation
+(requirement to remove polly independent)
+</th><td class="open"> Open
+</td><td>Tobias
+</td></tr>
+<tr>
+<th align="left"> <a href="http://llvm.org/bugs/show_bug.cgi?id=12398">Remove
+the need for independent blocks</a>
+</th><td class="open"> Open
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> Run-time alias checks
+</th><td class="open"> Open
+</td><td>Sebastian
+</td></tr>
+<tr>
+<th align="left"> <a href="http://llvm.org/bugs/show_bug.cgi?id=12404">Integrate
+with the LLVM BBVectorizer</a>
+</th><td class="nice">Open
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> <a href="http://llvm.org/bugs/show_bug.cgi?id=10381">Derive
+optimal types (instead of always using i64)</a>
+</th><td class="niceinprogress"> in progress
+</td><td>Tobias
+</td></tr>
+<tr>
+<th align="left"> <a
+href="http://polly.llvm.org/documentation/gpgpucodegen.html">GPGPU Code
+Generation</a>
+</th><td class="niceinprogress">in progress
+</td><td>
+Yabin
+</td></tr>
+<tr>
+<th align="left"> <a
+href="http://polly.llvm.org/documentation/memaccess.html">Allow optimizers to
+change memory access functions</a>
+</th><td class="nice"> Open
+</td><td>
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> <a href="http://llvm.org/bugs/show_bug.cgi?id=12406">Make code
+generation independent of the clast</a>
+</th><td class="done">Done
+</td><td>
+</td></tr>
+
+<tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> General</th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> Teach bugpoint to extract regions
+</th><td class="nice"> Open
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> Add <a
+href="http://www.cse.ohio-state.edu/~pouchet/software/polybench/">Polybench
+3.2</a> to the LLVM test suite
+</th><td class="done"> Done
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> Build against an installed LLVM
+</th><td class="done"> Done<br />
+</td><td>
+</td></tr>
+<tr>
+<th align="left"> Setup buildbot regression testers using LNT
+</th><td class="done"> Done
+</td><td> Tobias
+</td></tr>
+</tbody></table>
+<h3 id="llvm"> Polly as a LLVM Project (Finished February 2012)</h3>
+
+<table class="wikitable" cellpadding="2">
+
+<tbody>
+<tr style="background: rgb(239, 239, 239);">
+<th>Task
+</th><th> Status
+</th><th>Owner
+</th></tr>
+<tr>
+<th align="left"> Move to LLVM SVN
+</th><td class="done" align="center">
+<a
+href="http://llvm.org/svn/llvm-project/polly"
+>http://llvm.org/svn/llvm-project/polly</a>
+</td><td> Tobias
+
+</td></tr>
+<tr>
+<th align="left"> Git mirror
+</th><td class="done" align="center">
+git://llvm.org/git/polly.git
+</td><td> Tobias
+</td></tr>
+<tr>
+<th align="left"> Commit mails
+</th><td class="done" align="center">
+llvm-commits@cs.uiuc.edu
+</td><td> Tobias
+</td></tr>
+<tr>
+
+<th align="left"> LLVM Bugzilla category
+</th><td class="done" align="center">
+<a href="http://llvm.org/bugs/enter_bug.cgi?product=Projects">LLVM Bugzilla</a>
+<br />
+(Product is 'Projects', Component is 'Polly')
+</td><td> Tobias
+<tr>
+<th align="left"> Website
+</th><td class="done" align="center">
+<a href="http://polly.llvm.org">http://polly.llvm.org</a>
+</td><td> Tobias
+</td></tr>
+<tr>
+<th align="left">Buildbot that runs 'make polly-test'
+</th><td class="done" align="center">
+<a href="http://lab.llvm.org:8011/console">Buildbot</a>
+</td>
+<td> Tobias, Andreas
+</td></tr>
+</th><td>
+
+</td></tr>
+</tbody></table>
+<h3 id="phase2"> Phase 2 - First Optimizations and Enhanced User Experience (Finished
+February 2012)</h3>
+<p>
+
+First optimizations to show the usefullness of Polly and enhance the user
+experience. We also try to increase the amount of code we can optimize.
+</p>
+<table class="wikitable" cellpadding="2">
+
+<tbody>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Frontend </th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<tr>
+<th align="left"> Allow parameters in access functions
+</th><td align="center" class='done'> Done
+</td><td> Tobias
+</td></tr>
+
+<tr>
+<th align="left"> Improved Scalar Evolution parsing
+</th><td align="center" class='done'> Done
+</td><td> Tobias
+</td></tr>
+<tr>
+<th align="left"> (Graphical) user feedback on Scop Detection
+</th><td align="center" class='done'> Done
+</td><td> Tobias
+</td></tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Optimizer </th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> Dependency Analysis
+</th><td class="done" align="center"> Done
+</td><td> Tobias
+</td></tr>
+<tr>
+<tr>
+<th align="left"> Optimizer - Connect Pluto (through PoCC)
+</th><td class="done" align="center"> Done
+</td><td> Tobias
+</td></tr>
+<tr>
+<tr>
+<th align="left"> Optimizer - Add ISL internal Pluto like optimizer
+</th><td class="done" align="center"> Done
+</td><td> Tobias
+</td></tr>
+
+<tr>
+<th align="left"> Import/Export - SCoPLib 0.2 (needed for PoCC)
+</th><td class="done" align="center">Done
+
+</td><td> Tobias
+</td></tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Back End</th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left">SIMD code generation for trivially vectorizable loops
+</th><td class="done">Done
+</td><td>Tobias
+</td></tr>
+<tr>
+<th align="left">OpenMP code generation
+</th><td class="done">Done
+</td><td> Raghesh, Tobias
+
+</td></tr>
+<tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> General</th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> clang integration
+</th><td class="done" align="center"> done
+
+</td><td> Tobias
+</td></tr>
+<tr>
+<th align="left"> Commit RegionPass patch upstream
+</th><td class="done" align="center"> done
+
+</td><td> Tobias
+</td></tr>
+<tr>
+</tbody></table>
+<h3 id="phase1">Phase 1 - Get Something Working (Finished October 2010)</h3>
+<p>Create a minimal version of Polly that can transform an LLVM-IR program to
+the polyhedral model and back to LLVM-IR. No transformations are performed.
+</p>
+<table class="wikitable" cellpadding="2">
+
+<tbody>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Front End</th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+
+<th align="left"> Region detection
+</td><td class="done"> Done
+</td><td>Ether
+</td></tr>
+<tr>
+<th align="left"> Access Functions
+</td><td class="done"> Done
+</td><td>John, Ether
+</td></tr>
+<tr>
+<th align="left"> Alias sets
+</td><td class="done"> Done
+</td><td>Ether
+</td></tr>
+<tr>
+<th align="left"> Scalar evolution to affine expression
+</td><td class="done"> Done
+
+</td><td>
+Ether
+</td></tr>
+<tr>
+<th align="left"> SCoP extraction
+</td><td class="done"> Done
+</td><td>Tobias, Ether
+
+</td></tr>
+<tr>
+<th align="left"> SCoPs to polyhedral model
+</td><td class="done"> Done
+</td><td>Tobias, Ether
+</td></tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Optimizer </th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> Define polyhedral description
+</td><td class="done"> Done
+</td><td>Tobias
+
+</td></tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> Back End</th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> Create LLVM-IR using CLooG
+</td><td class="done"> Done
+</td><td> Tobias
+
+</td></tr>
+<tr><td colspan='4'>&nbsp;</td></tr>
+<tr><th colspan="3" style="background: rgb(239, 239, 239);"> General</th></tr>
+<tr style="background: rgb(239, 239, 239)">
+  <th width="400px"> Task </th>
+  <th width="150px"> Status </th>
+  <th> Owner </th>
+</tr>
+<tr>
+<th align="left"> Setup git repositories
+
+</td><td class="done"> Done
+</td><td> Tobias
+</td></tr>
+<tr>
+<th align="left"> Add CLooG/isl to build system
+</td><td class="done"> Done
+</td><td> Tobias
+
+</td></tr>
+
+</tbody></table>
+</div>
+</div>
+</body>
+</html>
diff --git a/rc1/www/video-js/video-js.css b/rc1/www/video-js/video-js.css
new file mode 100644
index 0000000..c9c4823
--- /dev/null
+++ b/rc1/www/video-js/video-js.css
@@ -0,0 +1,242 @@
+/* 
+VideoJS Default Styles (http://videojs.com)
+Version 2.0.2
+
+REQUIRED STYLES (be careful overriding)
+================================================================================ */
+/* Box containing video, controls, and download links.
+   Will be set to the width of the video element through JS
+   If you want to add some kind of frame or special positioning, use another containing element, not video-js-box. */
+.video-js-box { text-align: left; position: relative; line-height: 0 !important; margin: 0; padding: 0 !important; border: none !important;  }
+
+/* Video Element */
+video.video-js { background-color: #000; position: relative; padding: 0; }
+
+.vjs-flash-fallback { display: block; }
+
+/* Poster Overlay Style */
+.video-js-box img.vjs-poster { display: block; position: absolute; left: 0; top: 0; width: 100%; height: 100%; margin: 0; padding: 0; cursor: pointer; }
+/* Subtiles Style */
+.video-js-box .vjs-subtitles { color: #fff; font-size: 20px; text-align: center; position: absolute; bottom: 40px; left: 0; right: 0; }
+
+/* Fullscreen styles for main elements */
+.video-js-box.vjs-fullscreen { position: fixed; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: 1000; }
+.video-js-box.vjs-fullscreen video.video-js,
+.video-js-box.vjs-fullscreen .vjs-flash-fallback { position: relative; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000; }
+.video-js-box.vjs-fullscreen img.vjs-poster { z-index: 1001; }
+.video-js-box.vjs-fullscreen .vjs-spinner { z-index: 1001; }
+.video-js-box.vjs-fullscreen .vjs-controls { z-index: 1003; }
+.video-js-box.vjs-fullscreen .vjs-big-play-button { z-index: 1004; }
+.video-js-box.vjs-fullscreen .vjs-subtitles { z-index: 1004; }
+
+/* Styles Loaded Check */
+.vjs-styles-check { height: 5px; position: absolute; }
+/* Controls Below Video */
+.video-js-box.vjs-controls-below .vjs-controls { position: relative; opacity: 1; background-color: #000; }
+.video-js-box.vjs-controls-below .vjs-subtitles { bottom: 75px; } /* Account for height of controls below video */
+
+/* DEFAULT SKIN (override in another file)
+================================================================================
+Using all CSS to draw the controls. Images could be used if desired.
+Instead of editing this file, I recommend creating your own skin CSS file to be included after this file,
+so you can upgrade to newer versions easier. */
+
+/* Controls Layout 
+  Using absolute positioning to position controls */
+.video-js-box .vjs-controls {
+  position: absolute; margin: 0; opacity: 0.85; color: #fff;
+  display: none; /* Start hidden */
+  left: 0; right: 0; /* 100% width of video-js-box */ 
+  width: 100%;
+  bottom: 0px; /* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
+  height: 35px; /* Including any margin you want above or below control items */
+  padding: 0; /* Controls are absolutely position, so no padding necessary */
+}
+
+.video-js-box .vjs-controls > div { /* Direct div children of control bar */
+  position: absolute; /* Use top, bottom, left, and right to specifically position the control. */
+  text-align: center; margin: 0; padding: 0;
+  height: 25px; /* Default height of individual controls */
+  top: 5px; /* Top margin to put space between video and controls when controls are below */
+
+  /* CSS Background Gradients 
+     Using to give the aqua-ish look. */
+  /* Default */ background-color: #0B151A;
+  /* Webkit  */ background: #1F3744 -webkit-gradient(linear, left top, left bottom, from(#0B151A), to(#1F3744)) left 12px;
+  /* Firefox */ background: #1F3744 -moz-linear-gradient(top,  #0B151A,  #1F3744) left 12px;
+
+  /* CSS Curved Corners */
+  border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px;
+
+  /* CSS Shadows */
+  box-shadow: 1px 1px 2px #000; -webkit-box-shadow: 1px 1px 2px #000; -moz-box-shadow: 1px 1px 2px #000;
+}
+
+/* Placement of Control Items 
+   - Left side of pogress bar, use left & width
+   - Rigth side of progress bar, use right & width
+   - Expand with the video (like progress bar) use left & right */
+.vjs-controls > div.vjs-play-control       { left: 5px;   width: 25px;  }
+.vjs-controls > div.vjs-progress-control   { left: 35px;  right: 165px; } /* Using left & right so it expands with the width of the video */
+.vjs-controls > div.vjs-time-control       { width: 75px; right: 90px;  } /* Time control and progress bar are combined to look like one */
+.vjs-controls > div.vjs-volume-control     { width: 50px; right: 35px;  }
+.vjs-controls > div.vjs-fullscreen-control { width: 25px; right: 5px;   }
+
+/* Removing curved corners on progress control and time control to join them. */
+.vjs-controls > div.vjs-progress-control {
+  border-top-right-radius: 0; -webkit-border-top-right-radius: 0; -moz-border-radius-topright: 0;
+  border-bottom-right-radius: 0; -webkit-border-bottom-right-radius: 0; -moz-border-radius-bottomright: 0;
+}
+.vjs-controls > div.vjs-time-control { 
+  border-top-left-radius: 0; -webkit-border-top-left-radius: 0; -moz-border-radius-topleft: 0;
+  border-bottom-left-radius: 0; -webkit-border-bottom-left-radius: 0; -moz-border-radius-bottomleft: 0;
+}
+
+/* Play/Pause
+-------------------------------------------------------------------------------- */
+.vjs-play-control { cursor: pointer !important; }
+/* Play Icon */
+.vjs-play-control span { display: block; font-size: 0; line-height: 0; }
+.vjs-paused .vjs-play-control span {
+  width: 0; height: 0; margin: 8px 0 0 8px;
+  /* Drawing the play triangle with borders - http://www.infimum.dk/HTML/slantinfo.html */
+  border-left: 10px solid #fff; /* Width & Color of play icon */
+  /* Height of play icon is total top & bottom border widths. Color is transparent. */
+  border-top: 5px solid rgba(0,0,0,0); border-bottom: 5px solid rgba(0,0,0,0);
+}
+.vjs-playing .vjs-play-control span {
+  width: 3px; height: 10px; margin: 8px auto 0;
+  /* Drawing the pause bars with borders */
+  border-top: 0px; border-left: 3px solid #fff; border-bottom: 0px; border-right: 3px solid #fff;
+}
+
+/* Progress
+-------------------------------------------------------------------------------- */
+.vjs-progress-holder { /* Box containing play and load progresses */
+  position: relative; padding: 0; overflow:hidden; cursor: pointer !important;
+  height: 9px; border: 1px solid #777;
+  margin: 7px 1px 0 5px; /* Placement within the progress control item */
+  border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px;
+}
+.vjs-progress-holder div { /* Progress Bars */
+  position: absolute; display: block; width: 0; height: 9px; margin: 0; padding: 0;
+  border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px;
+}
+.vjs-play-progress {
+  /* CSS Gradient */
+  /* Default */ background: #fff;
+  /* Webkit  */ background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#777));
+  /* Firefox */ background: -moz-linear-gradient(top,  #fff,  #777);
+}
+.vjs-load-progress {
+  opacity: 0.8;
+  /* CSS Gradient */
+  /* Default */ background-color: #555;
+  /* Webkit  */ background: -webkit-gradient(linear, left top, left bottom, from(#555), to(#aaa));
+  /* Firefox */ background: -moz-linear-gradient(top,  #555,  #aaa);
+}
+
+/* Time Display
+-------------------------------------------------------------------------------- */
+.vjs-controls .vjs-time-control { font-size: 10px; line-height: 1; font-weight: normal; font-family: Helvetica, Arial, sans-serif; }
+.vjs-controls .vjs-time-control span { line-height: 25px; /* Centering vertically */ }
+
+/* Volume
+-------------------------------------------------------------------------------- */
+.vjs-volume-control { cursor: pointer !important; }
+.vjs-volume-control div { display: block; margin: 0 5px 0 5px; padding: 4px 0 0 0; }
+/* Drawing the volume icon using 6 span elements */
+.vjs-volume-control div span { /* Individual volume bars */
+  float: left; padding: 0;
+  margin: 0 2px 0 0; /* Space between */
+  width: 5px; height: 0px; /* Total height is height + bottom border */
+  border-bottom: 18px solid #555; /* Default (off) color and height of visible portion */
+}
+.vjs-volume-control div span.vjs-volume-level-on { border-color: #fff; /* Volume on bar color */ }
+/* Creating differnt bar heights through height (transparent) and bottom border (visible). */
+.vjs-volume-control div span:nth-child(1) { border-bottom-width: 2px; height: 16px; }
+.vjs-volume-control div span:nth-child(2) { border-bottom-width: 4px; height: 14px; }
+.vjs-volume-control div span:nth-child(3) { border-bottom-width: 7px; height: 11px; }
+.vjs-volume-control div span:nth-child(4) { border-bottom-width: 10px; height: 8px; }
+.vjs-volume-control div span:nth-child(5) { border-bottom-width: 14px; height: 4px; }
+.vjs-volume-control div span:nth-child(6) { margin-right: 0; }
+
+/* Fullscreen
+-------------------------------------------------------------------------------- */
+.vjs-fullscreen-control { cursor: pointer !important; }
+.vjs-fullscreen-control div {
+  padding: 0; text-align: left; vertical-align: top; cursor: pointer !important; 
+  margin: 5px 0 0 5px; /* Placement within the fullscreen control item */
+  width: 20px; height: 20px;
+}
+/* Drawing the fullscreen icon using 4 span elements */
+.vjs-fullscreen-control div span { float: left; margin: 0; padding: 0; font-size: 0; line-height: 0; width: 0; text-align: left; vertical-align: top; }
+.vjs-fullscreen-control div span:nth-child(1) { /* Top-left triangle */
+  margin-right: 3px; /* Space between top-left and top-right */
+  margin-bottom: 3px; /* Space between top-left and bottom-left */
+  border-top: 6px solid #fff; /* Height and color */
+  border-right: 6px solid rgba(0,0,0,0);  /* Width */
+}
+.vjs-fullscreen-control div span:nth-child(2) { border-top: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); }
+.vjs-fullscreen-control div span:nth-child(3) { clear: both; margin: 0 3px 0 0; border-bottom: 6px solid #fff; border-right: 6px solid rgba(0,0,0,0); }
+.vjs-fullscreen-control div span:nth-child(4) { border-bottom: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); }
+/* Icon when video is in fullscreen mode */
+.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(1) { border: none; border-bottom: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); }
+.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(2) { border: none; border-bottom: 6px solid #fff; border-right: 6px solid rgba(0,0,0,0); }
+.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(3) { border: none; border-top: 6px solid #fff; border-left: 6px solid rgba(0,0,0,0); }
+.vjs-fullscreen .vjs-fullscreen-control div span:nth-child(4) { border: none; border-top: 6px solid #fff; border-right: 6px solid rgba(0,0,0,0); }
+
+/* Download Links - Used for browsers that don't support any video.
+---------------------------------------------------------*/
+.vjs-no-video { font-size: small; line-height: 1.5; }
+
+/* Big Play Button (at start)
+---------------------------------------------------------*/
+div.vjs-big-play-button {
+  display: none; /* Start hidden */ z-index: 2;
+  position: absolute; top: 50%; left: 50%; width: 80px; height: 80px; margin: -43px 0 0 -43px; text-align: center; vertical-align: center; cursor: pointer !important;
+  border: 3px solid #fff; opacity: 0.9;
+  border-radius: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px;
+  
+  /* CSS Background Gradients */
+  /* Default */ background-color: #0B151A;
+  /* Webkit  */ background: #1F3744 -webkit-gradient(linear, left top, left bottom, from(#0B151A), to(#1F3744)) left 40px;
+  /* Firefox */ background: #1F3744 -moz-linear-gradient(top,  #0B151A,  #1F3744) left 40px;
+
+  /* CSS Shadows */
+  box-shadow: 4px 4px 8px #000; -webkit-box-shadow: 4px 4px 8px #000; -moz-box-shadow: 4px 4px 8px #000;
+}
+div.vjs-big-play-button:hover {
+  box-shadow: 0px 0px 80px #fff; -webkit-box-shadow: 0px 0px 80px #fff; -moz-box-shadow: 0px 0px 80px #fff;
+}
+
+div.vjs-big-play-button span {
+  display: block; font-size: 0; line-height: 0;
+  width: 0; height: 0; margin: 20px 0 0 23px;
+  /* Drawing the play triangle with borders - http://www.infimum.dk/HTML/slantinfo.html */
+  border-left: 40px solid #fff; /* Width & Color of play icon */
+  /* Height of play icon is total top & bottom border widths. Color is transparent. */
+  border-top: 20px solid rgba(0,0,0,0); border-bottom: 20px solid rgba(0,0,0,0);
+}
+
+/* Spinner Styles
+---------------------------------------------------------*/
+/* CSS Spinners by Kilian Valkhof - http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/ */
+.vjs-spinner { display: none; position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; z-index: 1; margin: -50px 0 0 -50px;
+  /* Scaling makes the circles look smoother. */
+  transform: scale(0.5); -webkit-transform:scale(0.5); -moz-transform:scale(0.5);
+}
+/* Spinner circles */
+.vjs-spinner div { position:absolute; left: 40px; top: 40px; width: 20px; height: 20px; background: #fff;
+  border-radius: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px;
+  border: 1px solid #ccc; /* Added border so can be visible on white backgrounds */
+}
+/* Each circle */
+.vjs-spinner div:nth-child(1) { opacity: 0.12; transform: rotate(000deg) translate(0, -40px) scale(0.1); -webkit-transform: rotate(000deg) translate(0, -40px) scale(0.1); -moz-transform: rotate(000deg) translate(0, -40px) scale(0.1); }
+.vjs-spinner div:nth-child(2) { opacity: 0.25; transform: rotate(045deg) translate(0, -40px) scale(0.2); -webkit-transform: rotate(045deg) translate(0, -40px) scale(0.2); -moz-transform: rotate(045deg) translate(0, -40px) scale(0.2); }
+.vjs-spinner div:nth-child(3) { opacity: 0.37; transform: rotate(090deg) translate(0, -40px) scale(0.4); -webkit-transform: rotate(090deg) translate(0, -40px) scale(0.4); -moz-transform: rotate(090deg) translate(0, -40px) scale(0.4); }
+.vjs-spinner div:nth-child(4) { opacity: 0.50; transform: rotate(135deg) translate(0, -40px) scale(0.6); -webkit-transform: rotate(135deg) translate(0, -40px) scale(0.6); -moz-transform: rotate(135deg) translate(0, -40px) scale(0.6); }
+.vjs-spinner div:nth-child(5) { opacity: 0.62; transform: rotate(180deg) translate(0, -40px) scale(0.8); -webkit-transform: rotate(180deg) translate(0, -40px) scale(0.8); -moz-transform: rotate(180deg) translate(0, -40px) scale(0.8); }
+.vjs-spinner div:nth-child(6) { opacity: 0.75; transform: rotate(225deg) translate(0, -40px) scale(1.0); -webkit-transform: rotate(225deg) translate(0, -40px) scale(1.0); -moz-transform: rotate(225deg) translate(0, -40px) scale(1.0); }
+.vjs-spinner div:nth-child(7) { opacity: 0.87; transform: rotate(270deg) translate(0, -40px) scale(1.1); -webkit-transform: rotate(270deg) translate(0, -40px) scale(1.1); -moz-transform: rotate(270deg) translate(0, -40px) scale(1.1); }
+.vjs-spinner div:nth-child(8) { opacity: 1.00; transform: rotate(315deg) translate(0, -40px) scale(1.3); -webkit-transform: rotate(315deg) translate(0, -40px) scale(1.3); -moz-transform: rotate(315deg) translate(0, -40px) scale(1.3); }
\ No newline at end of file
diff --git a/rc1/www/video-js/video.js b/rc1/www/video-js/video.js
new file mode 100644
index 0000000..c0efccd
--- /dev/null
+++ b/rc1/www/video-js/video.js
@@ -0,0 +1,1758 @@
+/*
+VideoJS - HTML5 Video Player
+v2.0.2
+
+This file is part of VideoJS. Copyright 2010 Zencoder, Inc.
+
+VideoJS is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+VideoJS 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with VideoJS.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+// Self-executing function to prevent global vars and help with minification
+(function(window, undefined){
+  var document = window.document;
+
+// Using jresig's Class implementation http://ejohn.org/blog/simple-javascript-inheritance/
+(function(){var initializing=false, fnTest=/xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; this.JRClass = function(){}; JRClass.extend = function(prop) { var _super = this.prototype; initializing = true; var prototype = new this(); initializing = false; for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } function JRClass() { if ( !initializing && this.init ) this.init.apply(this, arguments); } JRClass.prototype = prototype; JRClass.constructor = JRClass; JRClass.extend = arguments.callee; return JRClass;};})();
+
+// Video JS Player Class
+var VideoJS = JRClass.extend({
+
+  // Initialize the player for the supplied video tag element
+  // element: video tag
+  init: function(element, setOptions){
+
+    // Allow an ID string or an element
+    if (typeof element == 'string') {
+      this.video = document.getElementById(element);
+    } else {
+      this.video = element;
+    }
+    // Store reference to player on the video element.
+    // So you can acess the player later: document.getElementById("video_id").player.play();
+    this.video.player = this;
+    this.values = {}; // Cache video values.
+    this.elements = {}; // Store refs to controls elements.
+
+    // Default Options
+    this.options = {
+      autoplay: false,
+      preload: true,
+      useBuiltInControls: false, // Use the browser's controls (iPhone)
+      controlsBelow: false, // Display control bar below video vs. in front of
+      controlsAtStart: false, // Make controls visible when page loads
+      controlsHiding: true, // Hide controls when not over the video
+      defaultVolume: 0.85, // Will be overridden by localStorage volume if available
+      playerFallbackOrder: ["html5", "flash", "links"], // Players and order to use them
+      flashPlayer: "htmlObject",
+      flashPlayerVersion: false // Required flash version for fallback
+    };
+    // Override default options with global options
+    if (typeof VideoJS.options == "object") { _V_.merge(this.options, VideoJS.options); }
+    // Override default & global options with options specific to this player
+    if (typeof setOptions == "object") { _V_.merge(this.options, setOptions); }
+    // Override preload & autoplay with video attributes
+    if (this.getPreloadAttribute() !== undefined) { this.options.preload = this.getPreloadAttribute(); }
+    if (this.getAutoplayAttribute() !== undefined) { this.options.autoplay = this.getAutoplayAttribute(); }
+
+    // Store reference to embed code pieces
+    this.box = this.video.parentNode;
+    this.linksFallback = this.getLinksFallback();
+    this.hideLinksFallback(); // Will be shown again if "links" player is used
+
+    // Loop through the player names list in options, "html5" etc.
+    // For each player name, initialize the player with that name under VideoJS.players
+    // If the player successfully initializes, we're done
+    // If not, try the next player in the list
+    this.each(this.options.playerFallbackOrder, function(playerType){
+      if (this[playerType+"Supported"]()) { // Check if player type is supported
+        this[playerType+"Init"](); // Initialize player type
+        return true; // Stop looping though players
+      }
+    });
+
+    // Start Global Listeners - API doesn't exist before now
+    this.activateElement(this, "player");
+    this.activateElement(this.box, "box");
+  },
+  /* Behaviors
+  ================================================================================ */
+  behaviors: {},
+  newBehavior: function(name, activate, functions){
+    this.behaviors[name] = activate;
+    this.extend(functions);
+  },
+  activateElement: function(element, behavior){
+    // Allow passing and ID string
+    if (typeof element == "string") { element = document.getElementById(element); }
+    this.behaviors[behavior].call(this, element);
+  },
+  /* Errors/Warnings
+  ================================================================================ */
+  errors: [], // Array to track errors
+  warnings: [],
+  warning: function(warning){
+    this.warnings.push(warning);
+    this.log(warning);
+  },
+  /* History of errors/events (not quite there yet)
+  ================================================================================ */
+  history: [],
+  log: function(event){
+    if (!event) { return; }
+    if (typeof event == "string") { event = { type: event }; }
+    if (event.type) { this.history.push(event.type); }
+    if (this.history.length >= 50) { this.history.shift(); }
+    try { console.log(event.type); } catch(e) { try { opera.postError(event.type); } catch(e){} }
+  },
+  /* Local Storage
+  ================================================================================ */
+  setLocalStorage: function(key, value){
+    if (!localStorage) { return; }
+    try {
+      localStorage[key] = value;
+    } catch(e) {
+      if (e.code == 22 || e.code == 1014) { // Webkit == 22 / Firefox == 1014
+        this.warning(VideoJS.warnings.localStorageFull);
+      }
+    }
+  },
+  /* Helpers
+  ================================================================================ */
+  getPreloadAttribute: function(){
+    if (typeof this.video.hasAttribute == "function" && this.video.hasAttribute("preload")) {
+      var preload = this.video.getAttribute("preload");
+      // Only included the attribute, thinking it was boolean
+      if (preload === "" || preload === "true") { return "auto"; }
+      if (preload === "false") { return "none"; }
+      return preload;
+    }
+  },
+  getAutoplayAttribute: function(){
+    if (typeof this.video.hasAttribute == "function" && this.video.hasAttribute("autoplay")) {
+      var autoplay = this.video.getAttribute("autoplay");
+      if (autoplay === "false") { return false; }
+      return true;
+    }
+  },
+  // Calculates amoutn of buffer is full
+  bufferedPercent: function(){ return (this.duration()) ? this.buffered()[1] / this.duration() : 0; },
+  // Each that maintains player as context
+  // Break if true is returned
+  each: function(arr, fn){
+    if (!arr || arr.length === 0) { return; }
+    for (var i=0,j=arr.length; i<j; i++) {
+      if (fn.call(this, arr[i], i)) { break; }
+    }
+  },
+  extend: function(obj){
+    for (var attrname in obj) {
+      if (obj.hasOwnProperty(attrname)) { this[attrname]=obj[attrname]; }
+    }
+  }
+});
+VideoJS.player = VideoJS.prototype;
+
+////////////////////////////////////////////////////////////////////////////////
+// Player Types
+////////////////////////////////////////////////////////////////////////////////
+
+/* Flash Object Fallback (Player Type)
+================================================================================ */
+VideoJS.player.extend({
+  flashSupported: function(){
+    if (!this.flashElement) { this.flashElement = this.getFlashElement(); }
+    // Check if object exists & Flash Player version is supported
+    if (this.flashElement && this.flashPlayerVersionSupported()) {
+      return true;
+    } else {
+      return false;
+    }
+  },
+  flashInit: function(){
+    this.replaceWithFlash();
+    this.element = this.flashElement;
+    this.video.src = ""; // Stop video from downloading if HTML5 is still supported
+    var flashPlayerType = VideoJS.flashPlayers[this.options.flashPlayer];
+    this.extend(VideoJS.flashPlayers[this.options.flashPlayer].api);
+    (flashPlayerType.init.context(this))();
+  },
+  // Get Flash Fallback object element from Embed Code
+  getFlashElement: function(){
+    var children = this.video.children;
+    for (var i=0,j=children.length; i<j; i++) {
+      if (children[i].className == "vjs-flash-fallback") {
+        return children[i];
+      }
+    }
+  },
+  // Used to force a browser to fall back when it's an HTML5 browser but there's no supported sources
+  replaceWithFlash: function(){
+    // this.flashElement = this.video.removeChild(this.flashElement);
+    if (this.flashElement) {
+      this.box.insertBefore(this.flashElement, this.video);
+      this.video.style.display = "none"; // Removing it was breaking later players
+    }
+  },
+  // Check if browser can use this flash player
+  flashPlayerVersionSupported: function(){
+    var playerVersion = (this.options.flashPlayerVersion) ? this.options.flashPlayerVersion : VideoJS.flashPlayers[this.options.flashPlayer].flashPlayerVersion;
+    return VideoJS.getFlashVersion() >= playerVersion;
+  }
+});
+VideoJS.flashPlayers = {};
+VideoJS.flashPlayers.htmlObject = {
+  flashPlayerVersion: 9,
+  init: function() { return true; },
+  api: { // No video API available with HTML Object embed method
+    width: function(width){
+      if (width !== undefined) {
+        this.element.width = width;
+        this.box.style.width = width+"px";
+        this.triggerResizeListeners();
+        return this;
+      }
+      return this.element.width;
+    },
+    height: function(height){
+      if (height !== undefined) {
+        this.element.height = height;
+        this.box.style.height = height+"px";
+        this.triggerResizeListeners();
+        return this;
+      }
+      return this.element.height;
+    }
+  }
+};
+
+
+/* Download Links Fallback (Player Type)
+================================================================================ */
+VideoJS.player.extend({
+  linksSupported: function(){ return true; },
+  linksInit: function(){
+    this.showLinksFallback();
+    this.element = this.video;
+  },
+  // Get the download links block element
+  getLinksFallback: function(){ return this.box.getElementsByTagName("P")[0]; },
+  // Hide no-video download paragraph
+  hideLinksFallback: function(){
+    if (this.linksFallback) { this.linksFallback.style.display = "none"; }
+  },
+  // Hide no-video download paragraph
+  showLinksFallback: function(){
+    if (this.linksFallback) { this.linksFallback.style.display = "block"; }
+  }
+});
+
+////////////////////////////////////////////////////////////////////////////////
+// Class Methods
+// Functions that don't apply to individual videos.
+////////////////////////////////////////////////////////////////////////////////
+
+// Combine Objects - Use "safe" to protect from overwriting existing items
+VideoJS.merge = function(obj1, obj2, safe){
+  for (var attrname in obj2){
+    if (obj2.hasOwnProperty(attrname) && (!safe || !obj1.hasOwnProperty(attrname))) { obj1[attrname]=obj2[attrname]; }
+  }
+  return obj1;
+};
+VideoJS.extend = function(obj){ this.merge(this, obj, true); };
+
+VideoJS.extend({
+  // Add VideoJS to all video tags with the video-js class when the DOM is ready
+  setupAllWhenReady: function(options){
+    // Options is stored globally, and added ot any new player on init
+    VideoJS.options = options;
+    VideoJS.DOMReady(VideoJS.setup);
+  },
+
+  // Run the supplied function when the DOM is ready
+  DOMReady: function(fn){
+    VideoJS.addToDOMReady(fn);
+  },
+
+  // Set up a specific video or array of video elements
+  // "video" can be:
+  //    false, undefined, or "All": set up all videos with the video-js class
+  //    A video tag ID or video tag element: set up one video and return one player
+  //    An array of video tag elements/IDs: set up each and return an array of players
+  setup: function(videos, options){
+    var returnSingular = false,
+    playerList = [],
+    videoElement;
+
+    // If videos is undefined or "All", set up all videos with the video-js class
+    if (!videos || videos == "All") {
+      videos = VideoJS.getVideoJSTags();
+    // If videos is not an array, add to an array
+    } else if (typeof videos != 'object' || videos.nodeType == 1) {
+      videos = [videos];
+      returnSingular = true;
+    }
+
+    // Loop through videos and create players for them
+    for (var i=0; i<videos.length; i++) {
+      if (typeof videos[i] == 'string') {
+        videoElement = document.getElementById(videos[i]);
+      } else { // assume DOM object
+        videoElement = videos[i];
+      }
+      playerList.push(new VideoJS(videoElement, options));
+    }
+
+    // Return one or all depending on what was passed in
+    return (returnSingular) ? playerList[0] : playerList;
+  },
+
+  // Find video tags with the video-js class
+  getVideoJSTags: function() {
+    var videoTags = document.getElementsByTagName("video"),
+    videoJSTags = [], videoTag;
+
+    for (var i=0,j=videoTags.length; i<j; i++) {
+      videoTag = videoTags[i];
+      if (videoTag.className.indexOf("video-js") != -1) {
+        videoJSTags.push(videoTag);
+      }
+    }
+    return videoJSTags;
+  },
+
+  // Check if the browser supports video.
+  browserSupportsVideo: function() {
+    if (typeof VideoJS.videoSupport != "undefined") { return VideoJS.videoSupport; }
+    VideoJS.videoSupport = !!document.createElement('video').canPlayType;
+    return VideoJS.videoSupport;
+  },
+
+  getFlashVersion: function(){
+    // Cache Version
+    if (typeof VideoJS.flashVersion != "undefined") { return VideoJS.flashVersion; }
+    var version = 0, desc;
+    if (typeof navigator.plugins != "undefined" && typeof navigator.plugins["Shockwave Flash"] == "object") {
+      desc = navigator.plugins["Shockwave Flash"].description;
+      if (desc && !(typeof navigator.mimeTypes != "undefined" && navigator.mimeTypes["application/x-shockwave-flash"] && !navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin)) {
+        version = parseInt(desc.match(/^.*\s+([^\s]+)\.[^\s]+\s+[^\s]+$/)[1], 10);
+      }
+    } else if (typeof window.ActiveXObject != "undefined") {
+      try {
+        var testObject = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+        if (testObject) {
+          version = parseInt(testObject.GetVariable("$version").match(/^[^\s]+\s(\d+)/)[1], 10);
+        }
+      }
+      catch(e) {}
+    }
+    VideoJS.flashVersion = version;
+    return VideoJS.flashVersion;
+  },
+
+  // Browser & Device Checks
+  isIE: function(){ return !+"\v1"; },
+  isIPad: function(){ return navigator.userAgent.match(/iPad/i) !== null; },
+  isIPhone: function(){ return navigator.userAgent.match(/iPhone/i) !== null; },
+  isIOS: function(){ return VideoJS.isIPhone() || VideoJS.isIPad(); },
+  iOSVersion: function() {
+    var match = navigator.userAgent.match(/OS (\d+)_/i);
+    if (match && match[1]) { return match[1]; }
+  },
+  isAndroid: function(){ return navigator.userAgent.match(/Android/i) !== null; },
+  androidVersion: function() {
+    var match = navigator.userAgent.match(/Android (\d+)\./i);
+    if (match && match[1]) { return match[1]; }
+  },
+
+  warnings: {
+    // Safari errors if you call functions on a video that hasn't loaded yet
+    videoNotReady: "Video is not ready yet (try playing the video first).",
+    // Getting a QUOTA_EXCEEDED_ERR when setting local storage occasionally
+    localStorageFull: "Local Storage is Full"
+  }
+});
+
+// Shim to make Video tag valid in IE
+if(VideoJS.isIE()) { document.createElement("video"); }
+
+// Expose to global
+window.VideoJS = window._V_ = VideoJS;
+
+/* HTML5 Player Type
+================================================================================ */
+VideoJS.player.extend({
+  html5Supported: function(){
+    if (VideoJS.browserSupportsVideo() && this.canPlaySource()) {
+      return true;
+    } else {
+      return false;
+    }
+  },
+  html5Init: function(){
+    this.element = this.video;
+
+    this.fixPreloading(); // Support old browsers that used autobuffer
+    this.supportProgressEvents(); // Support browsers that don't use 'buffered'
+
+    // Set to stored volume OR 85%
+    this.volume((localStorage && localStorage.volume) || this.options.defaultVolume);
+
+    // Update interface for device needs
+    if (VideoJS.isIOS()) {
+      this.options.useBuiltInControls = true;
+      this.iOSInterface();
+    } else if (VideoJS.isAndroid()) {
+      this.options.useBuiltInControls = true;
+      this.androidInterface();
+    }
+
+    // Add VideoJS Controls
+    if (!this.options.useBuiltInControls) {
+      this.video.controls = false;
+
+      if (this.options.controlsBelow) { _V_.addClass(this.box, "vjs-controls-below"); }
+
+      // Make a click on th video act as a play button
+      this.activateElement(this.video, "playToggle");
+
+      // Build Interface
+      this.buildStylesCheckDiv(); // Used to check if style are loaded
+      this.buildAndActivatePoster();
+      this.buildBigPlayButton();
+      this.buildAndActivateSpinner();
+      this.buildAndActivateControlBar();
+      this.loadInterface(); // Show everything once styles are loaded
+      this.getSubtitles();
+    }
+  },
+  /* Source Managemet
+  ================================================================================ */
+  canPlaySource: function(){
+    // Cache Result
+    if (this.canPlaySourceResult) { return this.canPlaySourceResult; }
+    // Loop through sources and check if any can play
+    var children = this.video.children;
+    for (var i=0,j=children.length; i<j; i++) {
+      if (children[i].tagName.toUpperCase() == "SOURCE") {
+        var canPlay = this.video.canPlayType(children[i].type) || this.canPlayExt(children[i].src);
+        if (canPlay == "probably" || canPlay == "maybe") {
+          this.firstPlayableSource = children[i];
+          this.canPlaySourceResult = true;
+          return true;
+        }
+      }
+    }
+    this.canPlaySourceResult = false;
+    return false;
+  },
+  // Check if the extention is compatible, for when type won't work
+  canPlayExt: function(src){
+    if (!src) { return ""; }
+    var match = src.match(/\.([^\.]+)$/);
+    if (match && match[1]) {
+      var ext = match[1].toLowerCase();
+      // Android canPlayType doesn't work
+      if (VideoJS.isAndroid()) {
+        if (ext == "mp4" || ext == "m4v") { return "maybe"; }
+      // Allow Apple HTTP Streaming for iOS
+      } else if (VideoJS.isIOS()) {
+        if (ext == "m3u8") { return "maybe"; }
+      }
+    }
+    return "";
+  },
+  // Force the video source - Helps fix loading bugs in a handful of devices, like the iPad/iPhone poster bug
+  // And iPad/iPhone javascript include location bug. And Android type attribute bug
+  forceTheSource: function(){
+    this.video.src = this.firstPlayableSource.src; // From canPlaySource()
+    this.video.load();
+  },
+  /* Device Fixes
+  ================================================================================ */
+  // Support older browsers that used "autobuffer"
+  fixPreloading: function(){
+    if (typeof this.video.hasAttribute == "function" && this.video.hasAttribute("preload") && this.video.preload != "none") {
+      this.video.autobuffer = true; // Was a boolean
+    } else {
+      this.video.autobuffer = false;
+      this.video.preload = "none";
+    }
+  },
+
+  // Listen for Video Load Progress (currently does not if html file is local)
+  // Buffered does't work in all browsers, so watching progress as well
+  supportProgressEvents: function(e){
+    _V_.addListener(this.video, 'progress', this.playerOnVideoProgress.context(this));
+  },
+  playerOnVideoProgress: function(event){
+    this.setBufferedFromProgress(event);
+  },
+  setBufferedFromProgress: function(event){ // HTML5 Only
+    if(event.total > 0) {
+      var newBufferEnd = (event.loaded / event.total) * this.duration();
+      if (newBufferEnd > this.values.bufferEnd) { this.values.bufferEnd = newBufferEnd; }
+    }
+  },
+
+  iOSInterface: function(){
+    if(VideoJS.iOSVersion() < 4) { this.forceTheSource(); } // Fix loading issues
+    if(VideoJS.isIPad()) { // iPad could work with controlsBelow
+      this.buildAndActivateSpinner(); // Spinner still works well on iPad, since iPad doesn't have one
+    }
+  },
+
+  // Fix android specific quirks
+  // Use built-in controls, but add the big play button, since android doesn't have one.
+  androidInterface: function(){
+    this.forceTheSource(); // Fix loading issues
+    _V_.addListener(this.video, "click", function(){ this.play(); }); // Required to play
+    this.buildBigPlayButton(); // But don't activate the normal way. Pause doesn't work right on android.
+    _V_.addListener(this.bigPlayButton, "click", function(){ this.play(); }.context(this));
+    this.positionBox();
+    this.showBigPlayButtons();
+  },
+  /* Wait for styles (TODO: move to _V_)
+  ================================================================================ */
+  loadInterface: function(){
+    if(!this.stylesHaveLoaded()) {
+      // Don't want to create an endless loop either.
+      if (!this.positionRetries) { this.positionRetries = 1; }
+      if (this.positionRetries++ < 100) {
+        setTimeout(this.loadInterface.context(this),10);
+        return;
+      }
+    }
+    this.hideStylesCheckDiv();
+    this.showPoster();
+    if (this.video.paused !== false) { this.showBigPlayButtons(); }
+    if (this.options.controlsAtStart) { this.showControlBars(); }
+    this.positionAll();
+  },
+  /* Control Bar
+  ================================================================================ */
+  buildAndActivateControlBar: function(){
+    /* Creating this HTML
+      <div class="vjs-controls">
+        <div class="vjs-play-control">
+          <span></span>
+        </div>
+        <div class="vjs-progress-control">
+          <div class="vjs-progress-holder">
+            <div class="vjs-load-progress"></div>
+            <div class="vjs-play-progress"></div>
+          </div>
+        </div>
+        <div class="vjs-time-control">
+          <span class="vjs-current-time-display">00:00</span><span> / </span><span class="vjs-duration-display">00:00</span>
+        </div>
+        <div class="vjs-volume-control">
+          <div>
+            <span></span><span></span><span></span><span></span><span></span><span></span>
+          </div>
+        </div>
+        <div class="vjs-fullscreen-control">
+          <div>
+            <span></span><span></span><span></span><span></span>
+          </div>
+        </div>
+      </div>
+    */
+
+    // Create a div to hold the different controls
+    this.controls = _V_.createElement("div", { className: "vjs-controls" });
+    // Add the controls to the video's container
+    this.box.appendChild(this.controls);
+    this.activateElement(this.controls, "controlBar");
+    this.activateElement(this.controls, "mouseOverVideoReporter");
+
+    // Build the play control
+    this.playControl = _V_.createElement("div", { className: "vjs-play-control", innerHTML: "<span></span>" });
+    this.controls.appendChild(this.playControl);
+    this.activateElement(this.playControl, "playToggle");
+
+    // Build the progress control
+    this.progressControl = _V_.createElement("div", { className: "vjs-progress-control" });
+    this.controls.appendChild(this.progressControl);
+
+    // Create a holder for the progress bars
+    this.progressHolder = _V_.createElement("div", { className: "vjs-progress-holder" });
+    this.progressControl.appendChild(this.progressHolder);
+    this.activateElement(this.progressHolder, "currentTimeScrubber");
+
+    // Create the loading progress display
+    this.loadProgressBar = _V_.createElement("div", { className: "vjs-load-progress" });
+    this.progressHolder.appendChild(this.loadProgressBar);
+    this.activateElement(this.loadProgressBar, "loadProgressBar");
+
+    // Create the playing progress display
+    this.playProgressBar = _V_.createElement("div", { className: "vjs-play-progress" });
+    this.progressHolder.appendChild(this.playProgressBar);
+    this.activateElement(this.playProgressBar, "playProgressBar");
+
+    // Create the progress time display (00:00 / 00:00)
+    this.timeControl = _V_.createElement("div", { className: "vjs-time-control" });
+    this.controls.appendChild(this.timeControl);
+
+    // Create the current play time display
+    this.currentTimeDisplay = _V_.createElement("span", { className: "vjs-current-time-display", innerHTML: "00:00" });
+    this.timeControl.appendChild(this.currentTimeDisplay);
+    this.activateElement(this.currentTimeDisplay, "currentTimeDisplay");
+
+    // Add time separator
+    this.timeSeparator = _V_.createElement("span", { innerHTML: " / " });
+    this.timeControl.appendChild(this.timeSeparator);
+
+    // Create the total duration display
+    this.durationDisplay = _V_.createElement("span", { className: "vjs-duration-display", innerHTML: "00:00" });
+    this.timeControl.appendChild(this.durationDisplay);
+    this.activateElement(this.durationDisplay, "durationDisplay");
+
+    // Create the volumne control
+    this.volumeControl = _V_.createElement("div", {
+      className: "vjs-volume-control",
+      innerHTML: "<div><span></span><span></span><span></span><span></span><span></span><span></span></div>"
+    });
+    this.controls.appendChild(this.volumeControl);
+    this.activateElement(this.volumeControl, "volumeScrubber");
+
+    this.volumeDisplay = this.volumeControl.children[0];
+    this.activateElement(this.volumeDisplay, "volumeDisplay");
+
+    // Crete the fullscreen control
+    this.fullscreenControl = _V_.createElement("div", {
+      className: "vjs-fullscreen-control",
+      innerHTML: "<div><span></span><span></span><span></span><span></span></div>"
+    });
+    this.controls.appendChild(this.fullscreenControl);
+    this.activateElement(this.fullscreenControl, "fullscreenToggle");
+  },
+  /* Poster Image
+  ================================================================================ */
+  buildAndActivatePoster: function(){
+    this.updatePosterSource();
+    if (this.video.poster) {
+      this.poster = document.createElement("img");
+      // Add poster to video box
+      this.box.appendChild(this.poster);
+
+      // Add poster image data
+      this.poster.src = this.video.poster;
+      // Add poster styles
+      this.poster.className = "vjs-poster";
+      this.activateElement(this.poster, "poster");
+    } else {
+      this.poster = false;
+    }
+  },
+  /* Big Play Button
+  ================================================================================ */
+  buildBigPlayButton: function(){
+    /* Creating this HTML
+      <div class="vjs-big-play-button"><span></span></div>
+    */
+    this.bigPlayButton = _V_.createElement("div", {
+      className: "vjs-big-play-button",
+      innerHTML: "<span></span>"
+    });
+    this.box.appendChild(this.bigPlayButton);
+    this.activateElement(this.bigPlayButton, "bigPlayButton");
+  },
+  /* Spinner (Loading)
+  ================================================================================ */
+  buildAndActivateSpinner: function(){
+    this.spinner = _V_.createElement("div", {
+      className: "vjs-spinner",
+      innerHTML: "<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>"
+    });
+    this.box.appendChild(this.spinner);
+    this.activateElement(this.spinner, "spinner");
+  },
+  /* Styles Check - Check if styles are loaded (move ot _V_)
+  ================================================================================ */
+  // Sometimes the CSS styles haven't been applied to the controls yet
+  // when we're trying to calculate the height and position them correctly.
+  // This causes a flicker where the controls are out of place.
+  buildStylesCheckDiv: function(){
+    this.stylesCheckDiv = _V_.createElement("div", { className: "vjs-styles-check" });
+    this.stylesCheckDiv.style.position = "absolute";
+    this.box.appendChild(this.stylesCheckDiv);
+  },
+  hideStylesCheckDiv: function(){ this.stylesCheckDiv.style.display = "none"; },
+  stylesHaveLoaded: function(){
+    if (this.stylesCheckDiv.offsetHeight != 5) {
+       return false;
+    } else {
+      return true;
+    }
+  },
+  /* VideoJS Box - Holds all elements
+  ================================================================================ */
+  positionAll: function(){
+    this.positionBox();
+    this.positionControlBars();
+    this.positionPoster();
+  },
+  positionBox: function(){
+    // Set width based on fullscreen or not.
+    if (this.videoIsFullScreen) {
+      this.box.style.width = "";
+      this.element.style.height="";
+      if (this.options.controlsBelow) {
+        this.box.style.height = "";
+        this.element.style.height = (this.box.offsetHeight - this.controls.offsetHeight) + "px";
+      }
+    } else {
+      this.box.style.width = this.width() + "px";
+      this.element.style.height=this.height()+"px";
+      if (this.options.controlsBelow) {
+        this.element.style.height = "";
+        // this.box.style.height = this.video.offsetHeight + this.controls.offsetHeight + "px";
+      }
+    }
+  },
+  /* Subtitles
+  ================================================================================ */
+  getSubtitles: function(){
+    var tracks = this.video.getElementsByTagName("TRACK");
+    for (var i=0,j=tracks.length; i<j; i++) {
+      if (tracks[i].getAttribute("kind") == "subtitles" && tracks[i].getAttribute("src")) {
+        this.subtitlesSource = tracks[i].getAttribute("src");
+        this.loadSubtitles();
+        this.buildSubtitles();
+      }
+    }
+  },
+  loadSubtitles: function() { _V_.get(this.subtitlesSource, this.parseSubtitles.context(this)); },
+  parseSubtitles: function(subText) {
+    var lines = subText.split("\n"),
+        line = "",
+        subtitle, time, text;
+    this.subtitles = [];
+    this.currentSubtitle = false;
+    this.lastSubtitleIndex = 0;
+
+    for (var i=0; i<lines.length; i++) {
+      line = _V_.trim(lines[i]); // Trim whitespace and linebreaks
+      if (line) { // Loop until a line with content
+
+        // First line - Number
+        subtitle = {
+          id: line, // Subtitle Number
+          index: this.subtitles.length // Position in Array
+        };
+
+        // Second line - Time
+        line = _V_.trim(lines[++i]);
+        time = line.split(" --> ");
+        subtitle.start = this.parseSubtitleTime(time[0]);
+        subtitle.end = this.parseSubtitleTime(time[1]);
+
+        // Additional lines - Subtitle Text
+        text = [];
+        for (var j=i; j<lines.length; j++) { // Loop until a blank line or end of lines
+          line = _V_.trim(lines[++i]);
+          if (!line) { break; }
+          text.push(line);
+        }
+        subtitle.text = text.join('<br/>');
+
+        // Add this subtitle
+        this.subtitles.push(subtitle);
+      }
+    }
+  },
+
+  parseSubtitleTime: function(timeText) {
+    var parts = timeText.split(':'),
+        time = 0;
+    // hours => seconds
+    time += parseFloat(parts[0])*60*60;
+    // minutes => seconds
+    time += parseFloat(parts[1])*60;
+    // get seconds
+    var seconds = parts[2].split(/\.|,/); // Either . or ,
+    time += parseFloat(seconds[0]);
+    // add miliseconds
+    ms = parseFloat(seconds[1]);
+    if (ms) { time += ms/1000; }
+    return time;
+  },
+
+  buildSubtitles: function(){
+    /* Creating this HTML
+      <div class="vjs-subtitles"></div>
+    */
+    this.subtitlesDisplay = _V_.createElement("div", { className: 'vjs-subtitles' });
+    this.box.appendChild(this.subtitlesDisplay);
+    this.activateElement(this.subtitlesDisplay, "subtitlesDisplay");
+  },
+
+  /* Player API - Translate functionality from player to video
+  ================================================================================ */
+  addVideoListener: function(type, fn){ _V_.addListener(this.video, type, fn.rEvtContext(this)); },
+
+  play: function(){
+    this.video.play();
+    return this;
+  },
+  onPlay: function(fn){ this.addVideoListener("play", fn); return this; },
+
+  pause: function(){
+    this.video.pause();
+    return this;
+  },
+  onPause: function(fn){ this.addVideoListener("pause", fn); return this; },
+  paused: function() { return this.video.paused; },
+
+  currentTime: function(seconds){
+    if (seconds !== undefined) {
+      try { this.video.currentTime = seconds; }
+      catch(e) { this.warning(VideoJS.warnings.videoNotReady); }
+      this.values.currentTime = seconds;
+      return this;
+    }
+    return this.video.currentTime;
+  },
+  onCurrentTimeUpdate: function(fn){
+    this.currentTimeListeners.push(fn);
+  },
+
+  duration: function(){
+    return this.video.duration;
+  },
+
+  buffered: function(){
+    // Storing values allows them be overridden by setBufferedFromProgress
+    if (this.values.bufferStart === undefined) {
+      this.values.bufferStart = 0;
+      this.values.bufferEnd = 0;
+    }
+    if (this.video.buffered && this.video.buffered.length > 0) {
+      var newEnd = this.video.buffered.end(0);
+      if (newEnd > this.values.bufferEnd) { this.values.bufferEnd = newEnd; }
+    }
+    return [this.values.bufferStart, this.values.bufferEnd];
+  },
+
+  volume: function(percentAsDecimal){
+    if (percentAsDecimal !== undefined) {
+      // Force value to between 0 and 1
+      this.values.volume = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
+      this.video.volume = this.values.volume;
+      this.setLocalStorage("volume", this.values.volume);
+      return this;
+    }
+    if (this.values.volume) { return this.values.volume; }
+    return this.video.volume;
+  },
+  onVolumeChange: function(fn){ _V_.addListener(this.video, 'volumechange', fn.rEvtContext(this)); },
+
+  width: function(width){
+    if (width !== undefined) {
+      this.video.width = width; // Not using style so it can be overridden on fullscreen.
+      this.box.style.width = width+"px";
+      this.triggerResizeListeners();
+      return this;
+    }
+    return this.video.offsetWidth;
+  },
+  height: function(height){
+    if (height !== undefined) {
+      this.video.height = height;
+      this.box.style.height = height+"px";
+      this.triggerResizeListeners();
+      return this;
+    }
+    return this.video.offsetHeight;
+  },
+
+  supportsFullScreen: function(){
+    if(typeof this.video.webkitEnterFullScreen == 'function') {
+      // Seems to be broken in Chromium/Chrome
+      if (!navigator.userAgent.match("Chrome") && !navigator.userAgent.match("Mac OS X 10.5")) {
+        return true;
+      }
+    }
+    return false;
+  },
+
+  html5EnterNativeFullScreen: function(){
+    try {
+      this.video.webkitEnterFullScreen();
+    } catch (e) {
+      if (e.code == 11) { this.warning(VideoJS.warnings.videoNotReady); }
+    }
+    return this;
+  },
+
+  // Turn on fullscreen (window) mode
+  // Real fullscreen isn't available in browsers quite yet.
+  enterFullScreen: function(){
+    if (this.supportsFullScreen()) {
+      this.html5EnterNativeFullScreen();
+    } else {
+      this.enterFullWindow();
+    }
+  },
+
+  exitFullScreen: function(){
+    if (this.supportsFullScreen()) {
+      // Shouldn't be called
+    } else {
+      this.exitFullWindow();
+    }
+  },
+
+  enterFullWindow: function(){
+    this.videoIsFullScreen = true;
+    // Storing original doc overflow value to return to when fullscreen is off
+    this.docOrigOverflow = document.documentElement.style.overflow;
+    // Add listener for esc key to exit fullscreen
+    _V_.addListener(document, "keydown", this.fullscreenOnEscKey.rEvtContext(this));
+    // Add listener for a window resize
+    _V_.addListener(window, "resize", this.fullscreenOnWindowResize.rEvtContext(this));
+    // Hide any scroll bars
+    document.documentElement.style.overflow = 'hidden';
+    // Apply fullscreen styles
+    _V_.addClass(this.box, "vjs-fullscreen");
+    // Resize the box, controller, and poster
+    this.positionAll();
+  },
+
+  // Turn off fullscreen (window) mode
+  exitFullWindow: function(){
+    this.videoIsFullScreen = false;
+    document.removeEventListener("keydown", this.fullscreenOnEscKey, false);
+    window.removeEventListener("resize", this.fullscreenOnWindowResize, false);
+    // Unhide scroll bars.
+    document.documentElement.style.overflow = this.docOrigOverflow;
+    // Remove fullscreen styles
+    _V_.removeClass(this.box, "vjs-fullscreen");
+    // Resize the box, controller, and poster to original sizes
+    this.positionAll();
+  },
+
+  onError: function(fn){ this.addVideoListener("error", fn); return this; },
+  onEnded: function(fn){
+    this.addVideoListener("ended", fn); return this;
+  }
+});
+
+////////////////////////////////////////////////////////////////////////////////
+// Element Behaviors
+// Tell elements how to act or react
+////////////////////////////////////////////////////////////////////////////////
+
+/* Player Behaviors - How VideoJS reacts to what the video is doing.
+================================================================================ */
+VideoJS.player.newBehavior("player", function(player){
+    this.onError(this.playerOnVideoError);
+    // Listen for when the video is played
+    this.onPlay(this.playerOnVideoPlay);
+    this.onPlay(this.trackCurrentTime);
+    // Listen for when the video is paused
+    this.onPause(this.playerOnVideoPause);
+    this.onPause(this.stopTrackingCurrentTime);
+    // Listen for when the video ends
+    this.onEnded(this.playerOnVideoEnded);
+    // Set interval for load progress using buffer watching method
+    // this.trackCurrentTime();
+    this.trackBuffered();
+    // Buffer Full
+    this.onBufferedUpdate(this.isBufferFull);
+  },{
+    playerOnVideoError: function(event){
+      this.log(event);
+      this.log(this.video.error);
+    },
+    playerOnVideoPlay: function(event){ this.hasPlayed = true; },
+    playerOnVideoPause: function(event){},
+    playerOnVideoEnded: function(event){
+      this.currentTime(0);
+      this.pause();
+    },
+
+    /* Load Tracking -------------------------------------------------------------- */
+    // Buffer watching method for load progress.
+    // Used for browsers that don't support the progress event
+    trackBuffered: function(){
+      this.bufferedInterval = setInterval(this.triggerBufferedListeners.context(this), 500);
+    },
+    stopTrackingBuffered: function(){ clearInterval(this.bufferedInterval); },
+    bufferedListeners: [],
+    onBufferedUpdate: function(fn){
+      this.bufferedListeners.push(fn);
+    },
+    triggerBufferedListeners: function(){
+      this.isBufferFull();
+      this.each(this.bufferedListeners, function(listener){
+        (listener.context(this))();
+      });
+    },
+    isBufferFull: function(){
+      if (this.bufferedPercent() == 1) { this.stopTrackingBuffered(); }
+    },
+
+    /* Time Tracking -------------------------------------------------------------- */
+    trackCurrentTime: function(){
+      if (this.currentTimeInterval) { clearInterval(this.currentTimeInterval); }
+      this.currentTimeInterval = setInterval(this.triggerCurrentTimeListeners.context(this), 100); // 42 = 24 fps
+      this.trackingCurrentTime = true;
+    },
+    // Turn off play progress tracking (when paused or dragging)
+    stopTrackingCurrentTime: function(){
+      clearInterval(this.currentTimeInterval);
+      this.trackingCurrentTime = false;
+    },
+    currentTimeListeners: [],
+    // onCurrentTimeUpdate is in API section now
+    triggerCurrentTimeListeners: function(late, newTime){ // FF passes milliseconds late as the first argument
+      this.each(this.currentTimeListeners, function(listener){
+        (listener.context(this))(newTime || this.currentTime());
+      });
+    },
+
+    /* Resize Tracking -------------------------------------------------------------- */
+    resizeListeners: [],
+    onResize: function(fn){
+      this.resizeListeners.push(fn);
+    },
+    // Trigger anywhere the video/box size is changed.
+    triggerResizeListeners: function(){
+      this.each(this.resizeListeners, function(listener){
+        (listener.context(this))();
+      });
+    }
+  }
+);
+/* Mouse Over Video Reporter Behaviors - i.e. Controls hiding based on mouse location
+================================================================================ */
+VideoJS.player.newBehavior("mouseOverVideoReporter", function(element){
+    // Listen for the mouse move the video. Used to reveal the controller.
+    _V_.addListener(element, "mousemove", this.mouseOverVideoReporterOnMouseMove.context(this));
+    // Listen for the mouse moving out of the video. Used to hide the controller.
+    _V_.addListener(element, "mouseout", this.mouseOverVideoReporterOnMouseOut.context(this));
+  },{
+    mouseOverVideoReporterOnMouseMove: function(){
+      this.showControlBars();
+      clearInterval(this.mouseMoveTimeout);
+      this.mouseMoveTimeout = setTimeout(this.hideControlBars.context(this), 4000);
+    },
+    mouseOverVideoReporterOnMouseOut: function(event){
+      // Prevent flicker by making sure mouse hasn't left the video
+      var parent = event.relatedTarget;
+      while (parent && parent !== this.box) {
+        parent = parent.parentNode;
+      }
+      if (parent !== this.box) {
+        this.hideControlBars();
+      }
+    }
+  }
+);
+/* Mouse Over Video Reporter Behaviors - i.e. Controls hiding based on mouse location
+================================================================================ */
+VideoJS.player.newBehavior("box", function(element){
+    this.positionBox();
+    _V_.addClass(element, "vjs-paused");
+    this.activateElement(element, "mouseOverVideoReporter");
+    this.onPlay(this.boxOnVideoPlay);
+    this.onPause(this.boxOnVideoPause);
+  },{
+    boxOnVideoPlay: function(){
+      _V_.removeClass(this.box, "vjs-paused");
+      _V_.addClass(this.box, "vjs-playing");
+    },
+    boxOnVideoPause: function(){
+      _V_.removeClass(this.box, "vjs-playing");
+      _V_.addClass(this.box, "vjs-paused");
+    }
+  }
+);
+/* Poster Image Overlay
+================================================================================ */
+VideoJS.player.newBehavior("poster", function(element){
+    this.activateElement(element, "mouseOverVideoReporter");
+    this.activateElement(element, "playButton");
+    this.onPlay(this.hidePoster);
+    this.onEnded(this.showPoster);
+    this.onResize(this.positionPoster);
+  },{
+    showPoster: function(){
+      if (!this.poster) { return; }
+      this.poster.style.display = "block";
+      this.positionPoster();
+    },
+    positionPoster: function(){
+      // Only if the poster is visible
+      if (!this.poster || this.poster.style.display == 'none') { return; }
+      this.poster.style.height = this.height() + "px"; // Need incase controlsBelow
+      this.poster.style.width = this.width() + "px"; // Could probably do 100% of box
+    },
+    hidePoster: function(){
+      if (!this.poster) { return; }
+      this.poster.style.display = "none";
+    },
+    // Update poster source from attribute or fallback image
+    // iPad breaks if you include a poster attribute, so this fixes that
+    updatePosterSource: function(){
+      if (!this.video.poster) {
+        var images = this.video.getElementsByTagName("img");
+        if (images.length > 0) { this.video.poster = images[0].src; }
+      }
+    }
+  }
+);
+/* Control Bar Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("controlBar", function(element){
+    if (!this.controlBars) {
+      this.controlBars = [];
+      this.onResize(this.positionControlBars);
+    }
+    this.controlBars.push(element);
+    _V_.addListener(element, "mousemove", this.onControlBarsMouseMove.context(this));
+    _V_.addListener(element, "mouseout", this.onControlBarsMouseOut.context(this));
+  },{
+    showControlBars: function(){
+      if (!this.options.controlsAtStart && !this.hasPlayed) { return; }
+      this.each(this.controlBars, function(bar){
+        bar.style.display = "block";
+      });
+    },
+    // Place controller relative to the video's position (now just resizing bars)
+    positionControlBars: function(){
+      this.updatePlayProgressBars();
+      this.updateLoadProgressBars();
+    },
+    hideControlBars: function(){
+      if (this.options.controlsHiding && !this.mouseIsOverControls) {
+        this.each(this.controlBars, function(bar){
+          bar.style.display = "none";
+        });
+      }
+    },
+    // Block controls from hiding when mouse is over them.
+    onControlBarsMouseMove: function(){ this.mouseIsOverControls = true; },
+    onControlBarsMouseOut: function(event){
+      this.mouseIsOverControls = false;
+    }
+  }
+);
+/* PlayToggle, PlayButton, PauseButton Behaviors
+================================================================================ */
+// Play Toggle
+VideoJS.player.newBehavior("playToggle", function(element){
+    if (!this.elements.playToggles) {
+      this.elements.playToggles = [];
+      this.onPlay(this.playTogglesOnPlay);
+      this.onPause(this.playTogglesOnPause);
+    }
+    this.elements.playToggles.push(element);
+    _V_.addListener(element, "click", this.onPlayToggleClick.context(this));
+  },{
+    onPlayToggleClick: function(event){
+      if (this.paused()) {
+        this.play();
+      } else {
+        this.pause();
+      }
+    },
+    playTogglesOnPlay: function(event){
+      this.each(this.elements.playToggles, function(toggle){
+        _V_.removeClass(toggle, "vjs-paused");
+        _V_.addClass(toggle, "vjs-playing");
+      });
+    },
+    playTogglesOnPause: function(event){
+      this.each(this.elements.playToggles, function(toggle){
+        _V_.removeClass(toggle, "vjs-playing");
+        _V_.addClass(toggle, "vjs-paused");
+      });
+    }
+  }
+);
+// Play
+VideoJS.player.newBehavior("playButton", function(element){
+    _V_.addListener(element, "click", this.onPlayButtonClick.context(this));
+  },{
+    onPlayButtonClick: function(event){ this.play(); }
+  }
+);
+// Pause
+VideoJS.player.newBehavior("pauseButton", function(element){
+    _V_.addListener(element, "click", this.onPauseButtonClick.context(this));
+  },{
+    onPauseButtonClick: function(event){ this.pause(); }
+  }
+);
+/* Play Progress Bar Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("playProgressBar", function(element){
+    if (!this.playProgressBars) {
+      this.playProgressBars = [];
+      this.onCurrentTimeUpdate(this.updatePlayProgressBars);
+    }
+    this.playProgressBars.push(element);
+  },{
+    // Ajust the play progress bar's width based on the current play time
+    updatePlayProgressBars: function(newTime){
+      var progress = (newTime !== undefined) ? newTime / this.duration() : this.currentTime() / this.duration();
+      if (isNaN(progress)) { progress = 0; }
+      this.each(this.playProgressBars, function(bar){
+        if (bar.style) { bar.style.width = _V_.round(progress * 100, 2) + "%"; }
+      });
+    }
+  }
+);
+/* Load Progress Bar Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("loadProgressBar", function(element){
+    if (!this.loadProgressBars) { this.loadProgressBars = []; }
+    this.loadProgressBars.push(element);
+    this.onBufferedUpdate(this.updateLoadProgressBars);
+  },{
+    updateLoadProgressBars: function(){
+      this.each(this.loadProgressBars, function(bar){
+        if (bar.style) { bar.style.width = _V_.round(this.bufferedPercent() * 100, 2) + "%"; }
+      });
+    }
+  }
+);
+
+/* Current Time Display Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("currentTimeDisplay", function(element){
+    if (!this.currentTimeDisplays) {
+      this.currentTimeDisplays = [];
+      this.onCurrentTimeUpdate(this.updateCurrentTimeDisplays);
+    }
+    this.currentTimeDisplays.push(element);
+  },{
+    // Update the displayed time (00:00)
+    updateCurrentTimeDisplays: function(newTime){
+      if (!this.currentTimeDisplays) { return; }
+      // Allows for smooth scrubbing, when player can't keep up.
+      var time = (newTime) ? newTime : this.currentTime();
+      this.each(this.currentTimeDisplays, function(dis){
+        dis.innerHTML = _V_.formatTime(time);
+      });
+    }
+  }
+);
+
+/* Duration Display Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("durationDisplay", function(element){
+    if (!this.durationDisplays) {
+      this.durationDisplays = [];
+      this.onCurrentTimeUpdate(this.updateDurationDisplays);
+    }
+    this.durationDisplays.push(element);
+  },{
+    updateDurationDisplays: function(){
+      if (!this.durationDisplays) { return; }
+      this.each(this.durationDisplays, function(dis){
+        if (this.duration()) { dis.innerHTML = _V_.formatTime(this.duration()); }
+      });
+    }
+  }
+);
+
+/* Current Time Scrubber Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("currentTimeScrubber", function(element){
+    _V_.addListener(element, "mousedown", this.onCurrentTimeScrubberMouseDown.rEvtContext(this));
+  },{
+    // Adjust the play position when the user drags on the progress bar
+    onCurrentTimeScrubberMouseDown: function(event, scrubber){
+      event.preventDefault();
+      this.currentScrubber = scrubber;
+
+      this.stopTrackingCurrentTime(); // Allows for smooth scrubbing
+
+      this.videoWasPlaying = !this.paused();
+      this.pause();
+
+      _V_.blockTextSelection();
+      this.setCurrentTimeWithScrubber(event);
+      _V_.addListener(document, "mousemove", this.onCurrentTimeScrubberMouseMove.rEvtContext(this));
+      _V_.addListener(document, "mouseup", this.onCurrentTimeScrubberMouseUp.rEvtContext(this));
+    },
+    onCurrentTimeScrubberMouseMove: function(event){ // Removeable
+      this.setCurrentTimeWithScrubber(event);
+    },
+    onCurrentTimeScrubberMouseUp: function(event){ // Removeable
+      _V_.unblockTextSelection();
+      document.removeEventListener("mousemove", this.onCurrentTimeScrubberMouseMove, false);
+      document.removeEventListener("mouseup", this.onCurrentTimeScrubberMouseUp, false);
+      if (this.videoWasPlaying) {
+        this.play();
+        this.trackCurrentTime();
+      }
+    },
+    setCurrentTimeWithScrubber: function(event){
+      var newProgress = _V_.getRelativePosition(event.pageX, this.currentScrubber);
+      var newTime = newProgress * this.duration();
+      this.triggerCurrentTimeListeners(0, newTime); // Allows for smooth scrubbing
+      // Don't let video end while scrubbing.
+      if (newTime == this.duration()) { newTime = newTime - 0.1; }
+      this.currentTime(newTime);
+    }
+  }
+);
+/* Volume Display Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("volumeDisplay", function(element){
+    if (!this.volumeDisplays) {
+      this.volumeDisplays = [];
+      this.onVolumeChange(this.updateVolumeDisplays);
+    }
+    this.volumeDisplays.push(element);
+    this.updateVolumeDisplay(element); // Set the display to the initial volume
+  },{
+    // Update the volume control display
+    // Unique to these default controls. Uses borders to create the look of bars.
+    updateVolumeDisplays: function(){
+      if (!this.volumeDisplays) { return; }
+      this.each(this.volumeDisplays, function(dis){
+        this.updateVolumeDisplay(dis);
+      });
+    },
+    updateVolumeDisplay: function(display){
+      var volNum = Math.ceil(this.volume() * 6);
+      this.each(display.children, function(child, num){
+        if (num < volNum) {
+          _V_.addClass(child, "vjs-volume-level-on");
+        } else {
+          _V_.removeClass(child, "vjs-volume-level-on");
+        }
+      });
+    }
+  }
+);
+/* Volume Scrubber Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("volumeScrubber", function(element){
+    _V_.addListener(element, "mousedown", this.onVolumeScrubberMouseDown.rEvtContext(this));
+  },{
+    // Adjust the volume when the user drags on the volume control
+    onVolumeScrubberMouseDown: function(event, scrubber){
+      // event.preventDefault();
+      _V_.blockTextSelection();
+      this.currentScrubber = scrubber;
+      this.setVolumeWithScrubber(event);
+      _V_.addListener(document, "mousemove", this.onVolumeScrubberMouseMove.rEvtContext(this));
+      _V_.addListener(document, "mouseup", this.onVolumeScrubberMouseUp.rEvtContext(this));
+    },
+    onVolumeScrubberMouseMove: function(event){
+      this.setVolumeWithScrubber(event);
+    },
+    onVolumeScrubberMouseUp: function(event){
+      this.setVolumeWithScrubber(event);
+      _V_.unblockTextSelection();
+      document.removeEventListener("mousemove", this.onVolumeScrubberMouseMove, false);
+      document.removeEventListener("mouseup", this.onVolumeScrubberMouseUp, false);
+    },
+    setVolumeWithScrubber: function(event){
+      var newVol = _V_.getRelativePosition(event.pageX, this.currentScrubber);
+      this.volume(newVol);
+    }
+  }
+);
+/* Fullscreen Toggle Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("fullscreenToggle", function(element){
+    _V_.addListener(element, "click", this.onFullscreenToggleClick.context(this));
+  },{
+    // When the user clicks on the fullscreen button, update fullscreen setting
+    onFullscreenToggleClick: function(event){
+      if (!this.videoIsFullScreen) {
+        this.enterFullScreen();
+      } else {
+        this.exitFullScreen();
+      }
+    },
+
+    fullscreenOnWindowResize: function(event){ // Removeable
+      this.positionControlBars();
+    },
+    // Create listener for esc key while in full screen mode
+    fullscreenOnEscKey: function(event){ // Removeable
+      if (event.keyCode == 27) {
+        this.exitFullScreen();
+      }
+    }
+  }
+);
+/* Big Play Button Behaviors
+================================================================================ */
+VideoJS.player.newBehavior("bigPlayButton", function(element){
+    if (!this.elements.bigPlayButtons) {
+      this.elements.bigPlayButtons = [];
+      this.onPlay(this.bigPlayButtonsOnPlay);
+      this.onEnded(this.bigPlayButtonsOnEnded);
+    }
+    this.elements.bigPlayButtons.push(element);
+    this.activateElement(element, "playButton");
+  },{
+    bigPlayButtonsOnPlay: function(event){ this.hideBigPlayButtons(); },
+    bigPlayButtonsOnEnded: function(event){ this.showBigPlayButtons(); },
+    showBigPlayButtons: function(){
+      this.each(this.elements.bigPlayButtons, function(element){
+        element.style.display = "block";
+      });
+    },
+    hideBigPlayButtons: function(){
+      this.each(this.elements.bigPlayButtons, function(element){
+        element.style.display = "none";
+      });
+    }
+  }
+);
+/* Spinner
+================================================================================ */
+VideoJS.player.newBehavior("spinner", function(element){
+    if (!this.spinners) {
+      this.spinners = [];
+      _V_.addListener(this.video, "loadeddata", this.spinnersOnVideoLoadedData.context(this));
+      _V_.addListener(this.video, "loadstart", this.spinnersOnVideoLoadStart.context(this));
+      _V_.addListener(this.video, "seeking", this.spinnersOnVideoSeeking.context(this));
+      _V_.addListener(this.video, "seeked", this.spinnersOnVideoSeeked.context(this));
+      _V_.addListener(this.video, "canplay", this.spinnersOnVideoCanPlay.context(this));
+      _V_.addListener(this.video, "canplaythrough", this.spinnersOnVideoCanPlayThrough.context(this));
+      _V_.addListener(this.video, "waiting", this.spinnersOnVideoWaiting.context(this));
+      _V_.addListener(this.video, "stalled", this.spinnersOnVideoStalled.context(this));
+      _V_.addListener(this.video, "suspend", this.spinnersOnVideoSuspend.context(this));
+      _V_.addListener(this.video, "playing", this.spinnersOnVideoPlaying.context(this));
+      _V_.addListener(this.video, "timeupdate", this.spinnersOnVideoTimeUpdate.context(this));
+    }
+    this.spinners.push(element);
+  },{
+    showSpinners: function(){
+      this.each(this.spinners, function(spinner){
+        spinner.style.display = "block";
+      });
+      clearInterval(this.spinnerInterval);
+      this.spinnerInterval = setInterval(this.rotateSpinners.context(this), 100);
+    },
+    hideSpinners: function(){
+      this.each(this.spinners, function(spinner){
+        spinner.style.display = "none";
+      });
+      clearInterval(this.spinnerInterval);
+    },
+    spinnersRotated: 0,
+    rotateSpinners: function(){
+      this.each(this.spinners, function(spinner){
+        // spinner.style.transform =       'scale(0.5) rotate('+this.spinnersRotated+'deg)';
+        spinner.style.WebkitTransform = 'scale(0.5) rotate('+this.spinnersRotated+'deg)';
+        spinner.style.MozTransform =    'scale(0.5) rotate('+this.spinnersRotated+'deg)';
+      });
+      if (this.spinnersRotated == 360) { this.spinnersRotated = 0; }
+      this.spinnersRotated += 45;
+    },
+    spinnersOnVideoLoadedData: function(event){ this.hideSpinners(); },
+    spinnersOnVideoLoadStart: function(event){ this.showSpinners(); },
+    spinnersOnVideoSeeking: function(event){ /* this.showSpinners(); */ },
+    spinnersOnVideoSeeked: function(event){ /* this.hideSpinners(); */ },
+    spinnersOnVideoCanPlay: function(event){ /* this.hideSpinners(); */ },
+    spinnersOnVideoCanPlayThrough: function(event){ this.hideSpinners(); },
+    spinnersOnVideoWaiting: function(event){
+      // Safari sometimes triggers waiting inappropriately
+      // Like after video has played, any you play again.
+      this.showSpinners();
+    },
+    spinnersOnVideoStalled: function(event){},
+    spinnersOnVideoSuspend: function(event){},
+    spinnersOnVideoPlaying: function(event){ this.hideSpinners(); },
+    spinnersOnVideoTimeUpdate: function(event){
+      // Safari sometimes calls waiting and doesn't recover
+      if(this.spinner.style.display == "block") { this.hideSpinners(); }
+    }
+  }
+);
+/* Subtitles
+================================================================================ */
+VideoJS.player.newBehavior("subtitlesDisplay", function(element){
+    if (!this.subtitleDisplays) {
+      this.subtitleDisplays = [];
+      this.onCurrentTimeUpdate(this.subtitleDisplaysOnVideoTimeUpdate);
+      this.onEnded(function() { this.lastSubtitleIndex = 0; }.context(this));
+    }
+    this.subtitleDisplays.push(element);
+  },{
+    subtitleDisplaysOnVideoTimeUpdate: function(time){
+      // Assuming all subtitles are in order by time, and do not overlap
+      if (this.subtitles) {
+        // If current subtitle should stay showing, don't do anything. Otherwise, find new subtitle.
+        if (!this.currentSubtitle || this.currentSubtitle.start >= time || this.currentSubtitle.end < time) {
+          var newSubIndex = false,
+              // Loop in reverse if lastSubtitle is after current time (optimization)
+              // Meaning the user is scrubbing in reverse or rewinding
+              reverse = (this.subtitles[this.lastSubtitleIndex].start > time),
+              // If reverse, step back 1 becase we know it's not the lastSubtitle
+              i = this.lastSubtitleIndex - (reverse) ? 1 : 0;
+          while (true) { // Loop until broken
+            if (reverse) { // Looping in reverse
+              // Stop if no more, or this subtitle ends before the current time (no earlier subtitles should apply)
+              if (i < 0 || this.subtitles[i].end < time) { break; }
+              // End is greater than time, so if start is less, show this subtitle
+              if (this.subtitles[i].start < time) {
+                newSubIndex = i;
+                break;
+              }
+              i--;
+            } else { // Looping forward
+              // Stop if no more, or this subtitle starts after time (no later subtitles should apply)
+              if (i >= this.subtitles.length || this.subtitles[i].start > time) { break; }
+              // Start is less than time, so if end is later, show this subtitle
+              if (this.subtitles[i].end > time) {
+                newSubIndex = i;
+                break;
+              }
+              i++;
+            }
+          }
+
+          // Set or clear current subtitle
+          if (newSubIndex !== false) {
+            this.currentSubtitle = this.subtitles[newSubIndex];
+            this.lastSubtitleIndex = newSubIndex;
+            this.updateSubtitleDisplays(this.currentSubtitle.text);
+          } else if (this.currentSubtitle) {
+            this.currentSubtitle = false;
+            this.updateSubtitleDisplays("");
+          }
+        }
+      }
+    },
+    updateSubtitleDisplays: function(val){
+      this.each(this.subtitleDisplays, function(disp){
+        disp.innerHTML = val;
+      });
+    }
+  }
+);
+
+////////////////////////////////////////////////////////////////////////////////
+// Convenience Functions (mini library)
+// Functions not specific to video or VideoJS and could probably be replaced with a library like jQuery
+////////////////////////////////////////////////////////////////////////////////
+
+VideoJS.extend({
+
+  addClass: function(element, classToAdd){
+    if ((" "+element.className+" ").indexOf(" "+classToAdd+" ") == -1) {
+      element.className = element.className === "" ? classToAdd : element.className + " " + classToAdd;
+    }
+  },
+  removeClass: function(element, classToRemove){
+    if (element.className.indexOf(classToRemove) == -1) { return; }
+    var classNames = element.className.split(/\s+/);
+    classNames.splice(classNames.lastIndexOf(classToRemove),1);
+    element.className = classNames.join(" ");
+  },
+  createElement: function(tagName, attributes){
+    return this.merge(document.createElement(tagName), attributes);
+  },
+
+  // Attempt to block the ability to select text while dragging controls
+  blockTextSelection: function(){
+    document.body.focus();
+    document.onselectstart = function () { return false; };
+  },
+  // Turn off text selection blocking
+  unblockTextSelection: function(){ document.onselectstart = function () { return true; }; },
+
+  // Return seconds as MM:SS
+  formatTime: function(secs) {
+    var seconds = Math.round(secs);
+    var minutes = Math.floor(seconds / 60);
+    minutes = (minutes >= 10) ? minutes : "0" + minutes;
+    seconds = Math.floor(seconds % 60);
+    seconds = (seconds >= 10) ? seconds : "0" + seconds;
+    return minutes + ":" + seconds;
+  },
+
+  // Return the relative horizonal position of an event as a value from 0-1
+  getRelativePosition: function(x, relativeElement){
+    return Math.max(0, Math.min(1, (x - this.findPosX(relativeElement)) / relativeElement.offsetWidth));
+  },
+  // Get an objects position on the page
+  findPosX: function(obj) {
+    var curleft = obj.offsetLeft;
+    while(obj = obj.offsetParent) {
+      curleft += obj.offsetLeft;
+    }
+    return curleft;
+  },
+  getComputedStyleValue: function(element, style){
+    return window.getComputedStyle(element, null).getPropertyValue(style);
+  },
+
+  round: function(num, dec) {
+    if (!dec) { dec = 0; }
+    return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
+  },
+
+  addListener: function(element, type, handler){
+    if (element.addEventListener) {
+      element.addEventListener(type, handler, false);
+    } else if (element.attachEvent) {
+      element.attachEvent("on"+type, handler);
+    }
+  },
+  removeListener: function(element, type, handler){
+    if (element.removeEventListener) {
+      element.removeEventListener(type, handler, false);
+    } else if (element.attachEvent) {
+      element.detachEvent("on"+type, handler);
+    }
+  },
+
+  get: function(url, onSuccess){
+    if (typeof XMLHttpRequest == "undefined") {
+      XMLHttpRequest = function () {
+        try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {}
+        try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (f) {}
+        try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (g) {}
+        //Microsoft.XMLHTTP points to Msxml2.XMLHTTP.3.0 and is redundant
+        throw new Error("This browser does not support XMLHttpRequest.");
+      };
+    }
+    var request = new XMLHttpRequest();
+    request.open("GET",url);
+    request.onreadystatechange = function() {
+      if (request.readyState == 4 && request.status == 200) {
+        onSuccess(request.responseText);
+      }
+    }.context(this);
+    request.send();
+  },
+
+  trim: function(string){ return string.toString().replace(/^\s+/, "").replace(/\s+$/, ""); },
+
+  // DOM Ready functionality adapted from jQuery. http://jquery.com/
+  bindDOMReady: function(){
+    if (document.readyState === "complete") {
+      return VideoJS.onDOMReady();
+    }
+    if (document.addEventListener) {
+      document.addEventListener("DOMContentLoaded", VideoJS.DOMContentLoaded, false);
+      window.addEventListener("load", VideoJS.onDOMReady, false);
+    } else if (document.attachEvent) {
+      document.attachEvent("onreadystatechange", VideoJS.DOMContentLoaded);
+      window.attachEvent("onload", VideoJS.onDOMReady);
+    }
+  },
+
+  DOMContentLoaded: function(){
+    if (document.addEventListener) {
+      document.removeEventListener( "DOMContentLoaded", VideoJS.DOMContentLoaded, false);
+      VideoJS.onDOMReady();
+    } else if ( document.attachEvent ) {
+      if ( document.readyState === "complete" ) {
+        document.detachEvent("onreadystatechange", VideoJS.DOMContentLoaded);
+        VideoJS.onDOMReady();
+      }
+    }
+  },
+
+  // Functions to be run once the DOM is loaded
+  DOMReadyList: [],
+  addToDOMReady: function(fn){
+    if (VideoJS.DOMIsReady) {
+      fn.call(document);
+    } else {
+      VideoJS.DOMReadyList.push(fn);
+    }
+  },
+
+  DOMIsReady: false,
+  onDOMReady: function(){
+    if (VideoJS.DOMIsReady) { return; }
+    if (!document.body) { return setTimeout(VideoJS.onDOMReady, 13); }
+    VideoJS.DOMIsReady = true;
+    if (VideoJS.DOMReadyList) {
+      for (var i=0; i<VideoJS.DOMReadyList.length; i++) {
+        VideoJS.DOMReadyList[i].call(document);
+      }
+      VideoJS.DOMReadyList = null;
+    }
+  }
+});
+VideoJS.bindDOMReady();
+
+// Allows for binding context to functions
+// when using in event listeners and timeouts
+Function.prototype.context = function(obj){
+  var method = this,
+  temp = function(){
+    return method.apply(obj, arguments);
+  };
+  return temp;
+};
+
+// Like context, in that it creates a closure
+// But insteaad keep "this" intact, and passes the var as the second argument of the function
+// Need for event listeners where you need to know what called the event
+// Only use with event callbacks
+Function.prototype.evtContext = function(obj){
+  var method = this,
+  temp = function(){
+    var origContext = this;
+    return method.call(obj, arguments[0], origContext);
+  };
+  return temp;
+};
+
+// Removeable Event listener with Context
+// Replaces the original function with a version that has context
+// So it can be removed using the original function name.
+// In order to work, a version of the function must already exist in the player/prototype
+Function.prototype.rEvtContext = function(obj, funcParent){
+  if (this.hasContext === true) { return this; }
+  if (!funcParent) { funcParent = obj; }
+  for (var attrname in funcParent) {
+    if (funcParent[attrname] == this) {
+      funcParent[attrname] = this.evtContext(obj);
+      funcParent[attrname].hasContext = true;
+      return funcParent[attrname];
+    }
+  }
+  return this.evtContext(obj);
+};
+
+// jQuery Plugin
+if (window.jQuery) {
+  (function($) {
+    $.fn.VideoJS = function(options) {
+      this.each(function() {
+        VideoJS.setup(this, options);
+      });
+      return this;
+    };
+    $.fn.player = function() {
+      return this[0].player;
+    };
+  })(jQuery);
+}
+
+
+// Expose to global
+window.VideoJS = window._V_ = VideoJS;
+
+// End self-executing function
+})(window);
\ No newline at end of file