1 //===------ ManagedMemoryRewrite.cpp - Rewrite global & malloc'd memory.
2 //---===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // Take a module and rewrite:
12 // 1. `malloc` -> `polly_mallocManaged`
13 // 2. `free` -> `polly_freeManaged`
14 // 3. global arrays with initializers -> global arrays that are initialized
15 //                                       with a constructor call to
16 //                                       `polly_mallocManaged`.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #include "polly/CodeGen/CodeGeneration.h"
21 #include "polly/CodeGen/IslAst.h"
22 #include "polly/CodeGen/IslNodeBuilder.h"
23 #include "polly/CodeGen/PPCGCodeGeneration.h"
24 #include "polly/CodeGen/Utils.h"
25 #include "polly/DependenceInfo.h"
26 #include "polly/LinkAllPasses.h"
27 #include "polly/Options.h"
28 #include "polly/ScopDetection.h"
29 #include "polly/ScopInfo.h"
30 #include "polly/Support/SCEVValidator.h"
31 #include "llvm/Analysis/AliasAnalysis.h"
32 #include "llvm/Analysis/BasicAliasAnalysis.h"
33 #include "llvm/Analysis/GlobalsModRef.h"
34 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
35 #include "llvm/Analysis/TargetLibraryInfo.h"
36 #include "llvm/Analysis/TargetTransformInfo.h"
37 #include "llvm/IR/LegacyPassManager.h"
38 #include "llvm/IR/Verifier.h"
39 #include "llvm/IRReader/IRReader.h"
40 #include "llvm/Linker/Linker.h"
41 #include "llvm/Support/TargetRegistry.h"
42 #include "llvm/Support/TargetSelect.h"
43 #include "llvm/Target/TargetMachine.h"
44 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
45 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
46 namespace {
47 
48 static llvm::Function *GetOrCreatePollyMallocManaged(Module &M) {
49   // TODO: should I allow this pass to be a standalone pass that
50   // doesn't care if PollyManagedMemory is enabled or not?
51   assert(PollyManagedMemory &&
52          "One should only rewrite malloc & free to"
53          "polly_{malloc,free}Managed with managed memory enabled.");
54   const char *Name = "polly_mallocManaged";
55   Function *F = M.getFunction(Name);
56 
57   // If F is not available, declare it.
58   if (!F) {
59     GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
60     PollyIRBuilder Builder(M.getContext());
61     // TODO: How do I get `size_t`? I assume from DataLayout?
62     FunctionType *Ty = FunctionType::get(Builder.getInt8PtrTy(),
63                                          {Builder.getInt64Ty()}, false);
64     F = Function::Create(Ty, Linkage, Name, &M);
65   }
66 
67   return F;
68 }
69 
70 static llvm::Function *GetOrCreatePollyFreeManaged(Module &M) {
71   // TODO: should I allow this pass to be a standalone pass that
72   // doesn't care if PollyManagedMemory is enabled or not?
73   assert(PollyManagedMemory &&
74          "One should only rewrite malloc & free to"
75          "polly_{malloc,free}Managed with managed memory enabled.");
76   const char *Name = "polly_freeManaged";
77   Function *F = M.getFunction(Name);
78 
79   // If F is not available, declare it.
80   if (!F) {
81     GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
82     PollyIRBuilder Builder(M.getContext());
83     // TODO: How do I get `size_t`? I assume from DataLayout?
84     FunctionType *Ty =
85         FunctionType::get(Builder.getVoidTy(), {Builder.getInt8PtrTy()}, false);
86     F = Function::Create(Ty, Linkage, Name, &M);
87   }
88 
89   return F;
90 }
91 
92 class ManagedMemoryRewritePass : public ModulePass {
93 public:
94   static char ID;
95   GPUArch Architecture;
96   GPURuntime Runtime;
97   ManagedMemoryRewritePass() : ModulePass(ID) {}
98   virtual bool runOnModule(Module &M) {
99     Function *Malloc = M.getFunction("malloc");
100 
101     if (Malloc) {
102       Function *PollyMallocManaged = GetOrCreatePollyMallocManaged(M);
103       assert(PollyMallocManaged && "unable to create polly_mallocManaged");
104       Malloc->replaceAllUsesWith(PollyMallocManaged);
105     }
106 
107     Function *Free = M.getFunction("free");
108 
109     if (Free) {
110       Function *PollyFreeManaged = GetOrCreatePollyFreeManaged(M);
111       assert(PollyFreeManaged && "unable to create polly_freeManaged");
112       Free->replaceAllUsesWith(PollyFreeManaged);
113     }
114 
115     return true;
116   }
117 };
118 
119 } // namespace
120 char ManagedMemoryRewritePass::ID = 42;
121 
122 Pass *polly::createManagedMemoryRewritePassPass(GPUArch Arch,
123                                                 GPURuntime Runtime) {
124   ManagedMemoryRewritePass *pass = new ManagedMemoryRewritePass();
125   pass->Runtime = Runtime;
126   pass->Architecture = Arch;
127   return pass;
128 }
129 
130 INITIALIZE_PASS_BEGIN(
131     ManagedMemoryRewritePass, "polly-acc-rewrite-managed-memory",
132     "Polly - Rewrite all allocations in heap & data section to managed memory",
133     false, false)
134 INITIALIZE_PASS_DEPENDENCY(PPCGCodeGeneration);
135 INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
136 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
137 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
138 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
139 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
140 INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
141 INITIALIZE_PASS_END(
142     ManagedMemoryRewritePass, "polly-acc-rewrite-managed-memory",
143     "Polly - Rewrite all allocations in heap & data section to managed memory",
144     false, false)
145