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       Malloc->eraseFromParent();
106     }
107 
108     Function *Free = M.getFunction("free");
109 
110     if (Free) {
111       Function *PollyFreeManaged = GetOrCreatePollyFreeManaged(M);
112       assert(PollyFreeManaged && "unable to create polly_freeManaged");
113       Free->replaceAllUsesWith(PollyFreeManaged);
114       Free->eraseFromParent();
115     }
116 
117     return true;
118   }
119 };
120 
121 } // namespace
122 char ManagedMemoryRewritePass::ID = 42;
123 
124 Pass *polly::createManagedMemoryRewritePassPass(GPUArch Arch,
125                                                 GPURuntime Runtime) {
126   ManagedMemoryRewritePass *pass = new ManagedMemoryRewritePass();
127   pass->Runtime = Runtime;
128   pass->Architecture = Arch;
129   return pass;
130 }
131 
132 INITIALIZE_PASS_BEGIN(
133     ManagedMemoryRewritePass, "polly-acc-rewrite-managed-memory",
134     "Polly - Rewrite all allocations in heap & data section to managed memory",
135     false, false)
136 INITIALIZE_PASS_DEPENDENCY(PPCGCodeGeneration);
137 INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
138 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
139 INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
140 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
141 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass);
142 INITIALIZE_PASS_DEPENDENCY(ScopDetectionWrapperPass);
143 INITIALIZE_PASS_END(
144     ManagedMemoryRewritePass, "polly-acc-rewrite-managed-memory",
145     "Polly - Rewrite all allocations in heap & data section to managed memory",
146     false, false)
147