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