1 //===------ PPCGCodeGeneration.cpp - Polly Accelerator Code Generation. ---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Take a scop created by ScopInfo and map it to GPU code using the ppcg 11 // GPU mapping strategy. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "polly/CodeGen/IslNodeBuilder.h" 16 #include "polly/DependenceInfo.h" 17 #include "polly/LinkAllPasses.h" 18 #include "polly/ScopInfo.h" 19 #include "llvm/Analysis/AliasAnalysis.h" 20 #include "llvm/Analysis/BasicAliasAnalysis.h" 21 #include "llvm/Analysis/GlobalsModRef.h" 22 #include "llvm/Analysis/PostDominators.h" 23 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h" 24 25 extern "C" { 26 #include "gpu.h" 27 #include "ppcg.h" 28 } 29 30 #include "llvm/Support/Debug.h" 31 32 using namespace polly; 33 using namespace llvm; 34 35 #define DEBUG_TYPE "polly-codegen-ppcg" 36 37 namespace { 38 class PPCGCodeGeneration : public ScopPass { 39 public: 40 static char ID; 41 42 /// The scop that is currently processed. 43 Scop *S; 44 45 PPCGCodeGeneration() : ScopPass(ID) {} 46 47 /// Construct compilation options for PPCG. 48 /// 49 /// @returns The compilation options. 50 ppcg_options *createPPCGOptions() { 51 auto DebugOptions = 52 (ppcg_debug_options *)malloc(sizeof(ppcg_debug_options)); 53 auto Options = (ppcg_options *)malloc(sizeof(ppcg_options)); 54 55 DebugOptions->dump_schedule_constraints = false; 56 DebugOptions->dump_schedule = false; 57 DebugOptions->dump_final_schedule = false; 58 DebugOptions->dump_sizes = false; 59 60 Options->debug = DebugOptions; 61 62 Options->reschedule = true; 63 Options->scale_tile_loops = false; 64 Options->wrap = false; 65 66 Options->non_negative_parameters = false; 67 Options->ctx = nullptr; 68 Options->sizes = nullptr; 69 70 Options->use_private_memory = false; 71 Options->use_shared_memory = false; 72 Options->max_shared_memory = 0; 73 74 Options->target = PPCG_TARGET_CUDA; 75 Options->openmp = false; 76 Options->linearize_device_arrays = true; 77 Options->live_range_reordering = false; 78 79 Options->opencl_compiler_options = nullptr; 80 Options->opencl_use_gpu = false; 81 Options->opencl_n_include_file = 0; 82 Options->opencl_include_files = nullptr; 83 Options->opencl_print_kernel_types = false; 84 Options->opencl_embed_kernel_code = false; 85 86 Options->save_schedule_file = nullptr; 87 Options->load_schedule_file = nullptr; 88 89 return Options; 90 } 91 92 /// Create a new PPCG scop from the current scop. 93 /// 94 /// For now the created scop is initialized to 'zero' and does not contain 95 /// any scop-specific information. 96 /// 97 /// @returns A new ppcg scop. 98 ppcg_scop *createPPCGScop() { 99 auto PPCGScop = (ppcg_scop *)malloc(sizeof(ppcg_scop)); 100 101 PPCGScop->options = createPPCGOptions(); 102 103 PPCGScop->start = 0; 104 PPCGScop->end = 0; 105 106 PPCGScop->context = nullptr; 107 PPCGScop->domain = nullptr; 108 PPCGScop->call = nullptr; 109 PPCGScop->tagged_reads = nullptr; 110 PPCGScop->reads = nullptr; 111 PPCGScop->live_in = nullptr; 112 PPCGScop->tagged_may_writes = nullptr; 113 PPCGScop->may_writes = nullptr; 114 PPCGScop->tagged_must_writes = nullptr; 115 PPCGScop->must_writes = nullptr; 116 PPCGScop->live_out = nullptr; 117 PPCGScop->tagged_must_kills = nullptr; 118 PPCGScop->tagger = nullptr; 119 120 PPCGScop->independence = nullptr; 121 PPCGScop->dep_flow = nullptr; 122 PPCGScop->tagged_dep_flow = nullptr; 123 PPCGScop->dep_false = nullptr; 124 PPCGScop->dep_forced = nullptr; 125 PPCGScop->dep_order = nullptr; 126 PPCGScop->tagged_dep_order = nullptr; 127 128 PPCGScop->schedule = nullptr; 129 PPCGScop->names = nullptr; 130 131 PPCGScop->pet = nullptr; 132 133 return PPCGScop; 134 } 135 136 /// Create a default-initialized PPCG GPU program. 137 /// 138 /// @returns A new gpu grogram description. 139 gpu_prog *createPPCGProg(ppcg_scop *PPCGScop) { 140 141 if (!PPCGScop) 142 return nullptr; 143 144 auto PPCGProg = isl_calloc_type(S->getIslCtx(), struct gpu_prog); 145 146 PPCGProg->ctx = S->getIslCtx(); 147 PPCGProg->scop = PPCGScop; 148 PPCGProg->context = nullptr; 149 PPCGProg->read = nullptr; 150 PPCGProg->may_write = nullptr; 151 PPCGProg->must_write = nullptr; 152 PPCGProg->tagged_must_kill = nullptr; 153 PPCGProg->may_persist = nullptr; 154 PPCGProg->to_outer = nullptr; 155 PPCGProg->to_inner = nullptr; 156 PPCGProg->any_to_outer = nullptr; 157 PPCGProg->array_order = nullptr; 158 PPCGProg->n_stmts = 0; 159 PPCGProg->stmts = nullptr; 160 PPCGProg->n_array = 0; 161 PPCGProg->array = nullptr; 162 163 return PPCGProg; 164 } 165 166 bool runOnScop(Scop &CurrentScop) override { 167 S = &CurrentScop; 168 169 auto PPCGScop = createPPCGScop(); 170 auto PPCGProg = createPPCGProg(PPCGScop); 171 gpu_prog_free(PPCGProg); 172 ppcg_scop_free(PPCGScop); 173 174 return true; 175 } 176 177 void printScop(raw_ostream &, Scop &) const override {} 178 179 void getAnalysisUsage(AnalysisUsage &AU) const override { 180 AU.addRequired<DominatorTreeWrapperPass>(); 181 AU.addRequired<RegionInfoPass>(); 182 AU.addRequired<ScalarEvolutionWrapperPass>(); 183 AU.addRequired<ScopDetection>(); 184 AU.addRequired<ScopInfoRegionPass>(); 185 AU.addRequired<LoopInfoWrapperPass>(); 186 187 AU.addPreserved<AAResultsWrapperPass>(); 188 AU.addPreserved<BasicAAWrapperPass>(); 189 AU.addPreserved<LoopInfoWrapperPass>(); 190 AU.addPreserved<DominatorTreeWrapperPass>(); 191 AU.addPreserved<GlobalsAAWrapperPass>(); 192 AU.addPreserved<PostDominatorTreeWrapperPass>(); 193 AU.addPreserved<ScopDetection>(); 194 AU.addPreserved<ScalarEvolutionWrapperPass>(); 195 AU.addPreserved<SCEVAAWrapperPass>(); 196 197 // FIXME: We do not yet add regions for the newly generated code to the 198 // region tree. 199 AU.addPreserved<RegionInfoPass>(); 200 AU.addPreserved<ScopInfoRegionPass>(); 201 } 202 }; 203 } 204 205 char PPCGCodeGeneration::ID = 1; 206 207 Pass *polly::createPPCGCodeGenerationPass() { return new PPCGCodeGeneration(); } 208 209 INITIALIZE_PASS_BEGIN(PPCGCodeGeneration, "polly-codegen-ppcg", 210 "Polly - Apply PPCG translation to SCOP", false, false) 211 INITIALIZE_PASS_DEPENDENCY(DependenceInfo); 212 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass); 213 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass); 214 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass); 215 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass); 216 INITIALIZE_PASS_DEPENDENCY(ScopDetection); 217 INITIALIZE_PASS_END(PPCGCodeGeneration, "polly-codegen-ppcg", 218 "Polly - Apply PPCG translation to SCOP", false, false) 219