Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -89,16 +89,6 @@ 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) @@ -111,9 +101,6 @@ set(GPU_CODEGEN TRUE) endif(POLLY_ENABLE_GPGPU_CODEGEN) -if (CLOOG_FOUND) - INCLUDE_DIRECTORIES( ${CLOOG_INCLUDE_DIR} ) -endif(CLOOG_FOUND) if (PLUTO_FOUND) INCLUDE_DIRECTORIES( ${PLUTO_INCLUDE_DIR} ) endif(PLUTO_FOUND) Index: Makefile.config.in =================================================================== --- Makefile.config.in +++ Makefile.config.in @@ -29,13 +29,12 @@ POLLY_CXXFLAGS += "-fno-rtti -fno-exceptions" PLUTO_FOUND := @pluto_found@ -CLOOG_FOUND := @cloog_found@ CUDALIB_FOUND := @cuda_found@ # Set include directroys -POLLY_INC := @gmp_inc@ @isl_inc@ @cloog_inc@ @cuda_inc@\ +POLLY_INC := @gmp_inc@ @isl_inc@ @cuda_inc@\ @pluto_inc@ -I$(POLLY_SRC_ROOT)/lib/JSON/include -POLLY_LD := @gmp_ld@ @isl_ld@ @cloog_ld@ @cuda_ld@ @pluto_ld@ +POLLY_LD := @gmp_ld@ @isl_ld@ @cuda_ld@ @pluto_ld@ -POLLY_LIB := @gmp_lib@ @isl_lib@ @cloog_lib@ @cuda_lib@ @pluto_lib@ +POLLY_LIB := @gmp_lib@ @isl_lib@ @cuda_lib@ @pluto_lib@ Index: autoconf/configure.ac =================================================================== --- autoconf/configure.ac +++ autoconf/configure.ac @@ -37,8 +37,6 @@ fi fi -AC_DEFINE([CLOOG_INT_GMP], [1], [Use gmp for isl]) - dnl ************************************************************************** dnl * Determine which system we are building on dnl ************************************************************************** @@ -83,14 +81,6 @@ 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" Index: cmake/FindCloog.cmake =================================================================== --- cmake/FindCloog.cmake +++ /dev/null @@ -1,19 +0,0 @@ -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) - Index: configure =================================================================== --- configure +++ configure @@ -595,10 +595,6 @@ pluto_lib pluto_inc pluto_found -cloog_ld -cloog_lib -cloog_inc -cloog_found isl_ld isl_lib isl_inc @@ -661,7 +657,6 @@ with_llvmobj with_gmp with_isl -with_cloog with_pluto enable_polly_gpu_codegen with_cuda @@ -1294,7 +1289,6 @@ --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-cuda prefix of cuda @@ -1897,7 +1891,6 @@ fi -$as_echo "#define CLOOG_INT_GMP 1" >>confdefs.h @@ -2578,96 +2571,6 @@ 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 -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 @@ -2755,17 +2658,6 @@ 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; - # Check whether --enable-polly_gpu_codegen was given. if test "${enable_polly_gpu_codegen+set}" = set; then : enableval=$enable_polly_gpu_codegen; Index: include/polly/CodeGen/Cloog.h =================================================================== --- include/polly/CodeGen/Cloog.h +++ /dev/null @@ -1,91 +0,0 @@ -//===- 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 */ Index: include/polly/CodeGen/CodeGeneration.h =================================================================== --- include/polly/CodeGen/CodeGeneration.h +++ include/polly/CodeGen/CodeGeneration.h @@ -27,13 +27,7 @@ }; extern VectorizerChoice PollyVectorizerChoice; -enum CodeGenChoice { -#ifdef CLOOG_FOUND - CODEGEN_CLOOG, -#endif - CODEGEN_ISL, - CODEGEN_NONE -}; +enum CodeGenChoice { CODEGEN_ISL, CODEGEN_NONE }; extern CodeGenChoice PollyCodeGenChoice; /// @brief Flag to turn on/off annotation of alias scopes. Index: include/polly/Config/config.h.in =================================================================== --- include/polly/Config/config.h.in +++ include/polly/Config/config.h.in @@ -1,11 +1,5 @@ /* 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 Index: include/polly/LinkAllPasses.h =================================================================== --- include/polly/LinkAllPasses.h +++ include/polly/LinkAllPasses.h @@ -26,11 +26,6 @@ } namespace polly { -#ifdef CLOOG_FOUND -llvm::Pass *createCloogExporterPass(); -llvm::Pass *createCloogInfoPass(); -llvm::Pass *createCodeGenerationPass(); -#endif llvm::Pass *createCodePreparationPass(); llvm::Pass *createDeadCodeElimPass(); llvm::Pass *createDependencesPass(); @@ -67,11 +62,6 @@ if (std::getenv("bar") != (char *)-1) return; -#ifdef CLOOG_FOUND - polly::createCloogExporterPass(); - polly::createCloogInfoPass(); - polly::createCodeGenerationPass(); -#endif polly::createCodePreparationPass(); polly::createDeadCodeElimPass(); polly::createDependencesPass(); @@ -99,9 +89,6 @@ namespace llvm { class PassRegistry; -#ifdef CLOOG_FOUND -void initializeCodeGenerationPass(llvm::PassRegistry &); -#endif void initializeCodePreparationPass(llvm::PassRegistry &); void initializeDeadCodeElimPass(llvm::PassRegistry &); void initializeIndependentBlocksPass(llvm::PassRegistry &); Index: lib/Analysis/ScopDetection.cpp =================================================================== --- lib/Analysis/ScopDetection.cpp +++ lib/Analysis/ScopDetection.cpp @@ -207,14 +207,6 @@ "accesses are enabled.\n"); PollyUseRuntimeAliasChecks = false; } - -#ifdef CLOOG_FOUND - if (PollyCodeGenChoice == CODEGEN_CLOOG) { - DEBUG(errs() << "WARNING: We disable runtime alias checks as the cloog " - "code generation cannot emit them.\n"); - PollyUseRuntimeAliasChecks = false; - } -#endif } template Index: lib/CMakeLists.txt =================================================================== --- lib/CMakeLists.txt +++ lib/CMakeLists.txt @@ -10,12 +10,6 @@ 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/IslExprBuilder.cpp @@ -35,7 +29,6 @@ Analysis/ScopPass.cpp Analysis/TempScopInfo.cpp CodeGen/BlockGenerators.cpp - ${CLOOG_FILES} ${ISL_CODEGEN_FILES} CodeGen/LoopGenerators.cpp CodeGen/IRBuilder.cpp Index: lib/CodeGen/Cloog.cpp =================================================================== --- lib/CodeGen/Cloog.cpp +++ /dev/null @@ -1,365 +0,0 @@ -//===- 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 - -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(); - - std::string FunctionName = R.getEntry()->getParent()->getName(); - std::string Filename = getFileName(&R); - - errs() << "Writing Scop '" << R.getNameStr() << "' in function '" - << FunctionName << "' to '" << Filename << "'...\n"; - - FILE *F = fopen(Filename.c_str(), "w"); - C.dump(F); - fclose(F); - - return false; -} - -void CloogExporter::getAnalysisUsage(AnalysisUsage &AU) const { - // Get the Common analysis usage of ScopPasses. - ScopPass::getAnalysisUsage(AU); - AU.addRequired(); -} - -static RegisterPass A("polly-export-cloog", - "Polly - Export the Cloog input file" - " (Writes a .cloog file for each Scop)"); - -llvm::Pass *polly::createCloogExporterPass() { return new CloogExporter(); } - -/// Write a .cloog input file -void CloogInfo::dump(FILE *F) { C->dump(F); } - -/// Print a source code representation of the program. -void CloogInfo::pprint(llvm::raw_ostream &OS) { C->pprint(OS); } - -/// Create the Cloog AST from this program. -const struct clast_root *CloogInfo::getClast() { return C->getClast(); } - -void CloogInfo::releaseMemory() { - if (C) { - delete C; - C = 0; - } -} - -bool CloogInfo::runOnScop(Scop &S) { - if (C) - delete C; - - scop = &S; - - C = new Cloog(&S); - - Function *F = S.getRegion().getEntry()->getParent(); - (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 Index: lib/CodeGen/CodeGeneration.cpp =================================================================== --- lib/CodeGen/CodeGeneration.cpp +++ /dev/null @@ -1,1117 +0,0 @@ -//===------ 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 -#include - -using namespace polly; -using namespace llvm; - -#define DEBUG_TYPE "polly-codegen" - -struct isl_set; - -namespace polly { -static cl::opt - 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 - 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 - GPUTriple("polly-gpgpu-triple", - cl::desc("Target triple for GPU code generation"), cl::Hidden, - cl::init(""), cl::cat(PollyCategory)); -#endif /* GPU_CODEGEN */ - -typedef DenseMap 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 &getParallelLoops(); - -private: - // The Scop we code generate. - Scop *S; - Pass *P; - LoopInfo &LI; - ScalarEvolution &SE; - DominatorTree &DT; - const DataLayout &DL; - - // 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 parallelLoops; - - void codegen(const clast_assignment *a); - - void codegen(const clast_assignment *a, ScopStmt *Statement, - unsigned Dimension, int vectorDim, - std::vector *VectorVMap = 0, - std::vector *VLTS = 0); - - void codegenSubstitutions(const clast_stmt *Assignment, ScopStmt *Statement, - int vectorDim = 0, - std::vector *VectorVMap = 0, - std::vector *VLTS = 0); - - void codegen(const clast_user_stmt *u, std::vector *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 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(ParallelLoopGenerator::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 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 &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().getDataLayout().getIntPtrType( - Builder.getContext()); -} - -const std::vector &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 *VectorVMap, - std::vector *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 *VectorVMap, - std::vector *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 *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, LI, - SE); - isl_set_free(Domain); - return; - } - - VectorValueMapT VectorMap(VectorDimensions); - std::vector VLTS(VectorDimensions); - - if (IVS) { - assert(u->substitutions && "Substitutions expected!"); - int i = 0; - for (Value *IV : *IVS) { - ClastVars[iterator] = IV; - 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 (const 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, LI, SE); - 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, LI, DT, 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 Values; - -public: - ParameterVisitor() : ClastVisitor(), Values() {} - - void visitUser(const clast_user_stmt *Stmt) { - const ScopStmt *S = static_cast(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(SrcVal)) - if (S->getParent()->getRegion().contains(OpInst)) - continue; - - if (isa(SrcVal) || isa(SrcVal)) - Values.insert(SrcVal); - } - } - } - - // Iterator to iterate over the values found. - typedef std::set::const_iterator const_iterator; - inline const_iterator begin() const { return Values.begin(); } - inline const_iterator end() const { return Values.end(); } -}; - -SetVector ClastStmtCodeGen::getOMPValues(const clast_stmt *Body) { - SetVector Values; - - // The clast variables - for (const auto &I : ClastVars) - 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 (Value *V : Params) { - Values.insert(V); - DEBUG(dbgs() << "Adding temporary for OMP copy-in: " << *V << "\n"); - } - - return Values; -} - -void ClastStmtCodeGen::updateWithValueMap( - ParallelLoopGenerator::ValueToValueMapTy &VMap) { - std::set Inserted; - - for (const auto &I : ClastVars) { - ClastVars[I.first] = VMap[I.second]; - Inserted.insert(I.second); - } - - for (const auto &I : VMap) { - 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 Nodes; - for (po_iterator I = po_begin(N), E = po_end(N); I != E; ++I) - Nodes.push_back(I->getBlock()); - - for (BasicBlock *BB : Nodes) - DT.eraseNode(BB); -} - -void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) { - Value *Stride, *LB, *UB, *IV; - BasicBlock::iterator LoopBody; - IntegerType *IntPtrTy = getIntPtrTy(); - SetVector Values; - ParallelLoopGenerator::ValueToValueMapTy VMap; - ParallelLoopGenerator OMPGen(Builder, P, LI, DT, DL); - - 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().getDomTree()); - - Builder.SetInsertPoint(AfterLoop); -} - -#ifdef GPU_CODEGEN -static unsigned getArraySizeInBytes(const ArrayType *AT) { - unsigned Bytes = AT->getNumElements(); - if (const ArrayType *T = dyn_cast(AT->getElementType())) - Bytes *= getArraySizeInBytes(T); - else - Bytes *= AT->getElementType()->getPrimitiveSizeInBits() / 8; - - return Bytes; -} - -SetVector ClastStmtCodeGen::getGPUValues(unsigned &OutputBytes) { - SetVector Values; - OutputBytes = 0; - - // Record the memory reference base addresses. - for (ScopStmt *Stmt : *S) { - for (MemoryAccess *MA : *Stmt) { - Value *BaseAddr = 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(BaseAddr->getType())) { - Type *T = PT->getArrayElementType(); - const ArrayType *ATy = dyn_cast(T); - OutputBytes = getArraySizeInBytes(ATy); - } - } - } - } - - return Values; -} - -const clast_stmt *ClastStmtCodeGen::getScheduleInfo(const clast_for *F, - std::vector &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 Values; - SetVector IVS; - std::vector 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(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 = nullptr; - 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, LI, DT, AfterBB, - CmpInst::ICMP_SLE); - const Value *OldIV_ = Statement->getInductionVariableForDimension(2); - Value *OldIV = const_cast(OldIV_); - VMap.insert(std::make_pair(OldIV, IV)); - } - - updateWithValueMap(VMap); - - BlockGenerator::generate(Builder, *Statement, ValueMap, LoopToScev, P, LI, - SE); - - 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 (Value *BaseAddr : Values) - for (BasicBlock *BB : *FN) - for (Instruction *Inst : *BB) - Inst->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(LB->getType()); - Stride = Stride.zext(LoopIVType->getBitWidth()); - Value *StrideValue = ConstantInt::get(LoopIVType, Stride); - - std::vector IVS(VectorWidth); - IVS[0] = LB; - - for (int i = 1; i < VectorWidth; i++) - IVS[i] = Builder.CreateAdd(IVS[i - 1], StrideValue, "p_vector_iv"); - - isl_set *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); -} - -static isl_union_map *getCombinedScheduleForSpace(Scop *S, unsigned dimLevel) { - isl_space *Space = S->getParamSpace(); - isl_union_map *schedule = isl_union_map_empty(Space); - - for (ScopStmt *Stmt : *S) { - 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 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(); - isl_union_map *Deps = - D.getDependences(Dependences::TYPE_RAW | Dependences::TYPE_WAW | - Dependences::TYPE_WAR | Dependences::TYPE_RAW); - isl_union_map *Schedule = - getCombinedScheduleForSpace(S, isl_set_n_dim(Domain)); - Schedule = - isl_union_map_intersect_range(Schedule, isl_union_set_from_set(Domain)); - bool IsParallel = D.isParallel(Schedule, Deps); - isl_union_map_free(Schedule); - return IsParallel; -} - -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().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(); - 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(), "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), LI(P->getAnalysis()), - SE(P->getAnalysis()), - DT(P->getAnalysis().getDomTree()), - DL(P->getAnalysis().getDataLayout()), Builder(B), - ExpGen(Builder, ClastVars) {} - -namespace { -class CodeGeneration : public ScopPass { - std::vector 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); - - Value *RTC = ConstantInt::getTrue(S.getSE()->getContext()); - BasicBlock *StartBlock = executeScopConditionally(S, this, RTC); - - PollyIRBuilder Builder(StartBlock->begin()); - - ClastStmtCodeGen CodeGen(&S, Builder, this); - CloogInfo &C = getAnalysis(); - CodeGen.codegen(C.getClast()); - - ParallelLoops.insert(ParallelLoops.begin(), - CodeGen.getParallelLoops().begin(), - CodeGen.getParallelLoops().end()); - return true; - } - - virtual void printScop(raw_ostream &OS) const { - for (const auto &PI : ParallelLoops) - OS << "Parallel loop with iterator '" << PI << "' generated\n"; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - - // FIXME: We do not yet add regions for the newly generated code to the - // region tree. - AU.addPreserved(); - AU.addPreserved(); - AU.addPreserved(); - AU.addPreservedID(IndependentBlocksID); - } -}; -} - -char CodeGeneration::ID = 1; - -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(DataLayoutPass); -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 Index: lib/Makefile =================================================================== --- lib/Makefile +++ lib/Makefile @@ -18,11 +18,6 @@ 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 @@ -65,7 +60,6 @@ Transform/ScheduleOptimizer.cpp \ ${GPGPU_FILES} \ ${ISL_CODEGEN_FILES} \ - ${CLOOG_FILES} \ ${POLLY_JSON_FILES} \ ${POLLY_PLUTO_FILES} Index: lib/Support/RegisterPasses.cpp =================================================================== --- lib/Support/RegisterPasses.cpp +++ lib/Support/RegisterPasses.cpp @@ -22,7 +22,6 @@ #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" @@ -69,12 +68,9 @@ CodeGenChoice polly::PollyCodeGenChoice; static cl::opt XCodeGenerator( "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::values(clEnumValN(CODEGEN_ISL, "isl", "isl code generator"), + clEnumValN(CODEGEN_NONE, "none", "no code generation"), + clEnumValEnd), cl::Hidden, cl::location(PollyCodeGenChoice), cl::init(CODEGEN_ISL), cl::ZeroOrMore, cl::cat(PollyCategory)); @@ -144,10 +140,6 @@ namespace polly { void initializePollyPasses(PassRegistry &Registry) { -#ifdef CLOOG_FOUND - initializeCloogInfoPass(Registry); - initializeCodeGenerationPass(Registry); -#endif initializeIslCodeGenerationPass(Registry); initializeCodePreparationPass(Registry); initializeDeadCodeElimPass(Registry); @@ -191,9 +183,7 @@ /// 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. +/// Polly supports the isl internal code generator. static void registerPollyPasses(llvm::PassManagerBase &PM) { registerCanonicalicationPasses(PM, SCEVCodegen); @@ -233,16 +223,6 @@ PM.add(polly::createJSONExporterPass()); switch (PollyCodeGenChoice) { -#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; Index: lib/Transform/IndependentBlocks.cpp =================================================================== --- lib/Transform/IndependentBlocks.cpp +++ lib/Transform/IndependentBlocks.cpp @@ -14,7 +14,6 @@ #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" @@ -505,9 +504,6 @@ AU.addPreserved(); AU.addRequired(); AU.addPreserved(); -#ifdef CLOOG_FOUND - AU.addPreserved(); -#endif } bool IndependentBlocks::runOnFunction(llvm::Function &F) { Index: test/Cloog/CodeGen/20100617.ll =================================================================== --- test/Cloog/CodeGen/20100617.ll +++ /dev/null @@ -1,19 +0,0 @@ -; RUN: opt %loadPolly -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 ] ; [#uses=1] - br i1 false, label %for.cond1, label %for.end32 - -for.cond1: ; preds = %for.cond - %indvar.next2 = add i64 %indvar1, 1 ; [#uses=1] - br label %for.cond - -for.end32: ; preds = %for.cond - ret void -} Index: test/Cloog/CodeGen/20100622.ll =================================================================== --- test/Cloog/CodeGen/20100622.ll +++ /dev/null @@ -1,43 +0,0 @@ -; RUN: opt %loadPolly -polly-codegen < %s -; RUN: opt %loadPolly -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 ] ; [#uses=1] - %indvar.next48 = add i32 %indvar47, 1 ; [#uses=2] - %exitcond50 = icmp eq i32 %indvar.next48, undef ; [#uses=1] - br i1 %exitcond50, label %bb31, label %bb29 - -bb31: ; preds = %bb29, %bb26.loopexit - %errtot.3 = phi float [ undef, %bb26.loopexit ], [ undef, %bb29 ] ; [#uses=0] - ret void -} - -; CHECK: SCOP: Index: test/Cloog/CodeGen/20100707.ll =================================================================== --- test/Cloog/CodeGen/20100707.ll +++ /dev/null @@ -1,27 +0,0 @@ -; RUN: opt %loadPolly -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 ; [#uses=1] - br label %bb8 - -bb7: ; preds = %bb8 - %indvar.next = add i64 %indvar, 1 ; [#uses=1] - br label %bb8 - -bb8: ; preds = %bb7, %bb6 - %indvar = phi i64 [ %indvar.next, %bb7 ], [ 0, %bb6 ] ; [#uses=2] - %exitcond = icmp ne i64 %indvar, %tmp ; [#uses=1] - br i1 %exitcond, label %bb7, label %return - -return: ; preds = %bb8 - ret void -} Index: test/Cloog/CodeGen/20100707_2.ll =================================================================== --- test/Cloog/CodeGen/20100707_2.ll +++ /dev/null @@ -1,115 +0,0 @@ -; RUN: opt %loadPolly -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 ; [#uses=0] - %1 = getelementptr inbounds [18 x [32 x double]]* undef, i64 0, i64 0 ; <[32 x double]*> [#uses=1] - %2 = getelementptr inbounds [32 x double]* %1, i64 0, i64 0 ; [#uses=0] - %3 = getelementptr inbounds [36 x double]* undef, i64 0, i64 0 ; [#uses=0] - %4 = sub nsw i32 17, %k.4 ; [#uses=1] - %5 = getelementptr inbounds [2 x [2 x [18 x [32 x double]]]]* @sb_sample, i64 0, i64 0 ; <[2 x [18 x [32 x double]]]*> [#uses=1] - %6 = getelementptr inbounds [2 x [18 x [32 x double]]]* %5, i64 0, i64 0 ; <[18 x [32 x double]]*> [#uses=1] - %7 = sext i32 %4 to i64 ; [#uses=1] - %8 = getelementptr inbounds [18 x [32 x double]]* %6, i64 0, i64 %7 ; <[32 x double]*> [#uses=1] - %9 = getelementptr inbounds [32 x double]* %8, i64 0, i64 0 ; [#uses=1] - %10 = load double* %9, align 8 ; [#uses=0] - %11 = fsub double 0.000000e+00, undef ; [#uses=1] - %12 = getelementptr inbounds double* getelementptr inbounds ([4 x [36 x double]]* @win193, i64 0, i64 2, i64 4), i64 0 ; [#uses=1] - store double %11, double* %12, align 8 - %13 = add nsw i32 %k.4, 9 ; [#uses=1] - %14 = add nsw i32 %k.4, 18 ; [#uses=1] - %15 = getelementptr inbounds [4 x [36 x double]]* @win193, i64 0, i64 0 ; <[36 x double]*> [#uses=1] - %16 = sext i32 %14 to i64 ; [#uses=1] - %17 = getelementptr inbounds [36 x double]* %15, i64 0, i64 %16 ; [#uses=1] - %18 = load double* %17, align 8 ; [#uses=0] - %19 = sext i32 %k.4 to i64 ; [#uses=1] - %20 = getelementptr inbounds [18 x [32 x double]]* undef, i64 0, i64 %19 ; <[32 x double]*> [#uses=1] - %21 = sext i32 %band.2 to i64 ; [#uses=1] - %22 = getelementptr inbounds [32 x double]* %20, i64 0, i64 %21 ; [#uses=1] - %23 = load double* %22, align 8 ; [#uses=0] - %24 = sext i32 %39 to i64 ; [#uses=1] - %25 = getelementptr inbounds [4 x [36 x double]]* @win193, i64 0, i64 %24 ; <[36 x double]*> [#uses=1] - %26 = getelementptr inbounds [36 x double]* %25, i64 0, i64 0 ; [#uses=1] - %27 = load double* %26, align 8 ; [#uses=0] - %28 = sub nsw i32 17, %k.4 ; [#uses=1] - %29 = getelementptr inbounds [2 x [2 x [18 x [32 x double]]]]* @sb_sample, i64 0, i64 0 ; <[2 x [18 x [32 x double]]]*> [#uses=1] - %30 = getelementptr inbounds [2 x [18 x [32 x double]]]* %29, i64 0, i64 0 ; <[18 x [32 x double]]*> [#uses=1] - %31 = sext i32 %28 to i64 ; [#uses=1] - %32 = getelementptr inbounds [18 x [32 x double]]* %30, i64 0, i64 %31 ; <[32 x double]*> [#uses=1] - %33 = getelementptr inbounds [32 x double]* %32, i64 0, i64 0 ; [#uses=1] - %34 = load double* %33, align 8 ; [#uses=0] - %35 = sext i32 %13 to i64 ; [#uses=1] - %36 = getelementptr inbounds double* getelementptr inbounds ([4 x [36 x double]]* @win193, i64 0, i64 2, i64 4), i64 %35 ; [#uses=1] - store double 0.000000e+00, double* %36, align 8 - %37 = sub nsw i32 %k.4, 1 ; [#uses=1] - br label %bb35 - -bb35: ; preds = %bb34, %bb27 - %k.4 = phi i32 [ %37, %bb34 ], [ 8, %bb27 ] ; [#uses=6] - br i1 undef, label %bb34, label %bb36 - -bb36: ; preds = %bb35 - unreachable - -bb37: ; preds = %bb32, %bb26 - %38 = add nsw i32 %band.2, 1 ; [#uses=1] - br label %bb48 - -bb48: ; preds = %bb37, %bb9 - %band.2 = phi i32 [ %38, %bb37 ], [ 0, %bb9 ] ; [#uses=2] - %39 = load i32* null, align 8 ; [#uses=1] - br i1 undef, label %bb26, label %bb25 - -bb50: ; preds = %bb54 - br i1 undef, label %bb3, label %bb51 - -bb51: ; preds = %bb50 - br i1 undef, label %bb52, label %bb53 - -bb52: ; preds = %bb51 - unreachable - -bb53: ; preds = %bb51 - br label %bb54 - -bb54: ; preds = %bb53, %bb, %entry - br i1 undef, label %bb50, label %return - -return: ; preds = %bb54 - ret void -} Index: test/Cloog/CodeGen/20100708_2.ll =================================================================== --- test/Cloog/CodeGen/20100708_2.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: opt %loadPolly -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 ] ; [#uses=1] - %tmp3 = trunc i64 undef to i32 ; [#uses=1] - br i1 false, label %bb3, label %bb4 - -bb3: ; preds = %bb2 - %tmp = srem i32 %tmp3, 1024 ; [#uses=0] - store double undef, double* undef - %indvar.next = add i64 %indvar, 1 ; [#uses=1] - br label %bb2 - -bb4: ; preds = %bb2 - br label %bb1 - -bb5: ; preds = %bb1 - ret void -} Index: test/Cloog/CodeGen/20100713.ll =================================================================== --- test/Cloog/CodeGen/20100713.ll +++ /dev/null @@ -1,34 +0,0 @@ -; RUN: opt %loadPolly -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 ; [#uses=1] - br label %bb21 - -bb20: ; preds = %bb21 - %1 = load float* undef, align 4 ; [#uses=0] - %2 = fpext float undef to double ; [#uses=1] - %3 = fdiv double %2, %a ; [#uses=0] - %indvar.next = add i64 %indvar, 1 ; [#uses=1] - br label %bb21 - -bb21: ; preds = %bb20, %bb19 - %indvar = phi i64 [ %indvar.next, %bb20 ], [ 0, %bb19 ] ; [#uses=1] - br i1 false, label %bb20, label %bb22.loopexit - -bb22.loopexit: ; preds = %bb21 - br label %bb22 - -bb22: ; preds = %bb22.loopexit, %bb18 - br label %return - -return: ; preds = %bb22 - ret void -} Index: test/Cloog/CodeGen/20100713_2.ll =================================================================== --- test/Cloog/CodeGen/20100713_2.ll +++ /dev/null @@ -1,34 +0,0 @@ -; RUN: opt %loadPolly -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 ; [#uses=1] - br i1 false, label %bb2, label %bb3 - -bb2: ; preds = %bb1 - br label %bb4 - -bb3: ; preds = %bb1 - br label %bb4 - -bb4: ; preds = %bb3, %bb2 - br i1 undef, label %bb5, label %bb6 - -bb5: ; preds = %bb4 - unreachable - -bb6: ; preds = %bb4 - %1 = getelementptr inbounds i8* undef, i64 %0 ; [#uses=0] - ret void - -return: ; preds = %bb, %entry - ret void -} Index: test/Cloog/CodeGen/20100717.ll =================================================================== --- test/Cloog/CodeGen/20100717.ll +++ /dev/null @@ -1,39 +0,0 @@ -; RUN: opt %loadPolly -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 ; [#uses=1] - br label %bb2 - -bb1: ; preds = %bb2 - %1 = getelementptr inbounds double** %A, i64 0 ; [#uses=0] - %2 = getelementptr inbounds double** %A, i64 0 ; [#uses=0] - %3 = getelementptr inbounds double** %A, i64 0 ; [#uses=0] - %4 = sext i32 %j.0 to i64 ; [#uses=1] - %5 = getelementptr inbounds double** %A, i64 %4 ; [#uses=1] - %6 = load double** %5, align 8 ; [#uses=0] - %7 = add nsw i32 %j.0, 1 ; [#uses=1] - br label %bb2 - -bb2: ; preds = %bb1, %bb - %j.0 = phi i32 [ %0, %bb ], [ %7, %bb1 ] ; [#uses=3] - %8 = icmp sle i32 %j.0, 50 ; [#uses=1] - br i1 %8, label %bb1, label %bb3 - -bb3: ; preds = %bb2 - %9 = add nsw i32 %i.0, 1 ; [#uses=1] - br label %bb4 - -bb4: ; preds = %bb3, %entry - %i.0 = phi i32 [ 0, %entry ], [ %9, %bb3 ] ; [#uses=3] - %10 = icmp sle i32 %i.0, 50 ; [#uses=1] - br i1 %10, label %bb, label %return - -return: ; preds = %bb4 - ret void -} Index: test/Cloog/CodeGen/20100718-DomInfo-2.ll =================================================================== --- test/Cloog/CodeGen/20100718-DomInfo-2.ll +++ /dev/null @@ -1,35 +0,0 @@ -; RUN: opt %loadPolly -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 -} Index: test/Cloog/CodeGen/20100718-DomInfo.ll =================================================================== --- test/Cloog/CodeGen/20100718-DomInfo.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: opt %loadPolly -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 ; [#uses=1] - br label %bb25 - -bb25: ; preds = %bb23, %entry - %indvar94 = phi i64 [ %indvar.next95, %bb23 ], [ 0, %entry ] ; [#uses=1] - br i1 false, label %bb23, label %return - -bb26: ; preds = %entry - ret void - -bb81: ; preds = %entry - ret void - -return: ; preds = %bb25 - ret void -} Index: test/Cloog/CodeGen/20100720-MultipleConditions.ll =================================================================== --- test/Cloog/CodeGen/20100720-MultipleConditions.ll +++ /dev/null @@ -1,97 +0,0 @@ -; RUN: opt %loadPolly -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 ; [#uses=0] - -define i32 @main() nounwind { -;