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