19dfe4e7cSTobias Grosser //===------ PPCGCodeGeneration.cpp - Polly Accelerator Code Generation. ---===// 29dfe4e7cSTobias Grosser // 39dfe4e7cSTobias Grosser // The LLVM Compiler Infrastructure 49dfe4e7cSTobias Grosser // 59dfe4e7cSTobias Grosser // This file is distributed under the University of Illinois Open Source 69dfe4e7cSTobias Grosser // License. See LICENSE.TXT for details. 79dfe4e7cSTobias Grosser // 89dfe4e7cSTobias Grosser //===----------------------------------------------------------------------===// 99dfe4e7cSTobias Grosser // 109dfe4e7cSTobias Grosser // Take a scop created by ScopInfo and map it to GPU code using the ppcg 119dfe4e7cSTobias Grosser // GPU mapping strategy. 129dfe4e7cSTobias Grosser // 139dfe4e7cSTobias Grosser //===----------------------------------------------------------------------===// 149dfe4e7cSTobias Grosser 159dfe4e7cSTobias Grosser #include "polly/CodeGen/IslNodeBuilder.h" 169dfe4e7cSTobias Grosser #include "polly/DependenceInfo.h" 179dfe4e7cSTobias Grosser #include "polly/LinkAllPasses.h" 189dfe4e7cSTobias Grosser #include "polly/ScopInfo.h" 199dfe4e7cSTobias Grosser #include "llvm/Analysis/AliasAnalysis.h" 209dfe4e7cSTobias Grosser #include "llvm/Analysis/BasicAliasAnalysis.h" 219dfe4e7cSTobias Grosser #include "llvm/Analysis/GlobalsModRef.h" 229dfe4e7cSTobias Grosser #include "llvm/Analysis/PostDominators.h" 239dfe4e7cSTobias Grosser #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 249dfe4e7cSTobias Grosser 25*e938517eSTobias Grosser extern "C" { 26*e938517eSTobias Grosser #include "gpu.h" 27*e938517eSTobias Grosser #include "ppcg.h" 28*e938517eSTobias Grosser } 29*e938517eSTobias Grosser 309dfe4e7cSTobias Grosser #include "llvm/Support/Debug.h" 319dfe4e7cSTobias Grosser 329dfe4e7cSTobias Grosser using namespace polly; 339dfe4e7cSTobias Grosser using namespace llvm; 349dfe4e7cSTobias Grosser 359dfe4e7cSTobias Grosser #define DEBUG_TYPE "polly-codegen-ppcg" 369dfe4e7cSTobias Grosser 379dfe4e7cSTobias Grosser namespace { 389dfe4e7cSTobias Grosser class PPCGCodeGeneration : public ScopPass { 399dfe4e7cSTobias Grosser public: 409dfe4e7cSTobias Grosser static char ID; 419dfe4e7cSTobias Grosser 42*e938517eSTobias Grosser /// The scop that is currently processed. 43*e938517eSTobias Grosser Scop *S; 44*e938517eSTobias Grosser 459dfe4e7cSTobias Grosser PPCGCodeGeneration() : ScopPass(ID) {} 469dfe4e7cSTobias Grosser 47*e938517eSTobias Grosser /// Construct compilation options for PPCG. 48*e938517eSTobias Grosser /// 49*e938517eSTobias Grosser /// @returns The compilation options. 50*e938517eSTobias Grosser ppcg_options *createPPCGOptions() { 51*e938517eSTobias Grosser auto DebugOptions = 52*e938517eSTobias Grosser (ppcg_debug_options *)malloc(sizeof(ppcg_debug_options)); 53*e938517eSTobias Grosser auto Options = (ppcg_options *)malloc(sizeof(ppcg_options)); 54*e938517eSTobias Grosser 55*e938517eSTobias Grosser DebugOptions->dump_schedule_constraints = false; 56*e938517eSTobias Grosser DebugOptions->dump_schedule = false; 57*e938517eSTobias Grosser DebugOptions->dump_final_schedule = false; 58*e938517eSTobias Grosser DebugOptions->dump_sizes = false; 59*e938517eSTobias Grosser 60*e938517eSTobias Grosser Options->debug = DebugOptions; 61*e938517eSTobias Grosser 62*e938517eSTobias Grosser Options->reschedule = true; 63*e938517eSTobias Grosser Options->scale_tile_loops = false; 64*e938517eSTobias Grosser Options->wrap = false; 65*e938517eSTobias Grosser 66*e938517eSTobias Grosser Options->non_negative_parameters = false; 67*e938517eSTobias Grosser Options->ctx = nullptr; 68*e938517eSTobias Grosser Options->sizes = nullptr; 69*e938517eSTobias Grosser 70*e938517eSTobias Grosser Options->use_private_memory = false; 71*e938517eSTobias Grosser Options->use_shared_memory = false; 72*e938517eSTobias Grosser Options->max_shared_memory = 0; 73*e938517eSTobias Grosser 74*e938517eSTobias Grosser Options->target = PPCG_TARGET_CUDA; 75*e938517eSTobias Grosser Options->openmp = false; 76*e938517eSTobias Grosser Options->linearize_device_arrays = true; 77*e938517eSTobias Grosser Options->live_range_reordering = false; 78*e938517eSTobias Grosser 79*e938517eSTobias Grosser Options->opencl_compiler_options = nullptr; 80*e938517eSTobias Grosser Options->opencl_use_gpu = false; 81*e938517eSTobias Grosser Options->opencl_n_include_file = 0; 82*e938517eSTobias Grosser Options->opencl_include_files = nullptr; 83*e938517eSTobias Grosser Options->opencl_print_kernel_types = false; 84*e938517eSTobias Grosser Options->opencl_embed_kernel_code = false; 85*e938517eSTobias Grosser 86*e938517eSTobias Grosser Options->save_schedule_file = nullptr; 87*e938517eSTobias Grosser Options->load_schedule_file = nullptr; 88*e938517eSTobias Grosser 89*e938517eSTobias Grosser return Options; 90*e938517eSTobias Grosser } 91*e938517eSTobias Grosser 92*e938517eSTobias Grosser /// Create a new PPCG scop from the current scop. 93*e938517eSTobias Grosser /// 94*e938517eSTobias Grosser /// For now the created scop is initialized to 'zero' and does not contain 95*e938517eSTobias Grosser /// any scop-specific information. 96*e938517eSTobias Grosser /// 97*e938517eSTobias Grosser /// @returns A new ppcg scop. 98*e938517eSTobias Grosser ppcg_scop *createPPCGScop() { 99*e938517eSTobias Grosser auto PPCGScop = (ppcg_scop *)malloc(sizeof(ppcg_scop)); 100*e938517eSTobias Grosser 101*e938517eSTobias Grosser PPCGScop->options = createPPCGOptions(); 102*e938517eSTobias Grosser 103*e938517eSTobias Grosser PPCGScop->start = 0; 104*e938517eSTobias Grosser PPCGScop->end = 0; 105*e938517eSTobias Grosser 106*e938517eSTobias Grosser PPCGScop->context = nullptr; 107*e938517eSTobias Grosser PPCGScop->domain = nullptr; 108*e938517eSTobias Grosser PPCGScop->call = nullptr; 109*e938517eSTobias Grosser PPCGScop->tagged_reads = nullptr; 110*e938517eSTobias Grosser PPCGScop->reads = nullptr; 111*e938517eSTobias Grosser PPCGScop->live_in = nullptr; 112*e938517eSTobias Grosser PPCGScop->tagged_may_writes = nullptr; 113*e938517eSTobias Grosser PPCGScop->may_writes = nullptr; 114*e938517eSTobias Grosser PPCGScop->tagged_must_writes = nullptr; 115*e938517eSTobias Grosser PPCGScop->must_writes = nullptr; 116*e938517eSTobias Grosser PPCGScop->live_out = nullptr; 117*e938517eSTobias Grosser PPCGScop->tagged_must_kills = nullptr; 118*e938517eSTobias Grosser PPCGScop->tagger = nullptr; 119*e938517eSTobias Grosser 120*e938517eSTobias Grosser PPCGScop->independence = nullptr; 121*e938517eSTobias Grosser PPCGScop->dep_flow = nullptr; 122*e938517eSTobias Grosser PPCGScop->tagged_dep_flow = nullptr; 123*e938517eSTobias Grosser PPCGScop->dep_false = nullptr; 124*e938517eSTobias Grosser PPCGScop->dep_forced = nullptr; 125*e938517eSTobias Grosser PPCGScop->dep_order = nullptr; 126*e938517eSTobias Grosser PPCGScop->tagged_dep_order = nullptr; 127*e938517eSTobias Grosser 128*e938517eSTobias Grosser PPCGScop->schedule = nullptr; 129*e938517eSTobias Grosser PPCGScop->names = nullptr; 130*e938517eSTobias Grosser 131*e938517eSTobias Grosser PPCGScop->pet = nullptr; 132*e938517eSTobias Grosser 133*e938517eSTobias Grosser return PPCGScop; 134*e938517eSTobias Grosser } 135*e938517eSTobias Grosser 136*e938517eSTobias Grosser /// Create a default-initialized PPCG GPU program. 137*e938517eSTobias Grosser /// 138*e938517eSTobias Grosser /// @returns A new gpu grogram description. 139*e938517eSTobias Grosser gpu_prog *createPPCGProg(ppcg_scop *PPCGScop) { 140*e938517eSTobias Grosser 141*e938517eSTobias Grosser if (!PPCGScop) 142*e938517eSTobias Grosser return nullptr; 143*e938517eSTobias Grosser 144*e938517eSTobias Grosser auto PPCGProg = isl_calloc_type(S->getIslCtx(), struct gpu_prog); 145*e938517eSTobias Grosser 146*e938517eSTobias Grosser PPCGProg->ctx = S->getIslCtx(); 147*e938517eSTobias Grosser PPCGProg->scop = PPCGScop; 148*e938517eSTobias Grosser PPCGProg->context = nullptr; 149*e938517eSTobias Grosser PPCGProg->read = nullptr; 150*e938517eSTobias Grosser PPCGProg->may_write = nullptr; 151*e938517eSTobias Grosser PPCGProg->must_write = nullptr; 152*e938517eSTobias Grosser PPCGProg->tagged_must_kill = nullptr; 153*e938517eSTobias Grosser PPCGProg->may_persist = nullptr; 154*e938517eSTobias Grosser PPCGProg->to_outer = nullptr; 155*e938517eSTobias Grosser PPCGProg->to_inner = nullptr; 156*e938517eSTobias Grosser PPCGProg->any_to_outer = nullptr; 157*e938517eSTobias Grosser PPCGProg->array_order = nullptr; 158*e938517eSTobias Grosser PPCGProg->n_stmts = 0; 159*e938517eSTobias Grosser PPCGProg->stmts = nullptr; 160*e938517eSTobias Grosser PPCGProg->n_array = 0; 161*e938517eSTobias Grosser PPCGProg->array = nullptr; 162*e938517eSTobias Grosser 163*e938517eSTobias Grosser return PPCGProg; 164*e938517eSTobias Grosser } 165*e938517eSTobias Grosser 166*e938517eSTobias Grosser bool runOnScop(Scop &CurrentScop) override { 167*e938517eSTobias Grosser S = &CurrentScop; 168*e938517eSTobias Grosser 169*e938517eSTobias Grosser auto PPCGScop = createPPCGScop(); 170*e938517eSTobias Grosser auto PPCGProg = createPPCGProg(PPCGScop); 171*e938517eSTobias Grosser gpu_prog_free(PPCGProg); 172*e938517eSTobias Grosser ppcg_scop_free(PPCGScop); 173*e938517eSTobias Grosser 174*e938517eSTobias Grosser return true; 175*e938517eSTobias Grosser } 1769dfe4e7cSTobias Grosser 1779dfe4e7cSTobias Grosser void printScop(raw_ostream &, Scop &) const override {} 1789dfe4e7cSTobias Grosser 1799dfe4e7cSTobias Grosser void getAnalysisUsage(AnalysisUsage &AU) const override { 1809dfe4e7cSTobias Grosser AU.addRequired<DominatorTreeWrapperPass>(); 1819dfe4e7cSTobias Grosser AU.addRequired<RegionInfoPass>(); 1829dfe4e7cSTobias Grosser AU.addRequired<ScalarEvolutionWrapperPass>(); 1839dfe4e7cSTobias Grosser AU.addRequired<ScopDetection>(); 1849dfe4e7cSTobias Grosser AU.addRequired<ScopInfoRegionPass>(); 1859dfe4e7cSTobias Grosser AU.addRequired<LoopInfoWrapperPass>(); 1869dfe4e7cSTobias Grosser 1879dfe4e7cSTobias Grosser AU.addPreserved<AAResultsWrapperPass>(); 1889dfe4e7cSTobias Grosser AU.addPreserved<BasicAAWrapperPass>(); 1899dfe4e7cSTobias Grosser AU.addPreserved<LoopInfoWrapperPass>(); 1909dfe4e7cSTobias Grosser AU.addPreserved<DominatorTreeWrapperPass>(); 1919dfe4e7cSTobias Grosser AU.addPreserved<GlobalsAAWrapperPass>(); 1929dfe4e7cSTobias Grosser AU.addPreserved<PostDominatorTreeWrapperPass>(); 1939dfe4e7cSTobias Grosser AU.addPreserved<ScopDetection>(); 1949dfe4e7cSTobias Grosser AU.addPreserved<ScalarEvolutionWrapperPass>(); 1959dfe4e7cSTobias Grosser AU.addPreserved<SCEVAAWrapperPass>(); 1969dfe4e7cSTobias Grosser 1979dfe4e7cSTobias Grosser // FIXME: We do not yet add regions for the newly generated code to the 1989dfe4e7cSTobias Grosser // region tree. 1999dfe4e7cSTobias Grosser AU.addPreserved<RegionInfoPass>(); 2009dfe4e7cSTobias Grosser AU.addPreserved<ScopInfoRegionPass>(); 2019dfe4e7cSTobias Grosser } 2029dfe4e7cSTobias Grosser }; 2039dfe4e7cSTobias Grosser } 2049dfe4e7cSTobias Grosser 2059dfe4e7cSTobias Grosser char PPCGCodeGeneration::ID = 1; 2069dfe4e7cSTobias Grosser 2079dfe4e7cSTobias Grosser Pass *polly::createPPCGCodeGenerationPass() { return new PPCGCodeGeneration(); } 2089dfe4e7cSTobias Grosser 2099dfe4e7cSTobias Grosser INITIALIZE_PASS_BEGIN(PPCGCodeGeneration, "polly-codegen-ppcg", 2109dfe4e7cSTobias Grosser "Polly - Apply PPCG translation to SCOP", false, false) 2119dfe4e7cSTobias Grosser INITIALIZE_PASS_DEPENDENCY(DependenceInfo); 2129dfe4e7cSTobias Grosser INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); 2139dfe4e7cSTobias Grosser INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); 2149dfe4e7cSTobias Grosser INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); 2159dfe4e7cSTobias Grosser INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass); 2169dfe4e7cSTobias Grosser INITIALIZE_PASS_DEPENDENCY(ScopDetection); 2179dfe4e7cSTobias Grosser INITIALIZE_PASS_END(PPCGCodeGeneration, "polly-codegen-ppcg", 2189dfe4e7cSTobias Grosser "Polly - Apply PPCG translation to SCOP", false, false) 219