Index: polly/trunk/include/polly/LinkAllPasses.h =================================================================== --- polly/trunk/include/polly/LinkAllPasses.h +++ polly/trunk/include/polly/LinkAllPasses.h @@ -42,6 +42,7 @@ llvm::Pass *createScopInfoWrapperPassPass(); llvm::Pass *createIslAstInfoPass(); llvm::Pass *createCodeGenerationPass(); +llvm::Pass *createPPCGCodeGenerationPass(); llvm::Pass *createIslScheduleOptimizerPass(); extern char &CodePreparationID; @@ -71,6 +72,7 @@ polly::createPollyCanonicalizePass(); polly::createIslAstInfoPass(); polly::createCodeGenerationPass(); + polly::createPPCGCodeGenerationPass(); polly::createIslScheduleOptimizerPass(); } } PollyForcePassLinking; // Force link by creating a global definition. @@ -84,6 +86,7 @@ void initializeJSONImporterPass(llvm::PassRegistry &); void initializeIslAstInfoPass(llvm::PassRegistry &); void initializeCodeGenerationPass(llvm::PassRegistry &); +void initializePPCGCodeGenerationPass(llvm::PassRegistry &); void initializeIslScheduleOptimizerPass(llvm::PassRegistry &); void initializePollyCanonicalizePass(llvm::PassRegistry &); } // namespace llvm Index: polly/trunk/lib/CMakeLists.txt =================================================================== --- polly/trunk/lib/CMakeLists.txt +++ polly/trunk/lib/CMakeLists.txt @@ -13,7 +13,9 @@ CodeGen/CodeGeneration.cpp) if (GPU_CODEGEN) - set (GPGPU_CODEGEN_FILES) + set (GPGPU_CODEGEN_FILES + CodeGen/PPCGCodeGeneration.cpp + ) endif (GPU_CODEGEN) # Compile ISL into a separate library. Index: polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp =================================================================== --- polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp +++ polly/trunk/lib/CodeGen/PPCGCodeGeneration.cpp @@ -0,0 +1,82 @@ +//===------ PPCGCodeGeneration.cpp - Polly Accelerator Code Generation. ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Take a scop created by ScopInfo and map it to GPU code using the ppcg +// GPU mapping strategy. +// +//===----------------------------------------------------------------------===// + +#include "polly/CodeGen/IslNodeBuilder.h" +#include "polly/DependenceInfo.h" +#include "polly/LinkAllPasses.h" +#include "polly/ScopInfo.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/GlobalsModRef.h" +#include "llvm/Analysis/PostDominators.h" +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" + +#include "llvm/Support/Debug.h" + +using namespace polly; +using namespace llvm; + +#define DEBUG_TYPE "polly-codegen-ppcg" + +namespace { +class PPCGCodeGeneration : public ScopPass { +public: + static char ID; + + PPCGCodeGeneration() : ScopPass(ID) {} + + bool runOnScop(Scop &S) override { return true; } + + void printScop(raw_ostream &, Scop &) const override {} + + void getAnalysisUsage(AnalysisUsage &AU) const override { + 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(); + AU.addPreserved(); + AU.addPreserved(); + + // FIXME: We do not yet add regions for the newly generated code to the + // region tree. + AU.addPreserved(); + AU.addPreserved(); + } +}; +} + +char PPCGCodeGeneration::ID = 1; + +Pass *polly::createPPCGCodeGenerationPass() { return new PPCGCodeGeneration(); } + +INITIALIZE_PASS_BEGIN(PPCGCodeGeneration, "polly-codegen-ppcg", + "Polly - Apply PPCG translation to SCOP", false, false) +INITIALIZE_PASS_DEPENDENCY(DependenceInfo); +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); +INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); +INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass); +INITIALIZE_PASS_DEPENDENCY(ScopDetection); +INITIALIZE_PASS_END(PPCGCodeGeneration, "polly-codegen-ppcg", + "Polly - Apply PPCG translation to SCOP", false, false) Index: polly/trunk/lib/Support/RegisterPasses.cpp =================================================================== --- polly/trunk/lib/Support/RegisterPasses.cpp +++ polly/trunk/lib/Support/RegisterPasses.cpp @@ -86,6 +86,14 @@ clEnumValEnd), cl::Hidden, cl::init(CODEGEN_ISL), cl::ZeroOrMore, cl::cat(PollyCategory)); +enum TargetChoice { TARGET_CPU, TARGET_GPU }; +static cl::opt + Target("polly-target", cl::desc("The hardware to target"), + cl::values(clEnumValN(TARGET_CPU, "cpu", "generate CPU code"), + clEnumValN(TARGET_GPU, "gpu", "generate GPU code"), + clEnumValEnd), + cl::init(TARGET_CPU), cl::ZeroOrMore, cl::cat(PollyCategory)); + VectorizerChoice polly::PollyVectorizerChoice; static cl::opt Vectorizer( "polly-vectorizer", cl::desc("Select the vectorization strategy"), @@ -145,6 +153,7 @@ namespace polly { void initializePollyPasses(PassRegistry &Registry) { initializeCodeGenerationPass(Registry); + initializePPCGCodeGenerationPass(Registry); initializeCodePreparationPass(Registry); initializeDeadCodeElimPass(Registry); initializeDependenceInfoPass(Registry); @@ -209,24 +218,32 @@ if (DeadCodeElim) PM.add(polly::createDeadCodeElimPass()); - switch (Optimizer) { - case OPTIMIZER_NONE: - break; /* Do nothing */ - - case OPTIMIZER_ISL: - PM.add(polly::createIslScheduleOptimizerPass()); - break; + if (Target == TARGET_GPU) { + // GPU generation provides its own scheduling optimization strategy. + } else { + switch (Optimizer) { + case OPTIMIZER_NONE: + break; /* Do nothing */ + + case OPTIMIZER_ISL: + PM.add(polly::createIslScheduleOptimizerPass()); + break; + } } if (ExportJScop) PM.add(polly::createJSONExporterPass()); - switch (CodeGenerator) { - case CODEGEN_ISL: - PM.add(polly::createCodeGenerationPass()); - break; - case CODEGEN_NONE: - break; + if (Target == TARGET_GPU) { + PM.add(polly::createPPCGCodeGenerationPass()); + } else { + switch (CodeGenerator) { + case CODEGEN_ISL: + PM.add(polly::createCodeGenerationPass()); + break; + case CODEGEN_NONE: + break; + } } // FIXME: This dummy ModulePass keeps some programs from miscompiling,