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,13 +90,68 @@ 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) * 100; + 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(); + + + + // HACK: refactor the priority stuff. + static int priority = 0; + appendToGlobalCtors(M, F, priority++, ReplacementToArr); + Constant *BitcastedNewArrExpr = ConstantExpr::getBitCast(ReplacementToArr, PointerType::get(ArrayTy, AddrSpace)); + Array.replaceAllUsesWith(BitcastedNewArrExpr); + // TODO: understand why this crashes. + // Array.eraseFromParent(); +} + 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) { @@ -114,6 +170,10 @@ Free->eraseFromParent(); } + for(GlobalVariable &Global : M.globals()) { + RewriteGlobalArray(M, *DL, Global); + } + return true; } }; Index: tools/GPURuntime/GPUJIT.c =================================================================== --- tools/GPURuntime/GPUJIT.c +++ tools/GPURuntime/GPUJIT.c @@ -33,8 +33,8 @@ #include #include -static int DebugMode; -static int CacheMode; +static int DebugMode = 1; +static int CacheMode = 1; static PollyGPURuntime Runtime = RUNTIME_NONE;