Index: lib/CodeGen/ManagedMemoryRewrite.cpp =================================================================== --- lib/CodeGen/ManagedMemoryRewrite.cpp +++ lib/CodeGen/ManagedMemoryRewrite.cpp @@ -43,6 +43,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" namespace { static llvm::Function *GetOrCreatePollyMallocManaged(Module &M) { @@ -89,19 +90,88 @@ return F; } +static void RewriteGlobalArray(Module &M, const DataLayout &DL, GlobalVariable &Array) { + static const unsigned AddrSpace = 0; + // We only want arrays. + ArrayType *ArrayTy = dyn_cast(Array.getType()->getElementType()); + if (!ArrayTy) return; + Type *ElemTy = ArrayTy->getElementType(); + PointerType *ElemPtrTy = PointerType::get(ElemTy, AddrSpace); + + // We only wish to replace stuff with internal linkage. Otherwise, + // our type edit from [T] to T* would be illegal across modules. + // It is interesting that most arrays don't seem to be tagged with internal linkage? + if (GlobalValue::isWeakForLinker(Array.getLinkage()) && false) {return; } + + if (!Array.hasInitializer()|| !isa(Array.getInitializer())) return; + + std::string NewName = (Array.getName() + Twine(".toptr")).str(); + GlobalVariable *ReplacementToArr = dyn_cast(M.getOrInsertGlobal(NewName, ElemPtrTy)); + ReplacementToArr->setInitializer(ConstantPointerNull::get(ElemPtrTy)); + + Function *PollyMallocManaged = GetOrCreatePollyMallocManaged(M); + Twine FnName = Array.getName() + ".constructor"; + PollyIRBuilder Builder(M.getContext()); + FunctionType *Ty = + FunctionType::get(Builder.getVoidTy(), {}, false); + const GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; + Function *F = Function::Create(Ty, Linkage, FnName, &M); + BasicBlock *Start = BasicBlock::Create(M.getContext(), "entry", F); + Builder.SetInsertPoint(Start); + + + int ArraySizeInt = DL.getTypeAllocSizeInBits(ArrayTy); + Value *ArraySize = ConstantInt::get(Builder.getInt64Ty(), ArraySizeInt); + ArraySize->setName("array.size"); + + Value *AllocatedMemRaw = Builder.CreateCall(PollyMallocManaged, { ArraySize }, "mem.raw"); + Value *AllocatedMemTyped = Builder.CreatePointerCast(AllocatedMemRaw, ElemPtrTy, "mem.typed"); + Builder.CreateStore(AllocatedMemTyped, ReplacementToArr); + Builder.CreateRetVoid(); + + // All the array's uses will be GEP + for (Use &use: Array.uses()) { + //GEPOperator *GEP = dyn_cast(use->getUser()); + GetElementPtrInst *GEP = dyn_cast(use.getUser()); + if (!GEP) { + errs() << "|User of global that is NOT a GEP: " << *use.getUser() << "\n"; + continue; + } + // assert(GEP && "Global array is being used without a GEP!"); + Builder.SetInsertPoint(GEP); + Value *BitcastedNewArray = Builder.CreateBitCast(ReplacementToArr, PointerType::get(ArrayTy, AddrSpace)); + use.set(BitcastedNewArray); + } + + + + // HACK: refactor this. + static int priority = 0; + appendToGlobalCtors(M, F, priority++, ReplacementToArr); + + + +} + class ManagedMemoryRewritePass : public ModulePass { public: static char ID; GPUArch Architecture; GPURuntime Runtime; + const DataLayout *DL; + ManagedMemoryRewritePass() : ModulePass(ID) {} + virtual bool runOnModule(Module &M) { + DL = &M.getDataLayout(); + Function *Malloc = M.getFunction("malloc"); if (Malloc) { Function *PollyMallocManaged = GetOrCreatePollyMallocManaged(M); assert(PollyMallocManaged && "unable to create polly_mallocManaged"); Malloc->replaceAllUsesWith(PollyMallocManaged); + Malloc->eraseFromParent(); } Function *Free = M.getFunction("free"); @@ -110,6 +180,11 @@ Function *PollyFreeManaged = GetOrCreatePollyFreeManaged(M); assert(PollyFreeManaged && "unable to create polly_freeManaged"); Free->replaceAllUsesWith(PollyFreeManaged); + Free->eraseFromParent(); + } + + for(GlobalVariable &Global : M.globals()) { + RewriteGlobalArray(M, *DL, Global); } return true; Index: test/GPGPU/managed-memory-rewrite-malloc-free.ll =================================================================== --- test/GPGPU/managed-memory-rewrite-malloc-free.ll +++ test/GPGPU/managed-memory-rewrite-malloc-free.ll @@ -41,6 +41,10 @@ ; HOST-IR call void @polly_freeManaged(i8* %toFreeBitcast) ; HOST-IR: declare void @polly_freeManaged(i8*) +; // Check that we remove the original malloc,free +; HOST-IR-NOT: declare i8* @malloc(i64) +; HOST-IR-NOT: declare void @free(i8*) + target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.12.0"